I’ve done plenty of searching but haven’t found any discussion for this sensor in ESPHome, and my implementation isn’t working as well as expected.
This might be a simple question on the use of delay() in ESPHome libraries (included xxxx.h files). Does delay(x) cause a wait of x milliseconds OR x microseconds - can an expert confirm? Based on what I’ve read it appears the former - if this is the case what function can I use for a sub-millisecond delay?
The sensor operation is simple: turn on a LED via a pin, wait 0.28msec, read an analogue value, wait 0.40msec, turn the LED off. Repeat this every 10msec (max). Apply a bit of maths and you can convert the ADC value to voltage and then to an air quality figure in µg/m³.
Located library code (GitHub - malfroid/esphome-KS0196: Simple code for ESP-based custom dust sensor using Sharp GP2Y1010AU0F sensor in the Keyestudio KS0196 PM2.5 Dust Sensor Module.
which is pretty well the same as arduino code I’ve found) performs the read/write function:
digitalWrite(PIN_LED, LOW); delay(280); value = analogRead(PIN_ADC); delay(40); digitalWrite(PIN_LED, HIGH); voltage = value * (VOLTAGE_VREF / 1024.0); publish_state(170 * voltage - 0.1);
The basic sensor config in an ESPHome yaml:
- platform: custom
lambda: |-
auto dust_sensor = new GP2Y1010AU0F();
App.register_component(dust_sensor);
return {dust_sensor};
sensors:
name: "${upper_devicename} PM2.5 Dust Sensor"
accuracy_decimals: 2
unit_of_measurement: "µg/m³"
icon: "mdi:smog"
This works…kind of. I get results, but for 20% of readings at best. I have multiple sensors all producing the same result so don’t think it’s hardware. In fact, if I turn on the LED permanently I get the same quality of readings (at best 20% non-zero and same range of numerical values return), which from the datasheet looks incorrect.
A 280msec delay instead of 280usec could be the problem. Is there a delaymillis()
or usleep()
etc that I should use?
Ideally I’d get the function call to perform multiple reads (say 10 readings spaced 10msec apart per Sharp datasheet), and average the non-zero results before returning a value to ESPHome.