Grove Air Quailty sensor fails in Air Quality Monitoring Kit

Following the AQMK tutorial here https://docs.particle.io/quickstart/aqmk-project/. Have assembled the hardware and entered code (see below) for the dust sensor and air quality sensor according to the tutorial. The code compiles and uploads without error. I have established connection to the Grove Air Quality Sensor but can not get it to return a value other than “None”.

The serial monitor shows that the dust sensor is working correctly, the air quality sensor seems to initialize but does not return appropriate values. The getAirQuality function returns “None” as long as the sketch is running.

Have I made some mistake in the code, do I have a bad air quality sensor, other ideas?

Thanks.

#include "math.h"
#include "Air_Quality_Sensor.h"

#define DUST_SENSOR_PIN D4
#define SENSOR_READING_INTERVAL 30000
#define AQS_PIN A2

AirQualitySensor aqSensor(AQS_PIN);

unsigned long lastInterval;
unsigned long lowpulseoccupancy = 0;
unsigned long last_lpo = 0;
unsigned long duration;

float ratio = 0;
float concentration = 0;

// setup() runs once, when the device is first turned on.
void setup() {
  // Put initialization like pinMode and begin functions here.
Serial.begin(9600);

pinMode(DUST_SENSOR_PIN, INPUT);
lastInterval = millis();

if (aqSensor.init())
{
  Serial.println("Air Quality Sensor ready.");
}
else
{
  Serial.println("Air Quality Sensor ERROR!");
}

}

// loop() runs over and over again, as quickly as it can execute.
void loop() {
  // The core of your code will likely live here.
duration = pulseIn(DUST_SENSOR_PIN, LOW);
lowpulseoccupancy = lowpulseoccupancy + duration;

if ((millis() - lastInterval) > SENSOR_READING_INTERVAL)
{
  getDustSensorReadings();

  lowpulseoccupancy = 0;
  lastInterval = millis();

  String quality  = getAirQuality();
  Serial.printlnf("Air Quality: %s", quality.c_str());
}

}

void getDustSensorReadings()
{
if (lowpulseoccupancy == 0)
{
  lowpulseoccupancy = last_lpo;
}
else
{
  last_lpo = lowpulseoccupancy;
}

ratio = lowpulseoccupancy / (SENSOR_READING_INTERVAL * 10.0);
concentration = 1.1 * pow(ratio, 3) - 3.8 * pow(ratio, 2) + 520 * ratio + 0.62;

Serial.printlnf("LPO: %d", lowpulseoccupancy);
Serial.printlnf("Ratio: %f%%", ratio);
Serial.printlnf("concentration: %f pcs/L", concentration);
}

String getAirQuality()
{
  int quality = aqSensor.slope();
  String qual = "None";

  if (quality == AirQualitySensor::FORCE_SIGNAL)
  {
    qual = "Danger";
  }
  else if (quality == AirQualitySensor::HIGH_POLLUTION)
  {
    qual == "High Pollution";
  }
  else if (quality == AirQualitySensor::LOW_POLLUTION)
  {
    qual == "Low Pollution";
  }
  else if (quality == AirQualitySensor::FRESH_AIR)
  {
    qual == "Fresh Air";
  }

  return qual;
}

Maybe you can print out the integer value of quality and see what raw value you get.
That might help understanding the cause.

I’m also not sure why the sample uses these unwieldy if() ... else if() constructs.
I’d find this much simpler to read

  switch(quality) {
    case AirQualitySensor::FORCE_SIGNAL:
      qual = "Danger";
      break;
    case AirQualitySensor::HIGH_POLLUTION:
      qual = "High Pollution";
      break;
    case AirQualitySensor::LOW_POLLUTION:
      qual = "Low Pollution";
      break;
    case AirQualitySensor::FRESH_AIR:
      qual = "Fresh Air";
      break;
   default:
     qual = String::format("Unknown %d", quality);
  }

(I might even prefer an array of strings instead of this kind of translation)

BTW, the probably cause for your issue is that you are using == (equality check) where there should be an assignment (=).

Thanks for that, ScruffR. I must’ve looked at it half a dozen times and missed the out of place == operators in the String function. Also, agreed, the switch looks nicer than if … else if.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.