Basically, I find NodeMCU to be great at doing very little. No, I mean that literally - if there's something IoT really small you need to do, NodeMCU might be the right device. Might...
- Ironically, in my previous post I discussed how NodeMCU could be programmed via Arduino. I was worried it might take up more memory, though, than programming in Lua. According to this blog, however, the opposite is true. Lua, being an interpreted language, sucks up tons of memory. I found that to be true - my original code attempted to open two connections in the same function. It couldn't run due to memory errors.
- I've mentioned before, but using NodeMCU is a kludgey experience. The device is awesome in principle, and it's only in its infancy, but connecting and disconnecting the USB cable to reset the device time after time... It gets old after a while.
- Lua is a relatively straightforward language, but it has its drawbacks (including taken up memory for comments).It took me two separate evenings to figure out how to successfully make an http connection.
Regardless, let's jump in... The mission was to connect my IoT device to the cloud. The goal was to publish data to Weather Undeground - goal achieved: https://www.wunderground.com/personal-weather-station/dashboard?ID=KUTWESTJ26
I decided to connect to Adafruits IOT site, as well, just to make a little spiffy control out of it: https://io.adafruit.com/johnover/weather
To upload data, I'm using a simple init.lua script, then the bmp180.lua script (standard), then the wu_lite.lua script I wrote:
-- BMP085 and NodeMCU Weather Underground
-- Submits temp and pressure to WUnderground
--**************************************************************
alti=1509 -- set correction for your altitude location in meters
--**************************************************************
wifi.setmode(wifi.STATION)
wifi.sta.connect()
sda=4 -- GPIO2 connect to SDA BMP180
scl=3 -- GPIO0 connect to SCL BMP180
pres=0 -- pressure
temp=0 -- temperature
oss=0 -- over sampling setting
--load BMP module and read sensors
function ReadBMP()
bmp180 = require("bmp180")
bmp180.init(sda, scl)
bmp180.read(oss)
pres = (bmp180.getPressure()/100+alti/8.43)/33.86388667
temp = ((bmp180.getTemperature()/10)*9/5+32)
--fare = (temp*9/5+32)
--print("Pressure: "..string.format("%.1f",pres).." inches")
--print("Temperature: "..string.format("%.1f",temp).." deg C")
--print("Temperature: "..string.format("%.1f",fare).." deg F")
--print(" ")
-- push to WUnderground
host = "rtupdate.wunderground.com"
param = "/weatherstation/updateweatherstation.php?ID=<WU_ID>&PASSWORD=<wu_password&" ..
"dateutc=now&tempf="..string.format("%.1f",temp).."&baromin="..string.format("%.1f",pres) ..
"&softwaretype=NodeMCU%20version%20.01&action=updateraw&realtime=1&rtfreq=2.5"
print(host .. param)
sendRequest(host, param)
-- host = nil
-- param = nil
-- ******************************************************************
-- adafruit io
-- create http client http://benlo.com/esp8266/esp8266QuickStart.html
-- ******************************************************************
host = "io.adafruit.com"
param = "/api/groups/weather/send.json?x-aio-key=<Adafruit_IO_key&temperature="
..string.format("%.1f",temp).."&pressure="..string.format("%.1f",pres)
sendRequest(host, param)
-- release module
bmp180 = nil
package.loaded["bmp180"]=nil
end
function sendRequest(host, param)
conn = nil
conn = net.createConnection(net.TCP, 0)
conn:on("receive", function (conn, payload)
success = true
print(payload)
end)
-- once connected, request page
conn:on ("connection", function(conn, payload)
print('\nConnected')
conn:send("GET " .. param.. " HTTP/1.1\r\nHost: " ..host.. " Connection: close\r\nAccept: */*\r\nUser-Agent: Mozilla/5.1 (compatible; esp8266 Lua; Windows NT 5.1)\r\n\r\n")
end)
conn:on("disconnection", function(conn, payload) print(' \nDisconnected') end)
conn:connect(80, host)
-- release connection objects
conn = nil
payload = nil
--host = nil
--param = nil
end
-- First reading data
ReadBMP()
-- Periodic reading of the sensor
tmr.alarm(1,300000,1, function()ReadBMP()end)
I had a lot of logic issues as I went along, then ran into memory issues which forced me to refactor (which in and of itself wasn't necessarily bad - I drove some efficiency into my programming).
The next step is to set this up outdoors and let it roll for a day or to. Then I need to figure out how to insert a time stamp (Adafruit's IO site doesn't calculate it for you). Once I'm done with that in Lua, I'll build the same functionality in Arduino and see how much better it runs.