<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

ESP8266簡易WIFI天氣時鐘

碼農愛學習 ? 來源:碼農愛學習 ? 作者:碼農愛學習 ? 2022-06-06 09:31 ? 次閱讀

本篇介紹了如何使用ESP8266,通過WIFI連網獲取網絡天氣和網絡時間,然后借助U8g2庫,在OLED上顯示當前時間和天氣信息。

1 HTTP獲取網絡天氣

連網獲取網絡天氣,一般需要通過http的方式,從天氣信息提供商的網絡地址獲取天氣信息。

1.1 注冊開發者key

這里以心知天氣為例,需要先注冊一個開發者賬號,然后獲取自己的私鑰,也就是等下要用到的key。

pYYBAGKczR2AP8pFAADHRuQ2xoI534.png

然后可以先在瀏覽器中輸入如下鏈接,注意要將自己的key替換進去,然后就可以測試一下天氣信息的獲取情況。

https://api.seniverse.com/v3/weather/now.json?key=替換為你的私鑰&location=HangZhou&language=en&unit=c

如下即為獲取的天氣信息,是json格式的:

pYYBAGKczSqAEsxBAAD9z39vn7o109.png

1.2 http請求基本原理

上面先通過瀏覽器的方式獲取到了天氣信息,而ESP8266沒有瀏覽器功能,需要編寫代碼實現http數據請求。

在編寫代碼之前,需要先了解一下基礎的http請求原理。

url全稱是資源描述符,一個url地址,用于描述一個網絡上的資源,而http中的get、post、put、delete就對于著這個資源的查、改、增、刪4個操作,get一般用于獲取/查詢資源信息。

url的格式: 【協議】://【主機名(或者叫域名)】【:端口號(可選)】/【文件路徑】/【文件名】

例如:https://api.seniverse.com/v3/weather/now.json?key=替換為你的私鑰&location=HangZhou&language=en&unit=c

協議:https

域名:api.seniverse.com

客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求數據四個部分組成,下圖給出了請求報文的一般格式。

poYBAGKczTGAA3FvAAA8OcVsn7A182.png

服務器HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。

pYYBAGKczTeAcHSeAADSG00i2ao868.png

根據http協議,可以編寫ESP8266進行http請求的代碼:

const char* host = "api.seniverse.com";     // 將要連接的服務器地址  
const int httpPort = 80;                    // 將要連接的服務器端口      
 
// 心知天氣HTTP請求所需信息
String reqUserKey = "xxxxxxxxxxxxxxxxx";   // 私鑰
String reqLocation = "HangZhou";           // 城市
String reqUnit = "c";                      // 攝氏/華氏
 
// 建立心知天氣API當前天氣請求資源地址
String reqRes = "/v3/weather/now.json?key=" + reqUserKey +
    + "&location=" + reqLocation + 
    "&language=en&unit=" +reqUnit;

// 建立http請求信息
// 請求方法(GET)+空格+URL+空格+協議(HTTP/1.1)+回車+換行+
// 頭部字段(Host)+冒號+值(服務器地址)+回車+換行+
// 頭部字段(Connection)+冒號+值(close)+回車+換行+回車+換行
String httpRequest = String("GET ") + reqRes + " HTTP/1.1\r\n" + 
    "Host: " + host + "\r\n" + 
    "Connection: close\r\n\r\n";

WiFiClient client;
// 嘗試連接服務器
if (client.connect(host, 80))
{
    // 向服務器發送http請求信息
    client.print(httpRequest);
    Serial.println("Sending request: ");
    Serial.println(httpRequest);  

    // 獲取并顯示服務器響應狀態行 
    String status_response = client.readStringUntil('\n');
    Serial.print("status_response: ");
    Serial.println(status_response);

    // 使用find跳過HTTP響應頭
    if (client.find("\r\n\r\n")) 
    {
        Serial.println("Found Header End. Start Parsing.");
    }

    // 利用ArduinoJson庫解析心知天氣響應信息
    parseInfo(client); 
} 

1.3 json數據解析

http請求獲取到的天氣數據是json格式的(關于json的介紹可參考:),需要對數據進行解析,獲取到具體的天氣和溫度等數據。

可以將獲取的json原始數據打印出來,方便確認程序是否獲取到的天氣數據。

