- -- 连接WiFi
- function connectWiFi()
- station_cfg={}
- station_cfg.ssid = "XGY-NJY"
- station_cfg.pwd = "njy123456"
- station_cfg.save = true
- print(wifi.sta.getip())
- wifi.setmode(wifi.STATION)
- wifi.sta.config(station_cfg)
- print(wifi.sta.getip())
- end
只需要修改成你的WIFI名字和密码即可
- -- OLED初始化
- function init_oled()
- i2c.setup(id, sda, scl, i2c.SLOW)
- disp = u8g2.ssd1306_i2c_128x32_univision(id, sla)
- -- 设置字体
- disp:setFont(u8g2.font_unifont_t_symbols)
- --disp:setFont(u8g2.font_6x10_tf)
- disp:setFontRefHeightExtendedText()
- --disp:setDrawColor(1)
- disp:setFontPosTop()
- disp:setFontDirection(0)
- -- 画边框
- --disp:drawFrame(0, 0, 128, 32)
- end
如果想要画个边框,可以去掉倒数第二行的注释“--”
接下来获取网络时间,先设置一下网络NTP服务器地址
- --NTP服务器列表
- NTP_SERVERS = {
- "ntp.aliyun.com",
- "time.asia.apple.com",
- "cn.ntp.org.cn",
- "time.windows.com",
- "cn.pool.ntp.org"
- }
- --获取网络时间
- function getNetTime()
- sntp.sync(NTP_SERVERS,
- function(sec, usec, server, info)
- print('sync', sec, usec, server)
- getWeather()
- end,
- function()
- print('failed!')
- end
- )
- end
获取天气信息,可以根据你的需要找一个支持json数据返回的天气服务网站,接口,我这里用的心知天气
- --获取天气
- function getWeather()
- http.get("http://api.seniverse.com/v3/weather/now.json?key=这里是你的私钥&location=nanjing&language=en&unit=c", nil,
- function(code, data)
- if (code < 0) then
- print("HTTP request failed")
- else
- -- print(code, data)
- r = sjson.decode(data)
- print("City: \t"..r.results[1]["location"]["name"])
- print("TianQiCode: \t"..r.results[1]["now"]["code"])
- print("\nTianQi: \t"..r.results[1]["now"]["text"])
- print("Tem: \t"..r.results[1]["now"]["temperature"])
- --推送到OLED显示
- --disp:clearBuffer()
- --disp:drawStr(0, 0, r.results[1]["location"]["name"]..":"..r.results[1]["now"]["text"].."-"..r.results[1]["now"]["temperature"])
- --disp:sendBuffer()
- --该函数仅用于获取天气信息存储在全局变量里,方便显示函数调用
- city = r.results[1]["location"]["name"]
- weather_now_code = tonumber(r.results[1]["now"]["code"])
- now_temperature = r.results[1]["now"]["temperature"]
- end
- end)
- end
其他的部分应该会Lua的都知道怎么写了,关键函数已提供。
效果非常的奈斯。
我设置的是第一行每隔五秒切换一次。
最后给大家看看我的完整源码
- -- 管脚定义
- sda = 5 -- GPIO14
- scl = 6 -- GPIO12
- sla = 0x3c -- oled的地址,一般为0x3c
- id = 0 -- iic总线 和 oled初始化,定义i2c编号id为0
- i = 0 --一个计数器
- --获取的信息
- city =""
- weather_now_code = 1
- now_temperature=25
- year=2022
- month=09
- day=07
- yday=1
- wday=1
- hour=1
- minute=1
- second=1
-
-
- --字符宽和高
- width = 16
- height = 16
- bits = string.char(
- --sting.char()方法
- --下边就是字模
- 0x06,0x00,0x89,0x2F,0x69,0x30,0x36,0x20,
- 0x10,0x20,0x18,0x00,0x18,0x00,0x18,0x00,
- 0x18,0x00,0x18,0x00,0x18,0x00,0x10,0x00,
- 0x30,0x20,0x60,0x10,0x80,0x0F,0x00,0x00
- )
- --显示到oled上
- function print_sheshidu(x,y)
- --是否显示背景色
- disp:setDrawColor(1)
- disp:setBitmapMode(0)
- -----以位图的方式显示
- disp:drawXBM(x,y,width,height,bits)
- end
-
-
-
- --NTP服务器列表
- NTP_SERVERS = {
- "ntp.aliyun.com",
- "time.asia.apple.com",
- "cn.ntp.org.cn",
- "time.windows.com",
- "cn.pool.ntp.org"
- }
-
- -- OLED初始化
- function init_oled()
- i2c.setup(id, sda, scl, i2c.SLOW)
- disp = u8g2.ssd1306_i2c_128x32_univision(id, sla)
- -- 设置字体
- disp:setFont(u8g2.font_unifont_t_symbols)
- --disp:setFont(u8g2.font_6x10_tf)
- disp:setFontRefHeightExtendedText()
- --disp:setDrawColor(1)
- disp:setFontPosTop()
- disp:setFontDirection(0)
- -- 画边框
- --disp:drawFrame(0, 0, 128, 32)
- end
- -- 显示函数
- function oled_show_msg()
- -- 设置显示内容
- disp:drawStr(0, 0, " --Hello OLED-- ")
- disp:drawStr(0, 16, "1234567890ABCDEF")
- -- 将内容发送到oled
- disp:sendBuffer()
- end
- -- 连接WiFi
- function connectWiFi()
- station_cfg={}
- station_cfg.ssid = "XGY-NJY"
- station_cfg.pwd = "njy123456"
- station_cfg.save = true
- print(wifi.sta.getip())
- wifi.setmode(wifi.STATION)
- wifi.sta.config(station_cfg)
- print(wifi.sta.getip())
- end
- --获取网络时间
- function getNetTime()
- sntp.sync(NTP_SERVERS,
- function(sec, usec, server, info)
- print('sync', sec, usec, server)
- getWeather()
- end,
- function()
- print('failed!')
- end
- )
- end
- function blinkTime()
- --获取当前时间写到全局变量,方便调用
- tm = rtctime.epoch2cal(rtctime.get()+(8*3600))
- year= tm["year"]
- month= tm["mon"]
- day = tm["day"]
- yday= tm["yday"]
- wday= tm["wday"]
- hour= tm["hour"]
- minute= tm["min"]
- second= tm["sec"]
- end
- function disTIME()
- tm = rtctime.epoch2cal(rtctime.get()+(8*3600))
- --打印转换后的年月日时分秒,以及今年的第几天,本周的第几天,本周第几天是从周日算第一天开始的,值的范围是1~7,周一是2
- print(string.format("%04d/%02d/%02d %02d:%02d:%02d %03d %d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"],tm["yday"],tm["wday"]))
- disp:clearBuffer() --每次显示新内容前,清理一下缓冲区,保证不受上次显示内容影响
- --推送给I2C显示年月日,今天是今年的第几天,今天是本周的第几天
- disp:drawStr(0, 0, string.format("%04d-%02d-%02d %03d %d", tm["year"], tm["mon"], tm["day"], tm["yday"], tm["wday"]))
- --第二行显示时分秒
- disp:drawStr(0, 16, string.format(" %02d:%02d:%02d ", tm["hour"], tm["min"], tm["sec"]))
- disp:sendBuffer()
- end
- --获取天气
- function getWeather()
- http.get("http://api.seniverse.com/v3/weather/now.json?key=换成你的私钥&location=nanjing&language=en&unit=c", nil,
- function(code, data)
- if (code < 0) then
- print("HTTP request failed")
- else
- -- print(code, data)
- r = sjson.decode(data)
- print("City: \t"..r.results[1]["location"]["name"])
- print("TianQiCode: \t"..r.results[1]["now"]["code"])
- print("\nTianQi: \t"..r.results[1]["now"]["text"])
- print("Tem: \t"..r.results[1]["now"]["temperature"])
- --该函数仅用于获取天气信息存储在全局变量里,方便显示函数调用
- city = r.results[1]["location"]["name"]
- weather_now_code = tonumber(r.results[1]["now"]["code"])
- now_temperature = r.results[1]["now"]["temperature"]
- end
- end)
- end
- function display_OLED091_A()
- disp:clearBuffer()
- disp:drawStr(0, 0, string.format("%04d-%02d-%02d %03d %d", year,month,day,yday,wday))
- disp:drawStr(0, 16,string.format(" %02d:%02d:%02d ", hour,minute,second))
- disp:sendBuffer()
- end
- function display_OLED091_B()
- disp:clearBuffer()
- --显示城市名
- disp:drawStr(0, 0, city.." ")
- --根据天气代码选择显示不同的图标表示天气信息
- --在显示位置上先计算前面的内容占用了多少宽度
- if(weather_now_code<=3) then
- disp:drawGlyph((string.len(city)+1)*8,0,0x2600)
- elseif (weather_now_code<=8) then
- disp:drawGlyph((string.len(city)+1)*8,0,0x2601)
- elseif (weather_now_code<=19) then
- disp:drawGlyph((string.len(city)+1)*8,0,0x2602)
- elseif (weather_now_code<=25) then
- disp:drawGlyph((string.len(city)+1)*8,0,0x2603)
- else
- disp:drawGlyph((string.len(city)+1)*8,0,0x2604)
- end
- --跟着显示温度
- disp:drawStr((string.len(city)+2)*8, 0, " "..now_temperature)
- --绘制℃
- print_sheshidu((string.len(city)+3+string.len(now_temperature))*8,0)
- --在第二行显示时分秒
- disp:drawStr(0, 16,string.format(" %02d:%02d:%02d ", hour,minute,second))
- disp:sendBuffer()
- end
- -- 主函数
- function main()
- init_oled()
- --开机显示一些简单的测试信息
- oled_show_msg()
- disp:clearBuffer()
- connectWiFi()
- getNetTime()
- --每1秒时间从本地取时间显示一次
- mytimer = tmr.create()
- mytimer:register(1000, tmr.ALARM_AUTO, function()
- blinkTime()
- i=i+1
- --print("This:", i)
- print("This".."-|"..string.format("%02d",i).."|-"..string.format("%04d/%02d/%02d %02d:%02d:%02d %03d %d", tm["year"], tm["mon"], tm["day"], tm["hour"], tm["min"], tm["sec"],tm["yday"],tm["wday"]))
- if (i>=60) then
- i=0
- print("a minute")
- elseif(i%10>=5) then
- display_OLED091_A()
- else
- --disTIME()
- display_OLED091_B()
- end
- end )
- mytimer:start()
- --定时每分钟从网络获取时间一次,每分钟获取一次天气信息
- NetTimer = tmr.create()
- NetTimer:register(60000, tmr.ALARM_AUTO,function()
- getNetTime()
- getWeather()
- print("get NET TIME")
- end )
- NetTimer:start()
-
- end
- -- 运行程序
- main()
第四步:
将代码保存成init.lua
通过串口上传到ESP8266模块即可。
好了,你学会了吗?这应该是当前网上最简单好学的一个物联网天气时钟教程了。
做了一块连接板,本来还想做外壳呢,想想算了,哈哈,后面可能还会玩其他的功能
https://www.bilibili.com/video/bv1GP4y1o7ey