From 458ab0d7a91276e1e8a82ae532565b82ae9de05c Mon Sep 17 00:00:00 2001 From: Pat Thoyts <patthoyts@users.sourceforge.net> Date: Mon, 9 Jan 2017 22:17:58 +0000 Subject: [PATCH] ESP8266 temperature logging to MQTT device. Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net> --- .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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 literal 0 HcmV?d00001 diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..bfe3ec3 --- /dev/null +++ b/init.lua @@ -0,0 +1,37 @@ +require('tmr') +require('wifi') +require('file') + +-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there +dofile("config.lua") + +function startup() + if file.exists("application.lua") then + -- the actual application is stored in 'application.lua' + print("Running application.lua") + dofile("application.lua") + else + print('warning: missing file "application.lua"') + end +end + +function abort() + tmr.stop(1) +end + +print("Connecting to WiFi access point...") +wifi.setmode(wifi.STATION) +print('MAC: ' .. wifi.sta.getmac()) +wifi.sta.config(SSID, PASSWORD) +-- wifi.sta.connect() not necessary because config() uses auto-connect=true by default +tmr.alarm(1, 1000, tmr.ALARM_AUTO, function() + if wifi.sta.getip() == nil then + print("Waiting for IP address...") + else + tmr.stop(1) + print("WiFi connection established, IP address: " .. wifi.sta.getip()) + print("You have 5 seconds to abort (abort())") + print("Waiting...") + tmr.alarm(1, 5000, tmr.ALARM_SINGLE, startup) + end +end) -- 2.23.0