esp8266学习笔记:OLED天气气象站+网络授时

一:准备材料

1.Nodemcu				1个
2.OLED屏幕				1个
3.心知天气账号			1个 

心知天气API网址:https://www.seniverse.com/signup?callback=%2Fdoc
这些大家都可以进行注册,主要使用的是心知天气的API接口来获取天气例如:在这里插入图片描述
其中key=你的密匙 location=需要获取天气的城市 language=需要的语言
大家可以通过API使用文档进行了解。
密匙是你的控制台中显示的密匙
esp8266学习笔记:OLED天气气象站+网络授时_第1张图片

二:固件下载

本程序需要添加固件如下:wifi,u8g ,sntp ,tmr ,cjson ,i2c ,gpio…

注意:u8g的字体记得要包含font_10x20font_6x10两种。

esp8266学习笔记:OLED天气气象站+网络授时_第2张图片

三:程序代码

wifi.lua

cfg={}
cfg.ssid = "ESP"			--账号
cfg.pwd = "123456789"		--密码

wifi.setmode(wifi.STATION)
wifi.sta.config(cfg)

tmr.alarm(0, 1000, tmr.ALARM_AUTO, function()
    if wifi.sta.getip() == nil then
        print("IP unavaiable, Waiting...")
    else
        print("Config done, IP is "..wifi.sta.getip())
        dofile("tianqi.lua")
        tmr.stop(0)
    end
end)
dofile("OLED.lua")

tianqi.lua

cit="zhengzhou"


function  tianqi()
    sntp.sync({ '120.25.108.11','102.120.2.101' }		--网络授时的服务器IP地址,可以通过ping来识别能不能使用
        function(sec,usec,server)
          print('sync', sec, usec, server)
          suer=user
        end
        function(index)
          print('failed:'..index)
        end)
        
   local srv=net.createConnection(net.TCP,0)
    srv:on("receive", function(conn, pl)
        i,j=string.find(pl, "{")
        sjson_str=string.sub(pl, i)
        local sjson = require("cjson")
        local weather = sjson.decode(sjson_str)
        City=weather["results"][1]["location"]["name"]
        Weather=weather["results"][1]["now"]["text"]
        Temperature=weather["results"][1]["now"]["temperature"]
        print(Weather.."\n"..City.."\n"..Temperature.."\n")
    end)
    srv:on("connection", function(conn, pl)
        conn:send("GET /v3/weather/now.json?key=qaqrbytdubgb6oto&location="..cit.."&language=en&unit=c HTTP/1.1\r\nHost: api.seniverse.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
    end)
    srv:connect(80,"api.seniverse.com")
end
tmr.alarm(1, 10000, tmr.ALARM_AUTO, function()
        tianqi()
 end)

在上面的代码中·sntp.sync({ '120.25.108.11','102.120.2.101' }含有两个IP地址,一个作为备用,通过ping来确定能不能接受和使用
方法:
1.‘’win+r‘’之后输入cmd,点击回车键
2.在控制面板上输入ping 120.25.108.11或者ping 102.120.2.101来查看能不能接受使用和延时
esp8266学习笔记:OLED天气气象站+网络授时_第3张图片

OLED.lua

sda = 1
scl = 2
TIMEZONE = 8
DAYS = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
City=""
Weather=""
Temperature=""
suer=""


local cloudy_width = 40
local cloudy_height = 40
local cloudy_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x81, 0x01, 0x00, 0x00, 0x04,
0x81, 0x00, 0x00, 0x00, 0x0C, 0x41, 0x00, 0x00, 0x00, 0x08, 0x60, 0x00,
0x00, 0x00, 0xF8, 0x2F, 0x00, 0x00, 0x00, 0x0C, 0x18, 0x00, 0x00, 0x7E,
0x06, 0x20, 0x00, 0x80, 0xC1, 0x13, 0x40, 0x0E, 0xC0, 0x00, 0xFF, 0xC0,
0x02, 0x60, 0x00, 0x82, 0x81, 0x00, 0x20, 0x00, 0x00, 0x83, 0x00, 0x30,
0x00, 0x00, 0x82, 0x01, 0x10, 0x00, 0x00, 0x8E, 0x01, 0x18, 0x00, 0x00,
0x90, 0x7F, 0x0C, 0x00, 0x00, 0xB0, 0x00, 0x04, 0x00, 0x00, 0xA0, 0x00,
0x02, 0x00, 0x00, 0xE0, 0x00, 0x02, 0x00, 0x00, 0xC0, 0x00, 0x02, 0x00,
0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x80,
0x00, 0x04, 0x00, 0x00, 0x80, 0x00, 0x0C, 0x00, 0x00, 0xC0, 0x00, 0x18,
0x00, 0x00, 0x60, 0x00, 0xE0, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
)

local sunny_width = 40
local sunny_height = 40
local sunny_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x18, 0x04, 0x00, 0x00, 0x60, 0x18,
0x06, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00,
0x80, 0x80, 0x81, 0x81, 0x01, 0x00, 0x43, 0x00, 0xC2, 0x00, 0x00, 0x2C,
0x00, 0x34, 0x00, 0x00, 0x10, 0x00, 0x0C, 0x00, 0x00, 0x10, 0x00, 0x08,
0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x80,
0x0B, 0x00, 0xD0, 0x01, 0x00, 0x08, 0x00, 0x10, 0x00, 0x00, 0x08, 0x00,
0x10, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00,
0x00, 0x38, 0x00, 0x1C, 0x00, 0x00, 0x66, 0x00, 0x66, 0x00, 0x80, 0xC3,
0x00, 0xC3, 0x01, 0x80, 0x80, 0xE7, 0x01, 0x01, 0x00, 0x40, 0x3C, 0x02,
0x00, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00, 0x20, 0x18, 0x06, 0x00, 0x00,
0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
)

