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