電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 30|回復(fù): 0
收起左側(cè)

單片機(jī)通過WIFI模塊(ESP8266)獲取網(wǎng)絡(luò)時間與天氣預(yù)報

[復(fù)制鏈接]

451

主題

451

帖子

2461

積分

三級會員

Rank: 3Rank: 3

積分
2461
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2022-10-24 08:10:00 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式

前幾天發(fā)布了開源4.3寸觸摸屏的文章,里面有WIFI獲取時間和天氣預(yù)報相關(guān)的功能,今天就來介紹一下這個功能是怎樣實現(xiàn)的。
1.底層驅(qū)動首先,硬件上,單片機(jī)通過串口AT指令訪問WIFI模塊(ESP8266)。具體AT指令怎樣寫,可以參考之前的文章《單片機(jī)裸機(jī)環(huán)境下編寫AT指令程序》。上電后,先配置WIFI模塊的工作模式等,用到的AT指令如下:1. 關(guān)閉回顯    ATE0                         2. 設(shè)置為STA模式    AT+CWMODE_DEF=1 3. 設(shè)置WIFI名稱和密碼    AT+CWJAP_DEF=”SSID”,”Password” 4. 開啟DHCP    AT+CWDHCP_DEF=1,1 5. 設(shè)置為單連接模式    AT+CIPMUX=0           6. 設(shè)置為透傳模式    AT+CIPMODE=1           
2.獲取網(wǎng)絡(luò)時間獲取網(wǎng)絡(luò)時間的方式有兩種,對于較新版本的固件,可以直接通過AT指令來獲取。(可以通過AT+GMR指令來查詢固件的版本。)AT+CIPSNTPTIME?對于較老版本的固件,不支持該AT指令,只能通過自己連接網(wǎng)絡(luò)服務(wù)器來獲取當(dāng)前時間。具體需要的AT指令如下:1.建立TCP鏈接    AT+CIPSTART="TCP","www.beijing-time.org",802.打開傳透模式    AT+CIPSEND3.收到‘>’符號后,隨便發(fā)送個數(shù)據(jù)4.等待接收數(shù)據(jù)接收的數(shù)據(jù)可以先用網(wǎng)絡(luò)調(diào)試助手來測試,如下,可以看到,數(shù)據(jù)中包含了當(dāng)前的日期和時間信息,我們可以先找到字符串中“Data”的位置,再解析后面的數(shù)據(jù)。數(shù)據(jù)格式固定,直接按照字符位置解析就行。需要注意的是,獲取的這個時間是格林威治時間,與北京時間相差8個小時。當(dāng)然,也可以通過連接其它NTP時間服務(wù)器來獲取時間,步驟是類似的。


3.獲取天氣預(yù)報天氣的獲取就要比時間稍復(fù)雜一些,網(wǎng)上有很多可以提供天氣預(yù)報的服務(wù)器,有些可以免費使用,一般都需要注冊一個賬號,這里以“心知天氣”為例進(jìn)行介紹。步驟如下:1.注冊賬號。在該網(wǎng)站注冊一個賬號:https://www.seniverse.com/。注冊之后就可以通過其開放的API來獲取天氣預(yù)報。有免費版和付費版,區(qū)別在于訪問頻次和獲取的天氣信息內(nèi)容不同。如下:

2.查看私鑰。在控制臺查看賬號的私鑰,這個在程序中要用。

3.API。有了這個私鑰,我們就可以通過API來獲取天氣預(yù)報了,相關(guān)的API說明可以在這里查詢:
https://seniverse.yuque.com/books/share/f4f9bf1a-d3d9-4a68-8996-950f8c88400e/sl6gvt#d29hl
先用網(wǎng)絡(luò)調(diào)試助手測試一下:

