Hi. I have bought a GP2Y1014AU particulate sensor and connected it to an ESP8266 board. I have used several code templates, like the one I have pasted below, but they all return a reading value equal or close to 0. Does anyone know if dust sensors, to work correctly, need to be placed in an environment without any light sources? Is something missing in the code that prevents to display a correct value?
#define dustPin A0 // Black wire
#define ledPin 2 // White wire
#define ANALOG_VOLTAGE 3.3 // analog top of range
void setup()
{
Serial.begin(115200);
while (!Serial) delay(100);
Serial.println("GP2Y1010AU0F Sensor demo");
pinMode(ledPin, OUTPUT);
}
void loop()
{
float output_voltage, dust_density;
digitalWrite(ledPin, LOW); // power on the LED
delayMicroseconds(280); // Wait 0.28ms according to DS
// take analog reading
output_voltage = analogRead(dustPin);
delay(1);
digitalWrite(ledPin, HIGH); // turn the LED off
output_voltage = (output_voltage / 1023) * ANALOG_VOLTAGE;
dust_density = (0.18 * output_voltage) - 0.1;
Serial.print("Voltage = ");
Serial.print(output_voltage);
Serial.print(",\tDust Density = ");
Serial.print(dust_density);
Serial.println(" mg/m3");
delay(1000);
}
I use small fan over the dust sensor. Made a difference for me in getting anything else but 0's.
I notice you are setting the dust sensor LED to LOW to take a reading. I use HIGH.
Here is how I coded the dust sensor.
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, 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()
Thanks for the tip. I'll definitely try to put a fan next to it. I have also used your code and it seems to return normal readings already. The sensor instructions also said to connect it to the 5V pin, so I changed that in the code too.
void loop()
{
float ADbits = 4095.0f;
float uPvolts = 5.0f;
float adcRawValue = 0.0f;
float dustDensity = 0.0f;
const float K = 0.5f;
digitalWrite(ledPin, HIGH); // power on the LED
delayMicroseconds(280); // Wait 0.28ms according to DS
// take analog reading
adcRawValue = analogRead(dustPin);
delay(1);
digitalWrite(ledPin, LOW); // turn the LED off
adcRawValue = ( adcRawValue * uPvolts ) / ADbits;
dustDensity = (adcRawValue / K) * 100.0;
if ( dustDensity < 0.0f )
{
dustDensity = 0.00f; // make negative values a 0
}
Serial.print("Voltage = ");
Serial.print(adcRawValue);
Serial.print(",\tDust Density = ");
Serial.print(dustDensity);
Serial.println(" mg/m3");
delay(1000);
}