some help with PPD42NJ

Hey!

I am playing around with the Shinyei PPD42NJ particle sensor and would like to get some input on the code and set up. According to the information availablethe pulseIn function works best with pulses from 10ms-3min. The Low pulse width of the PPD42NJ is supposed to be in the range of 1ms-300ms so pulseIn might not be the best way to read the sensor but I could not figure out a better way…

Anyway, I can not figure out why the program is continuing to print out after the 30s sample loop. It should only print after entering the IF loop but it seems the program in jumping back into the IF loop, why I dont know. A stupid mistake? Please give me your input=) Ive attached a photo with undesired print out in red box.

I have attached the datasheet for the sensor.

  • Arduino Uno r3
  • PPD42NJ (Pin 1 GND, Pin 3 to +5V, Pin 4 to digitalPin 8 on Arduino, Arduino GND conected to common GND)
  • ACtoDC regulated power supply (5V) connected to PPD42NJ
  • ACtoDC regulated power supply (9V) connected to Arduino
#define pinPPD42NS 8

int duration;
int starttime;
int sampletime_ms = 30000; //sampletime 30s ;
float lowpulseoccupancy = 0;

float ratio = 0;
String output = "";

void setup() {
  Serial.begin(9600);
  Serial.println("Lowpulseoccupancy [ms],Ratio [%] ");
  pinMode(pinPPD42NS, INPUT);

  delay(5000); // warm up time

  starttime = millis();//get the current time;
}

void loop() {
  // read PPD42NJ
  duration = pulseIn(pinPPD42NS, LOW) / 1000; //PulseIn returns the length of the LOW pulse in microseconds, convert to ms
  lowpulseoccupancy = lowpulseoccupancy + duration; 

  if ((millis() - starttime) > sampletime_ms) // Run if loop after the loop has run for sampletime_ms
  {
    ratio = lowpulseoccupancy * 100 / sampletime_ms; // ratios of lowpulseoccupancy and sampletims_ms in percentage

    output = String(lowpulseoccupancy);
    output += ",";
    output += String(ratio);

    Serial.println(output);

    // reset counters for next loop
    lowpulseoccupancy = 0;
    starttime = millis(); // reset starttime as the total time the program has been running
    duration = 0;
  }
}

/ Seb

150916 PPD42NJ Spec SPP15002(V00).pdf (215 KB)

Vatsug:
According to the information available the pulseIn function works best with pulses from 10ms-3min.

That's 10 microseconds not milliseconds.

The value returned from pulsein is in microseconds. So your sample time isn't 30 seconds is really 30 milliseconds.

DuaneDegn:
That's 10 microseconds not milliseconds.

The value returned from pulsein is in microseconds. So your sample time isn't 30 seconds is really 30 milliseconds.

Thanks DuaneDegn,

I actually converted the pulseIn microsecond to ms in the code but I totally forgot about it when I wrote the message.. In that case I guess the pulseIn function should work just fine! Thanks

" duration = pulseIn(pinPPD42NS, LOW) / 1000; //PulseIn returns the length of the LOW pulse in microseconds, convert to ms"

Vatsug:
I actually converted the pulseIn microsecond to ms in the code but I totally forgot about it when I wrote the message..

Sure enough you do.

So the program is supposed to output to the terminal once every 30 seconds (close to this anyway) but it only waits this 30s for the first loop? Is that right?

The program sure looks like it should display data once every 30 seconds (a little over 30 seconds).

The statement below make me think you need to change your "starttime" variable to an unsigned long.

Please note that the return value for millis() is an unsigned long, logic errors may occur if a programmer tries to do arithmetic with smaller data types such as int's. Even signed long may encounter errors as its maximum value is half that of its unsigned counterpart.

DuaneDegn:
The statement below make me think you need to change your "starttime" variable to an unsigned long.

DuaneDegn,

That made the trick! Thanks a lot!

/ Seb

Vatsug:
DuaneDegn,

That made the trick! Thanks a lot!

/ Seb

Very good to hear. Thanks for letting me know.