Particle Photon - Grove Dust Sensor -> receiving No data available in the console. Need Help Urgently!

I need to know why my code is keep showing log = No data available ? How do i make it actually sense the dust and give me a reading for it? What change do i need for the code? Please give me help/suggestion.


This is for the .cpp and .h

A better way to let people investigate and test your code would be to post the code as text (in a image code block) or as SHARE THIS REVISION link.

Screenshots of your code are the least useful way to do it :wink:

2 Likes

Hi,
I guess this will never work as you trying to use lib for PMS5003 with serial interface

for PPD42NS Grove Dust Sensor with PWM output (Low Pulse Occupancy time)

here is an example for PPD42NS with arduino which you can port/adapt for your needs :+1:

1 Like
// This #include statement was automatically added by the Particle IDE.
#include "DustSensor.h"

char resultstr[128]; // This is where we will put the data
DustSensor dustSensor;

void setup() {
    Particle.publish("log", "Air Quality Start");
    Particle.variable("result", resultstr, STRING);
    dustSensor.begin();
}

// Start out at 90 so our first reading is logged quickly
int i = 90;
// Have we found data this iteration
bool foundData = false;
// Where the found data is stored
pms5003data data;
// Used to compare against the last capture, the higher number is kept
pms5003data tempData;

/**
 * I'm only interested in the highest value found. Something like solder
 * will only trigger poor air quality for a short period of time.
 */
void loop() {
    i = i + 1;
    // .listen() returns true if data was captured
    if(dustSensor.listen()) {
        if(foundData == true) {
            // If we've already found data, keep the higher number.
            // TODO: Keep the higher number for each size.
            tempData = dustSensor.readData();
            if(tempData.pm10_standard > data.pm10_standard || tempData.pm25_standard > data.pm25_standard) {
                data = tempData;
            }
        } else {
            data = dustSensor.readData();
        }

        foundData = true;
    } // else do nothing, no data was captured
    // Every 10 seconds, publish the data
    if(i >= 100) {
        i = 0;
        if(foundData) {
            // Reset found data to false to allow for the reading.
            foundData = false;
            Particle.publish("log", "Found data!");
            // TODO: Send all data from struct
            sprintf(resultstr, "{\"pm10\":%i,\"pm25\":%i,\"pm100\":%i,\"checksum\":%i}", data.pm10_standard, data.pm25_standard, data.pm100_standard, data.checksum);
            Particle.publish("reading", resultstr);
        } else {
            // In 100 tries, no data was captured. There is likely a problem
            // with the wiring or too long of a delay between readings.
            Particle.publish("log", "No data available.");
        }
    }
    // Short delay before next reading. When this is too high, no data was
    // being captured. Keep it low or update the PMS5003 code to support
    // running in the background.
    delay(100);
}

for .cpp

// This example is a modified version of the code available for Arduino on
// the Adafruit website:
// https://learn.adafruit.com/pm25-air-quality-sensor/arduino-code

// TODO: Add support for putting sensor to sleep.

// WIRING
// VCC: The PMS5003 sensor requires 5v to power the fan. Plug it into VIN
// on the Particle Photon to get the 5v.
// TX: (transmit) on the PMS5003 should be connected to RX (receive) on the Photon
// GND: GND

// Includes
#include "DustSensor.h"

DustSensor::DustSensor(void) {

}

void DustSensor::begin() {
  Serial1.begin(BAUD_RATE);
  Serial1.setTimeout(SERIAL_TIMEOUT);
}

pms5003data DustSensor::readData() {
  return data;
}

boolean DustSensor::listen() {

  // check if serial has data
  if (!Serial1.available()) {
    return false;
  }

  if (Serial1.peek()  != 0x42) {
    Serial1.read();
    return false;
  }
  if (Serial1.available() < 32) {
    return false;
  }
  // read serial port into buffer
  // break if we haven't totally filled the buffer
  uint8_t buffer[32];
  uint16_t sum = 0;
  if (!Serial1.readBytes((char*)buffer, 32)) {
    return false;
  }

  // get checksum ready
  for (uint8_t i=0; i<30; i++) {
    sum += buffer[i];
  }

  uint16_t buffer_u16[15];
  for (uint8_t i=0; i<15; i++) {
    buffer_u16[i] = buffer[2 + i*2 + 1];
    buffer_u16[i] += (buffer[2 + i*2] << 8);
  }
  // put it into a nice struct :)
  memcpy((void *)&data, (void *)buffer_u16, 30);

  if (sum != data.checksum) {
    return false;
  }

  // success!
  return true;
}

for .h

//Includes
#include "Particle.h"

// Defines
#define BAUD_RATE           9600  //bps
#define SERIAL_TIMEOUT      500 //ms
#define BUFFER_SIZE         60 //bytes