具體代碼如下:

void parseInfo(WiFiClient client)
{
  const size_t capacity = JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(1) + 2 * JSON_OBJECT_SIZE(3) + JSON_OBJECT_SIZE(6) + 230;
  DynamicJsonDocument doc(capacity);
  deserializeJson(doc, client);
  Serial.println(doc.as());

  JsonObject result0 = doc["results"][0];
  JsonObject result0_now = result0["now"];

  // 通過串口監視器顯示以上信息
  g_strWeather = result0_now["text"].as();// "Sunny"
  g_iCode = result0_now["code"].as();// "0"
  g_iTemperature = result0_now["temperature"].as();// "32"
  g_strUpdateTime = result0["last_update"].as();// "2020-06-02T14:40:00+08:00"

  Serial.println(F("======Weahter Now======="));
  Serial.print(F("Weather Now: "));
  Serial.print(g_strWeather);
  Serial.print(F(" -> "));
  Serial.println(g_iCode);
  Serial.print(F("Temperature: "));
  Serial.println(g_iTemperature);
  Serial.print(F("Last Update: "));
  Serial.println(g_strUpdateTime);
  Serial.println(F("========================"));
}

原始json格式的天氣數據和解析后的天氣和溫度數據如下:

poYBAGKczT-AJANtAAEDvbsdX74343.png

天氣現象代碼對照表

解析到的天氣數據,除了英文形式的天氣信息(text),還有一個對應的天氣碼(code),如上圖的Cloudy對應的天氣碼是4。通過天氣碼,也可以轉換為天氣。天氣碼的對照表可參考心知天氣文檔:https://docs.seniverse.com/api/start/code.html

poYBAGKczUiADexiAABqezKK6UI281.png

簡化起見,這里只使用常用的4種天氣。

代碼 中文 英文
0 晴(國內城市白天晴) Sunny
4 多云 Cloudy
9 Overcast
13 小雨 Light Rain0

2 NTP網絡時間

NTP(Network Time Protocol) 是網絡時間協議,它是用來同步網絡中各個計算機時間的協議。

ESP8266可以連網,那就也可以通過獲取網絡時間來得到當前的時間:

time_t getNtpTime()
{
    IPAddress ntpServerIP; // NTP服務器的地址
 
    while(Udp.parsePacket() > 0); // 丟棄以前接收的任何數據包
    Serial.println("Transmit NTP Request");
    // 從池中獲取隨機服務器
    WiFi.hostByName(ntpServerName, ntpServerIP);
    Serial.print(ntpServerName);
    Serial.print(": ");
    Serial.println(ntpServerIP);
    sendNTPpacket(ntpServerIP);
    uint32_t beginWait = millis();
    while (millis() - beginWait < 1500)
    {
        int size = Udp.parsePacket();
        if (size >= NTP_PACKET_SIZE)
        {
            Serial.println("Receive NTP Response");
            isNTPConnected = true;
            Udp.read(packetBuffer, NTP_PACKET_SIZE); // 將數據包讀取到緩沖區
            unsigned long secsSince1900;
            // 將從位置40開始的四個字節轉換為長整型,只取前32位整數部分
            secsSince1900 = (unsigned long)packetBuffer[40] << 24;
            secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
            secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
            secsSince1900 |= (unsigned long)packetBuffer[43];
            Serial.println(secsSince1900);
            Serial.println(secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR);
            return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
        }
    }
    Serial.println("No NTP Response :-("); //無NTP響應
    isNTPConnected = false;
    return 0; //如果未得到時間則返回0
}

3 OLED顯示頁面設計

獲取到天氣信息和時間后,需要將這些信息顯示出來。

這里使用0.96寸OLED顯示屏來顯示,借助U8g2庫,顯示文字與天氣圖標(U8g2庫的使用,可參考:)。

具體的顯示代碼如下:

