summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Friesel <derf@finalrewind.org>2022-05-18 19:26:59 +0200
committerDaniel Friesel <derf@finalrewind.org>2022-05-18 19:26:59 +0200
commit726446fe6eb1b12ca2fbd2ebbd3e519452e15077 (patch)
treeb9ca62e714017788a96ddba05539a053a7282c4a
parent231f24f48c4c69693c0ef5a8cec59b562307a425 (diff)
add support for reading the work period from the sensor
-rw-r--r--README.md15
-rw-r--r--init.lua18
-rw-r--r--sds011.lua31
3 files changed, 44 insertions, 20 deletions
diff --git a/README.md b/README.md
index b38159c..1f3c839 100644
--- a/README.md
+++ b/README.md
@@ -46,12 +46,14 @@ port = softuart.setup(9600, 2, 1)
port:on("data", 10, uart_callback)
function uart_callback(data)
- local pm25i, pm25d, pm10i, pm10d = sds011.parse_frame(data)
- if pm25i ~= nil then
- -- pm25i/pm10i contain the integer part (i.e., PM2.5 / PM10 value in µg/m³)
- -- pm25d/pm10d contain the decimal/fractional part (i.e., PM2.5 / PM10 fraction in .1 µg/m³, range 0 .. 9)
- else
- -- invalid checksum or non-data frame (i.e., acknowledgment of a write command)
+ 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
+ end
end
end
```
@@ -68,6 +70,7 @@ Currently, the following commands are supported
* 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; does not change it
* period == 0: continuous operation (about one measurement per second)
* 0 < *period* ≤ 30: about one measurement every *period* minutes; fan turned off in-between
diff --git a/init.lua b/init.lua
index 51aeafc..6dc32d0 100644
--- a/init.lua
+++ b/init.lua
@@ -25,12 +25,13 @@ end
function setup_client()
print("Connected")
gpio.write(ledpin, 1)
+ port = softuart.setup(9600, 2, 1)
+ port:on("data", 10, uart_callback)
publishing_mqtt = true
mqttclient:publish(mqtt_prefix .. "/state", "online", 0, 1, function(client)
publishing_mqtt = false
+ port:write(sds011.set_work_period(nil))
end)
- port = softuart.setup(9600, 2, 1)
- port:on("data", 10, uart_callback)
end
function connect_mqtt()
@@ -55,8 +56,7 @@ function connect_wifi()
end
function uart_callback(data)
- local pm25i, pm25f, pm10i, pm10f = sds011.parse_frame(data)
- if pm25i == nil then
+ if not sds011.parse_frame(data) then
print("Invalid or data-less SDS011 frame")
return
end
@@ -64,8 +64,14 @@ function uart_callback(data)
if sds011.work_period > 0 then
work_period = string.format("%d min", sds011.work_period)
end
- local json_str = string.format('{"pm2_5_ugm3": %d.%d, "pm10_ugm3": %d.%d, "rssi_dbm": %d, "period": "%s"}', pm25i, pm25f, pm10i, pm10f, wifi.sta.getrssi(), work_period)
- local influx_str = string.format("pm2_5_ugm3=%d.%d,pm10_ugm3=%d.%d", pm25i, pm25f, pm10i, pm10f)
+
+ local json_str = string.format('{"rssi_dbm":%d,"period":"%s"', wifi.sta.getrssi(), work_period)
+ if sds011.pm2_5i ~= nil then
+ json_str = string.format('%s,"pm2_5_ugm3":%d.%d,"pm10_ugm3":%d.%d', json_str, sds011.pm2_5i, sds011.pm2_5f, sds011.pm10i, sds011.pm10f)
+ local influx_str = string.format("pm2_5_ugm3=%d.%d,pm10_ugm3=%d.%d", sds011.pm2_5i, sds011.pm2_5f, sds011.pm10i, sds011.pm10f)
+ end
+ json_str = json_str .. '}'
+
if not publishing_mqtt then
watchdog:start(true)
publishing_mqtt = true
diff --git a/sds011.lua b/sds011.lua
index dc0004f..98f5b09 100644
--- a/sds011.lua
+++ b/sds011.lua
@@ -55,23 +55,38 @@ end
function sds011.set_work_period(period)
-- period == 0 : continuous operation, about one measurement per second
-- period > 0 : about one measurement every <period> minutes, fan is turned off in-between
- if period < 0 or period > 30 then
+ if period ~= nil and (period < 0 or period > 30) then
return
end
- sds011.work_period = period
- local cmd = string.char(c_head, c_id, c_workperiod, c_write, period)
+ local op = c_write
+ if period == nil then
+ op = c_read
+ period = 0
+ end
+ local cmd = string.char(c_head, c_id, c_workperiod, op, period)
cmd = cmd .. string.char(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
return sds011.finish_cmd(cmd)
end
function sds011.parse_frame(data)
local header, command, pm25l, pm25h, pm10l, pm10h, id1, id2, sum, tail = struct.unpack("BBBBBBBBBB", data)
- if header ~= c_head or command ~= 0xc0 or (pm25l + pm25h + pm10l + pm10h + id1 + id2) % 256 ~= sum or tail ~= c_tail then
- return nil
+ if header ~= c_head or (pm25l + pm25h + pm10l + pm10h + id1 + id2) % 256 ~= sum or tail ~= c_tail then
+ return false
+ end
+ if command == 0xc0 then
+ local pm25 = pm25h * 256 + pm25l
+ local pm10 = pm10h * 256 + pm10l
+ sds011.pm2_5i = pm25 / 10
+ sds011.pm2_5f = pm25 % 10
+ sds011.pm10i = pm10 / 10
+ sds011.pm10f = pm10 % 10
+ return true
+ end
+ if command == 0xc5 then
+ sds011.work_period = pm10l
+ return true
end
- pm25 = pm25h * 256 + pm25l
- pm10 = pm10h * 256 + pm10l
- return pm25 / 10, pm25 % 10, pm10 / 10, pm10 % 10
+ return false
end
return sds011