ESP8266 Dust Sensor PPD42

I am doing a project where I have to connect an ESP8266 NodeMcu v1 board (attached photo) and a PPD42 SHINYEI Dust Sensor. Attached photo of the connection. Connection Photo (Black - GND, Red - Vin , Green - PIN D8)




I use this code:

int pin = 8;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 2000; 
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;

void setup() {
  Serial.begin(9600);
  pinMode(8,INPUT);
  starttime = millis(); 
}

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62; 
    Serial.print("Concentration = ");
    Serial.print(concentration);
    Serial.println(" pcs/0.01cf");
    Serial.println("\n");
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

The problem is that in the Serial Monitor I receive: ":+⸮⸮#⸮Rs5U⸮⸮$⸮ "
Anyone have any idea what may be happening?

Is your serial monitor set to 9600? Better to use 115K, it's faster.

I bought a 5V fan, put it on top of the dust sensor and run it off 3.3V.

My dust sensor task:

void fDoParticleDetector( void * parameter )
{
  /*
    ug/m3     AQI                 Lvl AQ (Air Quality)
    (air Quality Index)
    0-35     0-50                1   Excellent
    35-75    51-100              2   Average
    75-115   101-150             3   Light pollution
    115-150  151-200             4   moderate
    150-250  201-300             5   heavy
    250-500  >=300               6   serious
  */
  float ADbits = 4095.0f;
  float uPvolts = 3.3f;
  float adcValue = 0.0f;
  float dustDensity = 0.0f;
  float Voc = 0.6f; // Set the typical output voltage in Volts when there is zero dust.
  const float K = 0.5f; // Use the typical sensitivity in units of V per 100ug/m3.
  xEventGroupWaitBits (eg, evtWaitForBME, pdTRUE, pdTRUE, portMAX_DELAY );
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 100; //delay for mS
  for (;;)
  {
    //enable sensor led
    gpio_set_level( GPIO_NUM_4, HIGH ); // set gpio 4 to high to turn on sensor internal led for measurement
    esp_timer_start_once( oneshot_timer, 280 ); // trigger one shot timer for a 280uS timeout, warm up time.
    xEventGroupWaitBits (eg, evtDoParticleRead, pdTRUE, pdTRUE, portMAX_DELAY ); // event will be triggered by the timer expiring, wait here for the 280uS
    adcValue = float( adc1_get_raw(ADC1_CHANNEL_0) ); //take a raw ADC reading from the dust sensor
    gpio_set_level( GPIO_NUM_4, LOW );//Shut off the sensor LED
    adcValue = ( adcValue * uPvolts ) / ADbits; //calculate voltage
    dustDensity = (adcValue / K) * 100.0; //convert volts to dust density
    if ( dustDensity < 0.0f )
    {
      dustDensity = 0.00f; // make negative values a 0
    }
    if ( xSemaphoreTake( sema_PublishPM, 0 ) == pdTRUE )  // don't wait for semaphore to be available
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY );
      //log_i( "ADC volts %f Dust Density = %ug / m3 ", adcValue, dustDensity ); // print the calculated voltage and dustdensity
      MQTTclient.publish( topicInsidePM, String(dustDensity).c_str() );
      xSemaphoreGive( sema_MQTT_KeepAlive );
      x_eData.PM2 = dustDensity;
    }
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
    //log_i( " high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
  }
  vTaskDelete( NULL );
}// end fDoParticleDetector()

I’ve tried changing from 9600 to 115200 and changing the Vin PIN to 3V3, but I keep getting the same output on the Serial Monitor: " ⸮⸮1⸮⸮⸮ ⸮1⸮⸮⸮؁*⸮⸮#⸮⸮)⸮(⸮z⸮3⸮ "

WHen you comment out the lines:

 Serial.print(concentration);
    Serial.println(" pcs/0.01cf");

does that cause the issue?

If you put

  Serial.print(concentration);
Serial.println( "dink" );
    Serial.println(" pcs/0.01cf");

is their bad stuff before the words dink?

If in setup()

 Serial.begin(9600);
  pinMode(8,INPUT);
  starttime = millis();
Serial.println( "blabbue");

does that cause an issue?

I just added what you told me in the previous message, and it does not produce any errors, the output in the Serial Monitor continue being: "⸮; ⸮⸮ | ⸮⸮ \ R ⸮⸮yG⸮ ^ hb ⸮⸮⸮. ⸮ "

osfuco:
I just added what you told me in the previous message, and it does not produce any errors, the output in the Serial Monitor continue being: "⸮; ⸮⸮ | ⸮⸮ \ R ⸮⸮yG⸮ ^ hb ⸮⸮⸮. ⸮ "