可以看到,通過TCP連接服務(wù)器后,發(fā)送GET請求就可以收到天氣預(yù)報數(shù)據(jù),接下來就是解析數(shù)據(jù)了。4.解析數(shù)據(jù)。接收的數(shù)據(jù)是JSON格式的字符串,在單片機(jī)中我們可以移植cJSON來進(jìn)行解析。cJSON是一個開源的C語音解析庫,只有cJSON.c、cJSON.h兩個文件,直接添加到工程中就可以使用相關(guān)函數(shù)。程序如下:
  • void Weather_JSON( ){      char *data;    cJSON *root;    cJSON *results;    cJSON *last_update;    cJSON *loc_json, *daily_json;    cJSON *forecast_json;    char *loc_tmp, *weather_tmp;    int i = 0;
        data = (char*)(Uart1.RxBuf);//接受到的數(shù)據(jù)    root = cJSON_Parse(data);    if(root)    {        //printf("JSON格式正確:
    %s
    ",cJSON_Print(root));    //輸出json字符串        results = cJSON_GetObjectItem(root, "results");        results = cJSON_GetArrayItem(results,0);        if(results)        {            loc_json = cJSON_GetObjectItem(results, "location");   //得到location鍵對應(yīng)的值,是一個對象
                loc_tmp = cJSON_GetObjectItem(loc_json, "id") -> valuestring;            //printf("城市ID:%s
    ",loc_tmp);            loc_tmp = cJSON_GetObjectItem(loc_json, "name") -> valuestring;            memset(loc_str,0,20);            memcpy(loc_str,loc_tmp,strlen(loc_tmp));                      loc_tmp = cJSON_GetObjectItem(loc_json, "timezone") -> valuestring;            //printf("城市時區(qū):%s
    ",loc_tmp);
                daily_json = cJSON_GetObjectItem(results, "daily");            if(daily_json)            {                Weather_Dat[0].Flag = 1;                for(i = 0; i 3; i++)                {                    forecast_json = cJSON_GetArrayItem(daily_json, i);                    //weather_tmp = cJSON_GetObjectItem(forecast_json, "date") -> valuestring;//日期
                        weather_tmp = cJSON_GetObjectItem(forecast_json, "code_day") -> valuestring;//白天天氣代碼                    Weather_Dat.Weathcode = atoi(weather_tmp);
                        //weather_tmp = cJSON_GetObjectItem(forecast_json, "code_night") -> valuestring;//晚上天氣代碼
                        weather_tmp = cJSON_GetObjectItem(forecast_json, "high") -> valuestring;//最高溫度                    memset(Weather_Dat.HighT,0,4);                    memcpy(Weather_Dat.HighT,weather_tmp,strlen(weather_tmp));
                                          weather_tmp = cJSON_GetObjectItem(forecast_json, "low") -> valuestring;//最低溫度                    memset(Weather_Dat.LowT,0,4);                    memcpy(Weather_Dat.LowT,weather_tmp,strlen(weather_tmp));                                      weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_direction") -> valuestring;//風(fēng)向                    memset(Weather_Dat.Wind_Dir,0,10);                    memcpy(Weather_Dat.Wind_Dir,weather_tmp,strlen(weather_tmp));                                      weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_scale") -> valuestring;//風(fēng)力                    memset(Weather_Dat.WindScale,0,4);                    memcpy(Weather_Dat.WindScale,weather_tmp,strlen(weather_tmp));                                      weather_tmp = cJSON_GetObjectItem(forecast_json, "humidity") -> valuestring;//濕度                    memset(Weather_Dat.Humi,0,4);                    memcpy(Weather_Dat.Humi,weather_tmp,strlen(weather_tmp));                }            }            else            {                //printf("daily json格式錯誤\r
    ");                Weather_Dat[0].Flag = 0;            }
            }        else        {            Weather_Dat[0].Flag = 0;            //printf("results格式錯誤:%s\r
    ", cJSON_GetErrorPtr());        }    }    else    {        Weather_Dat[0].Flag = 0;        //printf("JSON格式錯誤\r
    ");    }    cJSON_Delete(root);  }解析后,將有用數(shù)據(jù)轉(zhuǎn)換為自己想要的格式存儲在變量中。需要注意的是,cJSON可能占用較大的堆棧,因此堆棧需要設(shè)大一些。
    總結(jié)一下,獲取天氣預(yù)報的步驟如下:
    1.注冊賬號。
    2.獲取私鑰。
    3.連接服務(wù)器。
        AT+CIPSTART="TCP”,” api.seniverse.com”,80
    4..打開傳透模式。
        AT+CIPSEND
    5..收到‘>’符號后,發(fā)送GET請求
    GET https://api.seniverse.com/v3/weather/daily.json?key=your_key&location=ip&language=zh-Hans&unit=c&start=0&days=3
    6.等待接收數(shù)據(jù),并解析。

    以上就是單片機(jī)通過AT指令訪問WIFI模塊獲取網(wǎng)絡(luò)時間和天氣預(yù)報的方法,需要注意的是上述所有指令后面別忘了加回車換行符。
    完整的程序可以看這里:
    程序

    推薦閱讀:
    Keil調(diào)試時設(shè)置斷點的高級用法
    幾種常用的產(chǎn)生負(fù)電源的方法STM32CubeMX系列教程
    了解一款新的單片機(jī)
       歡迎關(guān)注公眾號"嵌入式技術(shù)開發(fā)",大家可以后臺給我留言溝通交流。如果覺得該公眾號對你有所幫助,也歡迎推薦分享給其他人。
  • 回復(fù)

    使用道具 舉報

    發(fā)表回復(fù)

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則

    關(guān)閉

    站長推薦上一條 /1 下一條


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表