struct pms5003data {
  uint16_t framelen;
  uint16_t pm10_standard, pm25_standard, pm100_standard;
  uint16_t pm10_env, pm25_env, pm100_env;
  uint16_t particles_03um, particles_05um, particles_10um, particles_25um, particles_50um, particles_100um;
  uint16_t unused;
  uint16_t checksum;
};

class DustSensor {

public:
  DustSensor(void);

  void begin();
  bool listen();
  pms5003data readData();

private:
  struct pms5003data data;
};

https://go.particle.io/shared_apps/60b0050b9f3fb40017ff0a3d

Could you help me solve?

:thinking:
sometimes i’m lost in here :man_facepalming: did you read my post above carefully ???
are you using PSM5003 sensor or PPD42NS Grove sensor ? They are completely two different tings !

1 Like

try this:

#include "Particle.h"
#include <math.h>

int pin = D1;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 30000;//sampe 30s ;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
 
void setup() 
{
    Serial.begin(9600);
    pinMode(pin,INPUT);
    starttime = millis();//get the current time;
}
 
void loop() 
{
    duration = pulseIn(pin, LOW);
    lowpulseoccupancy = lowpulseoccupancy+duration;
 
    if ((millis()-starttime) > sampletime_ms)//if the sampel time == 30s
    {
        ratio = lowpulseoccupancy/(sampletime_ms*10.0);  // Integer percentage 0=>100
        concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
        Serial.print(lowpulseoccupancy);
        Serial.print(",");
        Serial.print(ratio);
        Serial.print(",");
        Serial.println(concentration);
        lowpulseoccupancy = 0;
        starttime = millis();
    }
}

and connect your output (PIN4 output ) yellow wire to D1 on your photon

UPDATE
and here is code with Particle.variable() and Particle.publish() (code above just prints data to Serial)
with JSON formatted data:

#include "Particle.h"
#include <math.h>

char resultstr[128];
int pin = D1;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 30000;//sampe 30s ;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
 
void setup() 
{
    Particle.variable("result", resultstr);
    Serial.begin(9600);
    pinMode(pin,INPUT);
    starttime = millis();//get the current time;
}
 
void loop() 
{
    duration = pulseIn(pin, LOW);
    lowpulseoccupancy = lowpulseoccupancy+duration;
 
    if ((millis()-starttime) > sampletime_ms)//if the sampel time == 30s
    {
        ratio = lowpulseoccupancy/(sampletime_ms*10.0);  // Integer percentage 0=>100
        concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
        Serial.print(lowpulseoccupancy);
        Serial.print(",");
        Serial.print(ratio);
        Serial.print(",");
        Serial.println(concentration);
        sprintf(resultstr, "{\"lowpulseoccupancy\":%d,\"ratio\":%.02f,\"concentration\":%.02f}", lowpulseoccupancy, ratio, concentration);
        Particle.publish("reading", resultstr);
        lowpulseoccupancy = 0;
        starttime = millis();
    }
}

here are explanation what is the lowpulseoccupancy, ratio and concentration for PPD42NS Grove Dust Sensor

1 Like

code for the Grove dust sensor Particle io.

#include "Particle.h"
#include "math.h"

int pin = D1;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 30000;//sampe 30s ;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;
 
void setup() 
{
    Serial.begin(9600);
    pinMode(pin,INPUT);
    starttime = millis();//get the current time;
}
 
void loop() 
{
    duration = pulseIn(pin, LOW);
    lowpulseoccupancy = lowpulseoccupancy+duration;
 
    if ((millis()-starttime) > sampletime_ms)//if the sampel time == 30s
    {
        ratio = lowpulseoccupancy/(sampletime_ms*10.0);  // Integer percentage 0=>100
        concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; // using spec sheet curve
        Particle.publish( "lowpulseoccupancy:  " +  String(lowpulseoccupancy) + ""  ,  "ratio:  " +   String(ratio) + ",   Concentration:  " + String(concentration, 0) + ""    );

        //Serial.print(lowpulseoccupancy);
        //Serial.print(",");
        //Serial.print(ratio);
        //Serial.print(",");
        //Serial.println(concentration);
        //lowpulseoccupancy = 0;
        starttime = millis();
    }
}

Please help me find a way to bring the value of concentration down, because it seems to high. Also the values are very erratic, any sort of suggestion to fix would help. Like 1000pm.

This doesn’t look good, to start with

You need to keep the wires separated better!
And why? Why do you swap red and black? Why not connect red to red and black to black? Although electrically it makes no difference, but it just screams bad practice.

You also seem to fail to reset lowpulseoccupancy once you have dealt with it.
Why is this commented out?

You should also account for the case that pulseIn() times out and then not add the duration to that. Additionally it would be wise to keep track of the number of successful pulseIn() calls rather than assuming that all attempts during sampletime_ms were successful.

Finally, use snprintf() instead of String() concatenations.

1 Like

How do i track a , successful pulseIn()?

https://docs.particle.io/reference/device-os/firmware/#pulsein-

Would be a good starting point for finding out youself :wink:

or have a peek