From 458ab0d7a91276e1e8a82ae532565b82ae9de05c Mon Sep 17 00:00:00 2001 From: Pat Thoyts Date: Mon, 9 Jan 2017 22:17:58 +0000 Subject: [PATCH 1/1] ESP8266 temperature logging to MQTT device. Signed-off-by: Pat Thoyts --- .gitignore | 4 ++ README.md | 22 +++++++++++ application.lua | 90 +++++++++++++++++++++++++++++++++++++++++++++ config.lua.example | 26 +++++++++++++ ds18b20.lua | 80 ++++++++++++++++++++++++++++++++++++++++ esp01_sensor.pdf | Bin 0 -> 28386 bytes init.lua | 37 +++++++++++++++++++ 7 files changed, 259 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 application.lua create mode 100644 config.lua.example create mode 100644 ds18b20.lua create mode 100644 esp01_sensor.pdf create mode 100644 init.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07da015 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/config.lua +/ESPlorer.Log +/ESPlorer.Log.lck + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff12389 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +MQTT Temperature Sensor +----------------------- + +Publish temperature over MQTT every 10 minutes + +Timer 4 reads the temperature every second and other +timers cause the last temperature reading to be published at intervals +over mqtt as defined in the config.lua file. We are sending to the local +server each minute and to a public one every 10 minutes. + + +The circuit board is an MP1584 based step-down board to provide 3V3 power +and two DS18B20 sensors hooked onto GPIO0 (aka pin 3 in nodemcu). +Also added 4K7 pullups to RST and EN and the 1-wire data line and +connected the ESP8266 serial lines to a molex RA header. + +Setup +----- + +Copy 'config.lua.example' to 'config.lua' and modify to suit your setup. +Upload to the ESP8266 device using luaload or esplorer etc. + diff --git a/application.lua b/application.lua new file mode 100644 index 0000000..36df79a --- /dev/null +++ b/application.lua @@ -0,0 +1,90 @@ +require('ds18b20') +require('mqtt') +require('gpio') + +dofile('config.lua') + +function mqtt_build_message() + local r = {} + for id,t in pairs(ds18b20.values) do + local t1 = t / 10000 + local t2 = (t >= 0 and t % 10000) or (10000 - t % 10000) + table.insert(r, string.format("{\"id\":\"%s\",\"temp\":%d.%04d}", id, t1, t2)) + end + return "[" .. table.concat(r, ",") .. "]" +end + +function mqtt_publish(m, prefix) + local topic = prefix .. '/' .. node.chipid() + m:publish(topic .. '/temperature', mqtt_build_message(), 0, 0, nil) +end + +function mqtt_create_client(server, prefix, timerid, interval) + local m = mqtt.Client(node.chipid(), 60, MQTT_USERNAME, MQTT_PASSWORD, 0) + m:lwt(prefix .. '/' .. node.chipid() .. '/error', 'disconnected', 0, 0) + m:on("connect", function(client) + mqtt_publish(client, prefix) + -- max time is 6870947 (1:54:30.947) + tmr.alarm(timerid, interval, 1, function() mqtt_publish(client, prefix) end) + end) + m:on("offline", function(client) + tmr.stop(timerid) + m:connect(server, MQTT_PORT, 0, 1) + end) + m:connect(server, MQTT_PORT, 0, 1) + return m +end + +function mqtt_start() + local clients = {} + ds18b20.update() + tmr.alarm(SENSOR_TIMER, SENSOR_INTERVAL * 1000, tmr.ALARM_AUTO, ds18b20.update) + for index,broker in ipairs(MQTT_BROKERS) do + local interval = broker.interval * 1000 + local m = mqtt_create_client(broker.host, broker.prefix, broker.timer, interval) + table.insert(clients, m) + end + return clients +end + +function mqtt_stop() + print("mqtt_stop") + for index,broker in ipairs(MQTT_BROKERS) do + tmr.stop(broker.timer) + tmr.unregister(broker.timer) + end + for index,client in ipairs(clients) do + if pcall(client.close) then + print("closed client") + else + print("failed to close client") + end + end + tmr.stop(SENSOR_TIMER) + tmr.unregister(SENSOR_TIMER) +end + +LED_STATE = 1 + +function blink() + if LED_STATE == 1 then + LED_STATE = 0 + else + LED_STATE = 1 + end + gpio.write(LED_PIN, LED_STATE) +end + +function blink_start() + gpio.mode(LED_PIN, gpio.OUTPUT) + tmr.alarm(LED_TIMER, LED_INTERVAL, tmr.ALARM_AUTO, blink) +end + +function blink_stop() + tmr.stop(LED_TIMER) + tmr.unregister(LED_TIMER) +end + +ds18b20.init(SENSOR_PIN) +blink_start() +clients = mqtt_start() diff --git a/config.lua.example b/config.lua.example new file mode 100644 index 0000000..c8069cc --- /dev/null +++ b/config.lua.example @@ -0,0 +1,26 @@ +-- WiFi network to join and the PSK password + +SSID='WIFI_SSID_HERE' +PASSWORD='WIFI_PASSWORD' + +SENSOR_PIN = 3 +SENSOR_TIMER = 2 +SENSOR_INTERVAL = 10 -- seconds + +LED_PIN = 4 +LED_TIMER = 5 +LED_INTERVAL = 1000 + +-- Username and password to use for MQTT +MQTT_PORT = 1883 +MQTT_USERNAME='' +MQTT_PASSWORD='' + +-- MQTT brokers and prefixes +-- +-- a list of MQTT brokers to publish too with a custom prefix for +-- each broker. Use a separate timer id for each broker. +MQTT_BROKERS = { + -- iot.eclipse.org + { host='198.41.30.241', prefix='mqtt_sensor_demo/nodemcu', timer=4, interval=600 } +} diff --git a/ds18b20.lua b/ds18b20.lua new file mode 100644 index 0000000..208ec9b --- /dev/null +++ b/ds18b20.lua @@ -0,0 +1,80 @@ +local modname = ... +local M = {} -- public interface +_G[modname] = M + +require('bit') +require('ow') + +M.CONVERT = 0x44 +M.READ_SCRATCHPAD = 0xBE + +local function hexstring(...) + local len = select('#', ...) + local r = {} + for n = 1, len do r[n] = string.format("%02x", select(n,...)) end + return table.concat(r, ':') +end + +local function find_devices(pin) + ow.setup(pin) + ow.reset_search(pin) + local devices = {} + repeat + local addr = ow.search(pin) + if addr ~= nil then table.insert(devices, addr) end + tmr.wdclr() + until addr == nil + return devices +end + +function M.init(pin) + M.pin = pin + M.timerid = 1 + M.delay = 800 + M.pending = 0 + M.values = {} + M.sensors = find_devices(pin) +end + +function M.read_sensors() + local pin = M.pin + for i,addr in ipairs(M.sensors) do + local id = hexstring(addr:byte(1,8)) + ow.reset(pin) + ow.select(pin,addr) + ow.write(pin,M.READ_SCRATCHPAD,1) + local data = nil + data = string.char(ow.read(pin)) + for i = 1, 8 do + data = data .. string.char(ow.read(pin)) + end + local crc = ow.crc8(string.sub(data,1,8)) + if (crc == data:byte(9)) then + local t = data:byte(1) + data:byte(2) * 256 + if (t > 32768) then + -- convert unsigned to signed twos complement. + t = (bit.bxor(t, 0xffff) + 1) * -1 + end + t = t * 625 + print(id, t) + M.values[id] = t + else + print(id, "bad crc") + end + M.pending = M.pending - 1 + end +end + +function M.update() + local t = 0 + M.pending = 0 + for i,addr in ipairs(M.sensors) do + ow.reset(M.pin) + ow.select(M.pin, addr) + ow.write(M.pin, M.CONVERT, 1) + M.pending = M.pending + 1 + end + tmr.alarm(M.timerid, M.delay, tmr.ALARM_SINGLE, M.read_sensors) +end + +return M diff --git a/esp01_sensor.pdf b/esp01_sensor.pdf new file mode 100644 index 0000000000000000000000000000000000000000..73705b81a104d540b48935ce71200d0bd601c2b5 GIT binary patch literal 28386 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 jO52%%$N4n|{zR3ti;