void testShowTimeAndWeather(rtc_time_t &now_time, weather_info_t &weather_info)
{
  u8g2.clearBuffer();
  int tm_year = now_time.tm_year;
  int tm_month = now_time.tm_mon;
  int tm_day = now_time.tm_mday;
  int tm_hour = now_time.tm_hour;
  int tm_minute = now_time.tm_min;
  int tm_sec = now_time.tm_sec;
  int tm_week = now_time.tm_week;
  
  //時分
  char str_big_time[] = "";
  my_strcat(str_big_time, tm_hour);
  strcat(str_big_time,":");
  my_strcat(str_big_time, tm_minute);
  u8g2.setFont(u8g2_font_logisoso24_tf); 
  u8g2.drawStr(0, 30, str_big_time);

  //秒
  char str_small_sec[] = "";
  my_strcat(str_small_sec, tm_sec);
  u8g2.setFont(u8g2_font_wqy14_t_gb2312);
  u8g2.drawStr(73, 30, str_small_sec);

  //日期
  char str_date[] = "";
  char str_temp[6];
  itoa(tm_year,str_temp,10);
  strcat(str_date,str_temp);
  strcat(str_date,"-");
  my_strcat(str_date, tm_month);
  strcat(str_date,"-");
  my_strcat(str_date, tm_day);
  u8g2.drawStr(0, 47, str_date);
  
  u8g2.setCursor(0, 63);
  u8g2.print("星期");
  switch (tm_week)
  {
    case 1: u8g2.print("日"); break;
    case 2: u8g2.print("一"); break;
    case 3: u8g2.print("二"); break;
    case 4: u8g2.print("三"); break;
    case 5: u8g2.print("四"); break;
    case 6: u8g2.print("五"); break;
    case 7: u8g2.print("六"); break;
    default: break;
  }
  u8g2.setCursor(60, 63);
  u8g2.print("杭州");

  //分割線
  u8g2.drawLine(90, 0, 90, 63);
  
  //天氣
  if (weather_info.iconIdx<0 || weather_info.iconIdx>3) //沒有對應的天氣圖標
  {
    Serial.print("no icon for weather: ");
    Serial.println(weather_info.weather);
  }
  else
  {
    u8g2.setFont(u8g2_font_open_iconic_weather_4x_t );
    u8g2.drawStr(96, 34, icon_index[weather_info.iconIdx]);
  }
  char temperature_tmp[25];
  itoa(weather_info.temp, temperature_tmp, 10);
  strcat(temperature_tmp,"℃");
  u8g2.setFont(u8g2_font_wqy16_t_gb2312);
  u8g2.setCursor(96, 55);
  u8g2.print(temperature_tmp);
  
  u8g2.sendBuffer();
}

4 最終效果

pYYBAGKczVKAJskVAAKYT8UVGWI251.png

5 總結

本篇介紹了http獲取網絡天氣的基本原理,并通過實踐,使用ESP8266連網獲取網絡天氣和網絡時間,借助U8g2庫,在OLED上顯示當前時間和天氣信息。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    4984

    文章

    18300

    瀏覽量

    288767
  • WIFI
    +關注

    關注

    81

    文章

    5163

    瀏覽量

    199495
  • Arduino
    +關注

    關注

    184

    文章

    6428

    瀏覽量

    184882
  • ESP8266
    +關注

    關注

    50

    文章

    947

    瀏覽量

    44004