local rain_width = 40
local rain_height = 40
local rain_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x01, 0x00, 0x00, 0x00,
0x1C, 0x07, 0x00, 0x00, 0x00, 0x06, 0xEC, 0x03, 0x00, 0x00, 0x03, 0x18,
0x04, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00,
0x80, 0x00, 0x00, 0x38, 0x00, 0xC0, 0x00, 0x00, 0xC0, 0x00, 0x60, 0x00,
0x00, 0x80, 0x00, 0x30, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x80,
0x01, 0x10, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x00, 0x06, 0x10,
0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00,
0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x06, 0xC0, 0x00, 0x00, 0x00, 0x03,
0x80, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x08, 0x0C, 0x00, 0x00, 0x38, 0x1C, 0x1C, 0x00, 0x00, 0x28, 0x2C, 0x14,
0x00, 0x00, 0x48, 0x28, 0x24, 0x00, 0x00, 0x78, 0x38, 0x3C, 0x00, 0x00,
0x00, 0x83, 0x01, 0x00, 0x00, 0x00, 0x87, 0x03, 0x00, 0x00, 0x00, 0x85,
0x06, 0x00, 0x00, 0x00, 0x8D, 0x05, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
)

local snow_width = 40
local snow_height = 40
local snow_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x03, 0x00, 0x00, 0x00,
0x0C, 0x8C, 0x01, 0x00, 0x00, 0x06, 0xF8, 0x07, 0x00, 0x00, 0x02, 0x10,
0x08, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00,
0x00, 0x01, 0x00, 0xF0, 0x00, 0xC0, 0x01, 0x00, 0x80, 0x01, 0x40, 0x00,
0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x00,
0x03, 0x10, 0x00, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x10,
0x00, 0x00, 0x00, 0x08, 0x30, 0x00, 0x00, 0x00, 0x08, 0x20, 0x00, 0x00,
0x00, 0x0C, 0x40, 0x00, 0x00, 0x00, 0x04, 0x80, 0x01, 0x00, 0x00, 0x03,
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
0x00, 0x20, 0x00, 0x00, 0x0F, 0x08, 0xF0, 0x00, 0x00, 0x1F, 0x6E, 0xF8,
0x00, 0x00, 0x0F, 0x3C, 0x70, 0x00, 0x00, 0x0F, 0x7F, 0xF0, 0x00, 0x00,
0x04, 0x3C, 0x20, 0x00, 0x00, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
)

