Unverified Commit 726446fe authored by Daniel Friesel's avatar Daniel Friesel
Browse files

add support for reading the work period from the sensor

parent 231f24f4
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -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)
	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
		-- invalid checksum or non-data frame (i.e., acknowledgment of a write command)
			-- 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

+12 −6
Original line number Diff line number Diff line
@@ -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
+23 −8
Original line number Diff line number Diff line
@@ -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