使用NodeMcu ESP8266开发板(其实就是带了个USB-TTL和自动重启),驱动ssd1306 I2C OLED 12864 屏幕,通过WiFi联网获取时间及天气信息及PM2.5信息
(没错这400多的PM2.5正是我大霾都-北京)
NodeMCU的lua开发,使用了两个天气的API,代码见下文
配套的NodeMCU固件下载:https://1drv.ms/u/s!AnyMcqveiSwuhzEYIHmd7TdEg12C
包含模块:cjson
file
gpio
http
i2c
net
node
ow
rtctime
sntp
tmr
u8g
uart
wifi及u8g的6x10,7x14r,9x18r几个字体。
-- Clock 2 - OLED Display clock TIMEZONE = 8 SDA_PIN = 2 -- OLED SDA Pin SCL_PIN = 1 -- OLED SCL Pin WEATHER_CITY = "Beijing" DAYS = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"} WEATHER_TEXT="" WEATHER_TEMP="" WEATHER_PM25="" function getTime() -- Get Time by connecting to timeapi.org sntp.sync('time-a.nist.gov', function(sec,usec,server) print('sync', sec, usec, server) end, function() print('sntp.sync() failed!') end ) end function getWeather() http.get("http://api.thinkpage.cn/v3/weather/now.json?key=3puseql9n2vxuknr&location=Beijing&language=en", nil, function(code, data) if (code < 0) then print("HTTP request failed") else print(code, "weather ok") weather = cjson.decode(data) WEATHER_TEXT = weather["results"][1]["now"]["text"] WEATHER_TEMP = weather["results"][1]["now"]["temperature"] end -- Then get PM2.5 data node.task.post(function() http.get("http://api.jirengu.com/weather.php", nil, function(code, data) if (code < 0) then print("HTTP request failed") else print(code, "PM2.5 ok") weather = cjson.decode(data) WEATHER_PM25 = weather["results"][1]["pm25"] end end) end) end) end function init_OLED(SDA_PIN, SCL_PIN) --Set up the u8glib lib sla = 0x3C i2c.setup(0, SDA_PIN, SCL_PIN, i2c.SLOW) disp = u8g.ssd1306_128x64_i2c(sla) -- disp:setFontRefHeightExtendedText() disp:setFont(u8g.font_6x10) disp:setFontPosTop() -- disp:setRot180() -- Rotate Display if needed end function update_OLED() -- Write Display disp:firstPage() repeat disp:setColorIndex(1); disp:drawBox(0, 0, 128, 64) disp:setColorIndex(0); disp:setFont(u8g.font_7x14r) disp:drawStr(5, 13, "NTP Clock v2") unixTime = rtctime.get() tm = rtctime.epoch2cal(unixTime + TIMEZONE*3600) -- print(string.format("%04d/%02d/%02d %02d:%02d:%02d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"])) disp:setFont(u8g.font_9x18r) disp:drawStr(30, 35, string.format("%02d:%02d:%02d", tm["hour"], tm["min"], tm["sec"])) disp:setFont(u8g.font_6x10) disp:drawStr(40, 45, DAYS[tm["wday"]]) disp:drawStr(60, 45, string.format("%02d-%02d", tm["mon"], tm["day"])) -- disp:drawStr(10, 55, WEATHER_CITY.." "..WEATHER_TEXT.." "..WEATHER_TEMP.."'C") disp:drawStr(16, 55,WEATHER_TEXT.." "..WEATHER_TEMP.."'C PM"..WEATHER_PM25) -- disp:drawStr(3, 63, "@Wu23333") until disp:nextPage() == false if(unixTime+30 % 3600 == 0)then getTime() getWeather() end end -- Main Program init_OLED(SDA_PIN,SCL_PIN) getTime() getWeather() tmr.alarm(0, 1000, 1, function() update_OLED() end)
上面是主程序,传进去后执行它,就可以看到效果了。
下面是一个用于调试用的init.lua脚本的内容,具有重新设置wifi信息,和延迟启动的功能(主程序需要命名为application.lua)
-- wifi config STATION_ENABLED = true SSID = "YourWiFiSSID" PASSWORD = "YourWiFiPassword" AP_ENABLED = true AP_SSID = "NodeMCU" AP_PASSWORD = "Password" function startup() if file.open("stop.lua") ~= nil then print("stop.lua deleted, abort") else print("Running") file.close("init.lua") -- the actual application is stored in 'application.lua' dofile("application.lua") end end -- the script start here node.setcpufreq(node.CPU160MHZ) if(STATION_ENABLED and AP_ENABLED)then wifi.setmode(wifi.STATIONAP) wifi.ap.config({ssid=AP_SSID, pwd=AT_PASSWORD}) print("SOFTAP is configured") wifi.sta.config(SSID, PASSWORD) else if(STATION_ENABLED)then wifi.setmode(wifi.STATION) wifi.sta.config(SSID, PASSWORD) end if(AP_ENABLED)then wifi.setmode(wifi.SOFTAP) wifi.ap.config({ssid=AP_SSID, pwd=AT_PASSWORD}) print("SOFTAP is configured") end end if(STATION_ENABLED)then print("Connecting to WiFi access point...") tmr.alarm(1, 1000, 1, 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("Create a file named 'stop.lua' in 5 seconds to abort the start") print("Waiting...") tmr.alarm(0, 5000, 0, startup) end end) else print("DEBUG: Create a file named 'stop.lua' in 5 seconds to abort the start") print("Waiting...") tmr.alarm(0, 5000, 0, startup) end
很欣赏你的作品,我是一个退休人员,不会单片机。能不能提供完整的程序。让我也实践一下。希望得到你的支持,谢谢!
上面这段就是完整的程序。
首先需要给ESP8266刷入NodeMCU固件,然后用ESPlorer这个IDE通过串口连接ESP8266,然后把上面这段代码存成lua并传输到ESP8266里,然后执行它就可以了。如果每次想让ESP8266一上电就执行的话可以把文件命名为init.lua
用工具ESP8266Flasher-x86-v0.9.2.4刷了v0.9.2.3 AT Firmware固件,用LuaStudio编译了init.lua,用LuaLoader工具刷init.lua到esp8266溢出全是乱码。1306上什么也没有。问二个问题:1.要专用固件?2.怎么连自家的WIFI?
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
或者也可以使用我新放上去的init.lua,如果调试的话可以配合这个脚本,以便可以阻止问题的程序自动启动。
你使用了SNTP,RTCTIME,I2C,U8G等非官方固件包含的模块,干脆把你的定制NodeMCU固件也共享一下吧,省得金声叔再去折腾那个英文网站。
ESPlorer这个东东没地方下载,,,,
恳求发一份我邮箱,jings_ks@hotmail.com
退休在家,想给自己增加的知识,因为从小爱好,巧遇文革,学识有限,只能求教于能人,望给予支持为盼!再次谢谢!
退休在家,想给自己增加点知识,原因是因为从小爱好,后又巧遇文革,所以,学识有限,只能求教于能人,望先生能给予支持为盼!再次谢谢!
谢谢你能发个固件我邮箱,让我也学习和实践一下!
近些天有些忙,没有看到回复,十分抱歉
我先把ESPlorer发给您吧,NodeMCU固件的话我得找找,找不到的话我再重新编译一个。
另外AT固件的话只能通过串口接受AT指令,需要配合其他控制器才能使用,所以这里没有使用AT固件
固件也发给你了
楼主你的固件地址打不开啊固件能邮箱发我一下吗1349788562@qq.com
我的固件里没有i^2c,u8g,http,很头疼。