收藏 人收藏

    評論

    相關推薦

    esp8266如何破解wifi密碼及詳細步驟

    本文首先介紹了在知道wifi賬號及密碼的情況下ESP8266連接wifi的步驟,其次介紹了esp8266破解wifi密碼的詳細步驟,最后介紹
    的頭像 發表于 05-24 08:57 ?8.8w次閱讀
    <b class='flag-5'>esp8266</b>如何破解<b class='flag-5'>wifi</b>密碼及詳細步驟

    stm32是如何控制ESP8266

    stm32控制ESP8266獲取指定城市天氣并且在led屏幕上顯示使用:在ATK_ESP8266文件夾下面的wifista.c第14行修改wifi的ssid號和密碼。編譯燒錄后即可使用
    發表于 01-12 06:39

    ESP8266_wifi模塊說明書

    ESP8266_WiFi Specifications _ChineseESP8266 wifi模塊說明書,中文版
    發表于 12-29 14:16 ?195次下載

    如何燒寫F103-霸道/指南者上的 ESP8266 WIFI的固件

    1-把板子上的USB轉串口的RXD、TXD與A9、A10連接的調帽拔掉,把ESP8266 WIFI 的 URX、RTX與 B10、B11連接的調帽拔掉 2-把USB轉串口的RXD與ESP8266
    發表于 11-24 17:46 ?18次下載
    如何燒寫F103-霸道/指南者上的 <b class='flag-5'>ESP8266</b> <b class='flag-5'>WIFI</b>的固件

    esp8266串口wifi實例

    ESP8266串口WiFi擴展板是深圳四博智聯科技有限公司開發的一款基于樂鑫ESP8266的超低功耗的UART-WiFi模塊,本文介紹了ESP826
    發表于 12-08 13:34 ?1.8w次閱讀

    esp8266中文資料匯總(esp8266引腳圖_與單片機連接_串口wifi實例)

    本文首先介紹了esp8266引腳圖功能與esp8266特性,其次介紹了 單片機與ESP8266串口連接及最小系統連接與程序分享,最后介紹了esp8266串口
    發表于 05-24 08:36 ?22.2w次閱讀
    <b class='flag-5'>esp8266</b>中文資料匯總(<b class='flag-5'>esp8266</b>引腳圖_與單片機連接_串口<b class='flag-5'>wifi</b>實例)

    如何將ESP8266連接到WiFi

    在之前的ESP8266項目中,我簡要介紹了ESP8266 WiFi模塊,如何開始使用ESP8266和Arduino,ESP8266
    的頭像 發表于 07-29 11:32 ?8.5w次閱讀
    如何將<b class='flag-5'>ESP8266</b>連接到<b class='flag-5'>WiFi</b>

    怎樣使用ESP8266 Flasher和Programmer燒寫ESP8266 AT固件

    選擇要連接的COM端口ESP8266 Flasher和Programmer + ESP8266 Wifi串行收發器模塊。將BAUDRATE設置為115200。
    的頭像 發表于 11-18 17:58 ?2w次閱讀

    ESP8266 WiFi模塊獲取網絡天氣適配戰艦開發板的使用實例

    本文檔的主要內容詳細介紹的是ESP8266 WiFi模塊獲取網絡天氣適配戰艦開發板的使用實例。
    發表于 06-12 16:36 ?38次下載
    <b class='flag-5'>ESP8266</b> <b class='flag-5'>WiFi</b>模塊獲取網絡<b class='flag-5'>天氣</b>適配戰艦開發板的使用實例

    ESP8266 wifi模塊開發匯總

    ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ESP8266 wifi模塊開發匯總?ESP8266 wifi模塊開發匯總本文檔主要介紹開發者在
    發表于 11-05 19:21 ?185次下載
    <b class='flag-5'>ESP8266</b> <b class='flag-5'>wifi</b>模塊開發匯總

    基于STM32的ESP8266天氣時鐘(2)--------MCU獲取天氣數據

    stm32通過ESP8266模塊獲取天氣,時間
    發表于 11-18 18:36 ?38次下載
    基于STM32的<b class='flag-5'>ESP8266</b><b class='flag-5'>天氣</b><b class='flag-5'>時鐘</b>(2)--------MCU獲取<b class='flag-5'>天氣</b>數據

    ESP8266 WIFI模擬GPS時鐘信號

    電子發燒友網站提供《ESP8266 WIFI模擬GPS時鐘信號.zip》資料免費下載
    發表于 08-04 14:33 ?7次下載
    <b class='flag-5'>ESP8266</b> <b class='flag-5'>WIFI</b>模擬GPS<b class='flag-5'>時鐘</b>信號

    基于ESP8266的NTP時鐘

    電子發燒友網站提供《基于ESP8266的NTP時鐘.zip》資料免費下載
    發表于 11-11 10:06 ?3次下載
    基于<b class='flag-5'>ESP8266</b>的NTP<b class='flag-5'>時鐘</b>

    基于ESP8266WiFi

    該項目使用 NodeMcu esp8266 和 Blynk 由您的智能手機控制的最簡單的 wifi 汽車。
    發表于 12-08 10:15 ?7次下載

    ESP8266ESP32上的WiFi Webradio

    電子發燒友網站提供《ESP8266ESP32上的WiFi Webradio.zip》資料免費下載
    發表于 06-13 11:38 ?0次下載
    <b class='flag-5'>ESP8266</b>或<b class='flag-5'>ESP</b>32上的<b class='flag-5'>WiFi</b> Webradio
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>