Yes or no, did the Serial.println( "blabbue"); print the baddie stuff?

And is this a duplicate post?

I get the same output with Serial.println ("blabbue") as without it (with serial code).

No this is not a duplicate post

osfuco:
I get the same output with Serial.println ("blabbue") as without it (with serial code).

No this is not a duplicate post

Does the line that prints Serial.println ("blabbue") print junk?

A) Yes

B) No

Answer A or B.

No

Ok, so the source of the issue is with the printing you have coded, agreed?

A:

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.print("Concentration = ");
    //Serial.print(concentration);
    //Serial.println(" pcs/0.01cf");
    //Serial.print("\n");
Serial.println();
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

Does that cause a print issue?

B:

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.print("Concentration = ");
    Serial.print(concentration);
    //Serial.println(" pcs/0.01cf");
    //Serial.print("\n");
Serial.println();
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

Does that cause an issue?

C:

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.print("Concentration = ");
    Serial.print(concentration);
    Serial.println(" pcs/0.01cf");
    //Serial.print("\n");
Serial.println();
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

Does that cause an issue?

D:

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.print("Concentration = ");
    //Serial.print(concentration);
    //Serial.println(" pcs/0.01cf");
    //Serial.print("\n");
Serial.println();
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

Issue?

E:

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);  
    concentration = 1.1*pow(ratio,3)-3.8*pow(ratio,2)+520*ratio+0.62;
    Serial.print("Concentration = ");
    Serial.print(concentration);
    Serial.println(" pcs/0.01cf");
    Serial.print("\n");
Serial.println();
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

Does that cause an issue?

What is the IDE core debug level set at?

This is a bit a wild guess from my side, because I don’t have any experience at all with a ESP8266 platform.
The sketch uses the D8 pin to read the sensor (using pulseIn to determine the low part of the PWM cycle).
But D8 also carries the RTS signal of the UART0 serial communication (and pin D7 carries the CTS signal).
I don’t know if Serial uses the UART0 hardware, but if that is the case then connecting the sensor to D8 may mess up the Serial communication (or depending on the point of view Serial may mess with the sensor). Then it would be better to connect the sensor to a different pin.
And for my education: in the ESP8266 world, do you refer to a pin as e.g. “8” or as “D8” e.g. in a pinMode statement?
Thank you.
Guy

I use ESP32’s and refer to the gpio number as GPIO_NUM_XX.

And I believe you are correct that your pin numbers being used may be at fault.

Idahowalker test codes:

A: It does not cause any problems at the output
B: Does not cause any problems at the output
C: It does not cause any problems at the output
D: Does not cause any problems at the output
MI: It does not cause any problems at the output

In all the options I get as output "P9z⸮⸮ Z + 5⸮⸮y ⸮ ⸮⸮", but no error.

Idahowalker

The IDE core debug level set at "NONE"

I thought this "P9z⸮⸮ Z + 5⸮⸮y ⸮ ⸮⸮" was an error? Oh, sorry I was trying to find the source and get rid of the error. My bad.

osfuco:
Idahowalker

The IDE core debug level set at “NONE”

Then how is it printing to the serial monitor?

Set core debug level to debug.

Good morning, now I am using this code:
Connections: (Black - GND, Red - Vin , Green - PIN D5)

int pin = 5;
unsigned long duration;
unsigned long starttime;
unsigned long sampletime_ms = 1000;//sampe 1s ;
unsigned long lowpulseoccupancy = 0;
float ratio = 0;
float concentration = 0;


void setup() {
  Serial.begin(9600);
  pinMode(5,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(ratio);
    Serial.print("concentration = ");
    Serial.print(concentration);
    Serial.print(" pcs/0.01cf  -  ");
    if (concentration < 1.0) {
     Serial.println("It's a smokeless and dustless environment"); 
  }
    if (concentration > 1.0 && concentration < 20000) {
     Serial.println("It's probably only you blowing air to the sensor :)"); 
    }
    
    if (concentration > 20000 && concentration < 315000) {
     Serial.println("Smokes from matches detected!"); 
    }
      if (concentration > 315000) {
     Serial.println("Smokes from cigarettes detected! Or It might be a huge fire! Beware!"); 
  }
    
    lowpulseoccupancy = 0;
    starttime = millis();
  }
}

I receive as output:

I think the problem is that the sensor is not turned on. I use the micro-usb with the PC to power the board

Maybe I have to set the Vin pin as 5V output? If so, how should I do it?

If you connect to the D5 pin, you should write
int pin=D5;
Guy