summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2022-05-29 11:03:38 +0200
committerDaniel Friesel <derf@finalrewind.org>2022-05-29 11:14:29 +0200
commita3352b1d8e3fe2fd3992142358013120791c4464 (patch)
treee308b62f149d9cb009f1f735fa1870ec3d9f50e2
parenta53edf85913d8f12e0640606dc61873d9b3e8745 (diff)
Add work/sleep query option and state tracking variable
-rw-r--r--README.md42
-rw-r--r--sds011.lua28
2 files changed, 52 insertions, 18 deletions
diff --git a/README.md b/README.md
index f7e8505..e9741ab 100644
--- a/README.md
+++ b/README.md
@@ -47,36 +47,58 @@ port:on("data", 10, uart_callback)
function uart_callback(data)
if sds011.parse_frame(data) then
- -- PM values or work period have been updated
if sds011.pm2_5i ~= nil then
-- pm2_5i/pm10i contain the integer part (i.e., PM2.5 / PM10 value in µg/m³)
- -- pm2_5d/pm10d contain the decimal/fractional part (i.e., PM2.5 / PM10 fraction in .1 µg/m³, range 0 .. 9)
- else
- -- sds011.work_period has been updated after using sds011.set_work_period
+ -- pm2_5f/pm10f contain the decimal/fractional part (i.e., PM2.5 / PM10 fraction in .1 µg/m³, range 0 .. 9)
end
end
end
```
-## SDS011 Configuration API
+## SDS011 API
If desired, **sds011.lua** can be used to configure the SDS011 sensor.
-Currently, the following commands are supported
+
+### Commands
* `port:write(sds011.set_report_mode(active))`
* active == nil: request current mode; do not change it.
The mode can be read from `sds011.active_mode` after a few milliseconds.
* active == true: periodically report PM2.5 and PM10 values via UART
* active == false: only report PM2.5 and PM10 values when queried
-* `port:write(sds011.sleep(sleep))`
- * sleep == true: put sensor into sleep mode.
- The fan is turned off, no further measurements are performed.
- * sleep == false: wake up sensor
* `port:write(sds011.set_work_period(period))`
* period == nil: request current work period; do not change it.
The work period can be read from `sds011.work_period` after a few milliseconds.
* period == 0: continuous operation (about one measurement per second)
* 0 < *period* ≤ 30: about one measurement every *period* minutes; fan turned off in-between
+* `port:write(sds011.sleep(sleep))`
+ * sleep == nil: query current sleep mode; do not change it.
+ The mode can be read from `sds011.working` after a few milliseconds; do
+ not trust its value before that.
+ Background: SDS011 sensors only respond to a sleep mode query when they are
+ not in sleep mode. To handle this, the driver sets `sds011.working = false`
+ when running the query, and reverts it to `sds011.working = true` only if
+ it receives an appropriate response.
+ * sleep == true: put sensor into sleep mode.
+ The fan is turned off, no further measurements are performed. In this mode,
+ `port:write(sds011.sleep(false))` is the only command accepted by the
+ device.
+ * sleep == false: wake up sensor
+* `port:write(sds011.query())`: Query PM2.5 and PM10 values in passive mode.
+ data is available after a few milliseconds.
+
+### Variables
+
+* `sds011.active_mode`
+ * true: the sensor automatically reports readings
+ * false: the sensor only reports readings when queried
+* `sds011.work_period`
+ * 0: perform one reading measurement every second
+ * otherwise: number of minutes between measurements
+* `sds011.working`
+ * true: the sensor is enabled
+ * false: the sensor is in sleep mode
+* `sds011.pm2_5i`, `sds011.pm2_5f`, `sds011.pm10i`, `sds011.pm10f`: see Usage
## Application Example
diff --git a/sds011.lua b/sds011.lua
index 44b965b..06cd5ac 100644
--- a/sds011.lua
+++ b/sds011.lua
@@ -18,8 +18,9 @@ local c_sleep = 0x00
local c_work = 0x01
local c_workperiod = 0x08
-sds011.work_period = nil
sds011.active_mode = nil
+sds011.work_period = nil
+sds011.working = nil
function sds011.finish_cmd(cmd)
cmd = cmd .. string.char(0xff, 0xff)
@@ -46,18 +47,22 @@ function sds011.set_report_mode(active)
elseif active then
cmd = c_active
end
- local cmd = string.char(c_head, c_id, c_report_mode, op, cmd)
+ cmd = string.char(c_head, c_id, c_report_mode, op, cmd)
cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
return sds011.finish_cmd(cmd)
end
-function sds011.sleep(sleep)
- local cmd = string.char(c_head, c_id, c_sleepcmd, c_write)
- if sleep then
- cmd = cmd .. string.char(c_sleep)
- else
- cmd = cmd .. string.char(c_work)
+function sds011.set_sleep(sleep)
+ local op = c_write
+ local cmd = c_work
+ if sleep == nil then
+ -- if the device is sleeping, it will not respond to a query
+ sds011.working = false
+ op = c_read
+ elseif sleep then
+ cmd = c_sleep
end
+ cmd = string.char(c_head, c_id, c_sleepcmd, op, cmd)
cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
return sds011.finish_cmd(cmd)
end
@@ -94,6 +99,13 @@ function sds011.parse_frame(data)
elseif command == 0xc5 and pm25l == 0x02 then
sds011.active_mode = pm10l == 0
return true
+ elseif command == 0xc5 and pm25l == 0x06 then
+ if pm25h == 0 or pm10l == 1 then
+ sds011.working = true
+ else
+ sds011.working = false
+ end
+ return true
elseif command == 0xc5 and pm25l == 0x08 then
sds011.work_period = pm10l
return true