local over_width = 40
local over_height = 40
local over_bits = string.char(
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0,
0x0F, 0x00, 0x00, 0x00, 0x70, 0x18, 0x00, 0x00, 0xE0, 0x1F, 0x60, 0x00,
0x00, 0xF0, 0xFF, 0x7F, 0x00, 0x00, 0x18, 0x00, 0xC0, 0x00, 0x00, 0x08,
0x00, 0x80, 0x00, 0x00, 0xFE, 0xFF, 0xFF, 0x00, 0x80, 0x01, 0x00, 0x80,
0x01, 0x80, 0x00, 0x00, 0x00, 0x02, 0x80, 0xFF, 0xFF, 0xFF, 0x07, 0xC0,
0x00, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x00, 0x0C, 0xF0, 0xFF, 0xFF,
0xFF, 0x0F, 0x10, 0x00, 0x00, 0x00, 0x0C, 0x10, 0x00, 0x00, 0x00, 0x04,
0xF0, 0xFF, 0xFF, 0xFF, 0x07, 0x20, 0x00, 0x00, 0x00, 0x02, 0x60, 0x00,
0x00, 0x80, 0x01, 0x80, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
)


function init_OLED(sda,scl)
     sla = 0x3c
     i2c.setup(0, sda, scl, i2c.SLOW)
     disp=u8g.ssd1306_128x64_i2c(sla)
     disp:setFont(u8g.font_6x10)
     disp:setFontPosTop()
end

function print_OLED()
   disp:firstPage()
   repeat
        if Weather == "" and suer=="" then
            disp:setColorIndex(1)
            disp:drawFrame(0,0,128,64)
            disp:setFont(u8g.font_10x20)
            disp:drawStr(45,22,"WIFI")
            disp:setFont(u8g.font_6x10)
            disp:drawStr(10,40,"Weather Station Is")
            disp:setFont(u8g.font_10x20)
            disp:drawStr(25,60,"Starting")
       else
       disp:setColorIndex(1)
       disp:setFont(u8g.font_6x10)
       disp:drawBox(0,0,128,14)
       disp:setColorIndex(0)
       disp:drawStr(40,10,  string.upper(cit))
       disp:setColorIndex(1)
       disp:drawFrame(0,15,128,49)
       disp:setFont(u8g.font_10x20)
       unixTime = rtctime.get()
       tm=rtctime.epoch2cal(unixTime + TIMEZONE*3600)
       disp:drawStr(45, 35, string.format("%02d:%02d:%02d", tm["hour"], tm["min"], tm["sec"]))
       disp:setFont(u8g.font_6x10)
       disp:drawStr(51, 56, DAYS[tm["wday"]])
       disp:drawStr(51, 46, string.format("%02d-%02d-%02d", tm["year"], tm["mon"], tm["day"]))
       if string.find(Weather,"Cloudy") ~= nil then
       disp:drawXBM(0,15, cloudy_width, cloudy_height, cloudy_bits)
       elseif string.find(Weather,"Rain") ~= nil then
       disp:drawXBM(0,15, rain_width, rain_height, rain_bits)
       elseif string.find(Weather,"Snow") ~= nil then
       disp:drawXBM(0,15, snow_width, snow_height, snow_bits)
       elseif string.find(Weather,"Overcast") ~= nil then
       disp:drawXBM(0,15, over_width, over_height, over_bits)
       elseif string.find(Weather,"Sun") ~= nil then
       disp:drawXBM(0,15, sunny_width, sunny_height, sunny_bits)
       end
       disp:drawStr(10,56, Temperature.."'C")
       end
   until disp:nextPage() == false
end

init_OLED(sda,scl)
tmr.alarm(2, 1000, 1, function()
    print_OLED()
end)

注意:大家在将 OLED.lua下载到 ESP8266 中时,可能会遇到下载错误,显示存储空间不足,可以在硬件复位之后首先下载这个文件,不影响使用

四:效果图

esp8266学习笔记:OLED天气气象站+网络授时_第4张图片
esp8266学习笔记:OLED天气气象站+网络授时_第5张图片
固件及代码链接:https://download.csdn.net/download/weixin_42573320/11701731

你可能感兴趣的:(nodemcu)