Skip to content

Instantly share code, notes, and snippets.

@alexellis
Created July 8, 2018 20:09
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
IoT Sensor with NodeMCU & BME280 in Lua for blog.alexellis.io
-- Copyright Alex Ellis 2018
-- License MIT
local mySsid="SSID"
local myKey="WPA_PASSWORD"
function connect_wifi(ssid, key)
wifi.setmode(wifi.STATION)
wifi.sta.config(ssid,key)
wifi.sta.connect()
tmr.delay(1000000)
end
function wait_ip()
print("Waiting for IP")
local max=15
while(wifi.sta.getip() == nil)
do
max=max-1
tmr.delay(1000000)
print(string.format('WiFi attempt %d', max))
if max==0 then
return
end
end
print("Waited for IP")
print(wifi.sta.getip())
end
connect_wifi(mySsid,myKey)
wait_ip()
brokerHost="test.mosquitto.org"
interval=15000
mytimer = tmr.create()
mytimer:register(interval, tmr.ALARM_AUTO, function()
m = mqtt.Client("nodemcu", 120)
m:connect(brokerHost, 1883, 0, function(client)
print(string.format("Connected to broker: %s",brokerHost))
sda, scl = 3, 4
mode = bme280.init(sda, scl)
print(mode)
tmr.delay(1000000)
H, T = bme280.humi()
t = T / 100
h = H / 1000
ip = wifi.sta.getip()
if ip == nil then
ip = "127.0.0.1"
end
vdd33=adc.readvdd33()
RSSI=wifi.sta.getrssi()
if RSSI == nil then
RSSI=-1
end
msg = string.format('{"sensor": "s1", "humidity": "%.2f", "temp": "%.3f", "ip": "%s", "vdd33": "%d", "rssi": %d}', h, t, ip, vdd33, RSSI)
print(msg)
client:publish("sensor-readings", msg, 0, 0, function(client) print("sent") end)
m:close()
end, function(client, reason)
print("failed reason", reason)
end)
end)
tmr.start(mytimer)
@Terrabits
Copy link

I tried this script on a NodeMCU v1.0, but no matter how high I set max the connection was never made before the while loop in wait_ip() would quit. Reading through the tmr.delay docs, I saw this warning:

tmr.delay()
Busyloops the processor for a specified number of microseconds.

This is in general a bad idea, because nothing else gets to run, and the networking stack (and other things) can fall over as a result.

See documentation here

It's better to use something like tmr.alarm to make periodic checks for an IP address and continue when WiFi is available (or if it waits too long). Between alarms the networking stack will get a chance to run.

For example:

local ssid     = "ssid"
local password = "password"

function connect_to_wifi(ssid, password)
  wifi.setmode(wifi.STATION)
  wifi.sta.config(ssid, password)
  wifi.sta.connect()
end
function wait_for_ip(callback)
  tmr.create():alarm(100, tmr.ALARM_AUTO,
  function(t)
    if wifi.sta.getip() ~= nil then
      t:unregister()
      callback()
    end
  end)
end

function continue_with_wifi()
  gpio.write(4, gpio.LOW)
  print('Connected to WiFi')
end

gpio.mode (4, gpio.OUTPUT)
gpio.write(4, gpio.HIGH)
connect_to_wifi(ssid, password)
wait_for_ip(continue_with_wifi)

@alexellis
Copy link
Author

It's quite possible that you are right. This worked for me for half a dozen devices which I ran for several months on my home network. Feel free to tune the code as per your needs (that's why I wrote the tutorial, and made the source available)

How did you get on?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment