NodeMCU MQTT battery powered wifi thermometer

This page is not finished, more info will be added soon.

Results

Images on server are updated every 5 minutes. Press F5 to update and see most recent charts.

Temperature last day Temperature last week Temperature last month Battery voltage last month

Lua code

There are 3 .lua scripts in this device now.

init.lua

This file is launched by the firmware whit every NodeMCU FW boot / wakeup. This file checks if the device was waked up from deepsleep or not. If it was not wake from deepsleep it waits 10s before it check if app.lc file exists (in case of wakeup from deepsleep there is no 10s delay). If app.lc exists, it is launched.

print(" ")
print("Bgr init.lua v1.2")
_, reset_reason = node.bootreason()
print("Bootreason = " .. reset_reason)

appfilename = "app.lc"

print("Checking if " .. appfilename .. " exists")
if file.exists(appfilename) then
    --appfile exists
    print(appfilename .. " exists!")
    if reset_reason == 5 then 
        print("It was wake from deep sleep, no waiting, launching " .. appfilename)
        dofile (appfilename)
    else
        print("It wasnt wake from deepsleep, wait 10sec and then run " .. appfilename)    
        tmr.alarm(1,10000,0,function()
            dofile (appfilename)
        end)
    end

else
    --appfile does not exists
    print(appfilename .. " does not exist, nothing to launch, quitting...")
end

app.lua - app.lc

This is the main app, I compiled it into app.lc after upload to ESP.

address = 0x4F  -- LM75 I2C Address
temp_reg = 0     -- temp reg for normal operation
temp_reg_shutdown = 1 --temp reg pro shutdown
bus = 0              -- I2C bus
sda, scl = 3, 4   -- Used pins for SDA (3=gpio0) and SCL (4=gpio2)
sleeptime = 60000000 --cas mezi odesilanim dat v us

function init_I2C(sda, scl)
    i2c.setup(bus, sda, scl, i2c.SLOW)
end 

function sleep()
  --print debug info
  print("going to sleep for " .. sleeptime/1000000 .. "s")

  --disconnect from broker
  m:close()

  --shutdown lm75
  i2c.start(bus)      
  i2c.address(bus, address, i2c.TRANSMITTER)
  i2c.write(bus, temp_reg_shutdown)
  i2c.stop(bus)

  node.dsleep(sleeptime, 1)

end

function read_temp() 
  i2c.start(bus)      
  i2c.address(bus, address, i2c.TRANSMITTER)
  i2c.write(bus, temp_reg)
  i2c.stop(bus)

  i2c.start(bus)
  i2c.address(bus, address, i2c.RECEIVER)
  t=i2c.read(bus, 2)
  i2c.stop(bus)

  h,l = string.byte(t,1,2)

  if h > 127 then 
    --zaporne teploty
    h = h - 255 
    l=(bit.band(bit.bnot(bit.rshift(l, 5))+1, 7))*125

    --zaokrouhlit desetiny na jedno misto
    l = ((l + 50) / 100)

    if h == 0 then
        --zaporne od 0 do -0.9999
        temp=string.format("-%d.%d", h,l)
    else
        --zaporne pod -1
        temp=string.format("%d.%d", h,l)
    end

  else
    -- kladne teploty
    l=(bit.band(bit.rshift(l, 5), 7))*125  

    --zaokrouhlit desetiny na jedno misto
    l = ((l + 50) / 100)

    temp=string.format("%d.%d", h,l)
  end

  return temp

end

-- init mqtt client with keepalive timer 120sec
m = mqtt.Client("some-cli-ID", 120, "broker-username", "broker-password")

m:on("offline", function(client) print ("offline") end)

function connectbroker (b)
    b:connect("your-broker-server", 8883, 1, function(client) 
                                        print("connected to broker")
                                        print ("temp: " .. t .. "C")
                                        m:publish("espthermo/temp",t,0,0, function(client) 
                                            print("temp ack")
                                            print ("battery: " .. battvolt .. "mV")
                                            m:publish("espthermo/batt",battvolt,0,0, function (client)
                                                print ("voltage ack")
                                                wifirssi=wifi.sta.getrssi()
                                                print ("wifi rssi: " .. wifirssi .. "dBm")
                                                m:publish("espthermo/wifi",wifirssi,0,0, function (client)
                                                    print("rssi ack")
                                                    sleep() 
                                                    end)
                                                end)
                                            end)
                                        end)
end

print(" ")
init_I2C(sda, scl)
battvolt=(adc.readvdd33(0))
t=read_temp()
print("Connecting to WiFi")
wifi.sta.eventMonReg(wifi.STA_GOTIP, function() 
    print("got IP:", wifi.sta.getip())
    connectbroker (m)
    end)

wifi.sta.eventMonStart()

wifi.sta.connect()

-- timer to go sleep after 10s even if cant send data to save battery
tmr.alarm(1,10000,0,function()
    print ("timeout sending data, turning off to save battery")
    sleep()
end)

cfg.lua

This file sets the WiFi name / password and othr options. Launch it just once - ESP will remember these options even after reboot / disconnect of power.

-- wifi mode
wifi.setmode(wifi.STATION)

-- band
wifi.setphymode(wifi.PHYMODE_G)

-- wifi network ssid / pwd + save
station_cfg={}
station_cfg.ssid="your-ssid"
station_cfg.pwd="wifi-password"
station_cfg.save=true
station_cfg.auto=true
wifi.sta.config(station_cfg)

-- disable autoconnect
wifi.sta.autoconnect(0)

-- init adc to read VDD33
adc.force_init_mode(adc.INIT_VDD33)

-- restart to apply
node.restart()

It

Links

Like my blog? Want to buy me coffee or beer?

LTC (litecoin): LeWzkcV2ArRv7Bi7TmrTpwkp6j2CZSLwfY

BTC (bitcoin): 1LzmUcwHK5Ys4zGPRoxYodjzpJsWiG61JY

DOGE (dogecoin): DQmS6EdDXssriDgSBpQMxYicHTiji6kMhx

ETH (ethereum): 0x387ff39c66e71c454ce5844c188c1a87835d2263

USDT (tether@ETH): 0xa69cae5a1da5ff5fb226e4bc87fe5d0f8c45908a

MANA (decentraland): 0xa69cae5a1da5ff5fb226e4bc87fe5d0f8c45908a

XMR (monero): 4JUdGzvrMFDWrUUwY3toJATSeNwjn54LkCnKBPRzDuhzi5vSepHfUckJNxRL2gjkNrSqtCoRUrEDAgRwsQvVCjZbRxBb8sEWJB1SCCuUEa