使用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 rtctimesntp 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,很头疼。