diff options
| -rw-r--r-- | README.md | 15 | ||||
| -rw-r--r-- | init.lua | 18 | ||||
| -rw-r--r-- | sds011.lua | 31 | 
3 files changed, 44 insertions, 20 deletions
| @@ -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 @@ -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 @@ -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 | 
