前幾天發(fā)布了開源4.3寸觸摸屏的文章,里面有WIFI獲取時間和天氣預報相關的功能,今天就來介紹一下這個功能是怎樣實現(xiàn)的。 
	1.底層驅(qū)動
	首先,硬件上,單片機通過串口AT指令訪問WIFI模塊(ESP8266)。具體AT指令怎樣寫,可以參考之前的文章《單片機裸機環(huán)境下編寫AT指令程序》。上電后,先配置WIFI模塊的工作模式等,用到的AT指令如下:
1. 關閉回顯 
	ATE0    
2. 設置為STA模式 
	AT+CWMODE_DEF=1
3. 設置WIFI名稱和密碼 
	AT+CWJAP_DEF=”SSID”,”Password”
4. 開啟DHCP 
	AT+CWDHCP_DEF=1,1
5. 設置為單連接模式 
	AT+CIPMUX=0 
6.設置為透傳模式 
	AT+CIPMODE=1  
	2.獲取網(wǎng)絡時間 獲取網(wǎng)絡時間的方式有兩種,對于較新版本的固件,可以直接通過AT指令來獲取。(可以通過AT+GMR指令來查詢固件的版本。) AT+CIPSNTPTIME? 對于較老版本的固件,不支持該AT指令,只能通過自己連接網(wǎng)絡服務器來獲取當前時間。具體需要的AT指令如下:
1.建立TCP鏈接 
	AT+CIPSTART="TCP","www.beijing-time.org",80
2.打開傳透模式 
	AT+CIPSEND
3.收到‘>’符號后,隨便發(fā)送個數(shù)據(jù)
4.等待接收數(shù)據(jù)
	接收的數(shù)據(jù)可以先用網(wǎng)絡調(diào)試助手來測試,如下,可以看到,數(shù)據(jù)中包含了當前的日期和時間信息,我們可以先找到字符串中“Data”的位置,再解析后面的數(shù)據(jù)。數(shù)據(jù)格式固定,直接按照字符位置解析就行。
	需要注意的是,獲取的這個時間是格林威治時間,與北京時間相差8個小時。
	當然,也可以通過連接其它NTP時間服務器來獲取時間,步驟是類似的。
	3.獲取天氣預報 天氣的獲取就要比時間稍復雜一些,網(wǎng)上有很多可以提供天氣預報的服務器,有些可以免費使用,一般都需要注冊一個賬號,這里以“心知天氣”為例進行介紹。步驟如下:
1.注冊賬號。
	在該網(wǎng)站注冊一個賬號:https://www.seniverse.com/。注冊之后就可以通過其開放的API來獲取天氣預報。有免費版和付費版,區(qū)別在于訪問頻次和獲取的天氣信息內(nèi)容不同。如下:
2.查看私鑰。
	在控制臺查看賬號的私鑰,這個在程序中要用。
	3.API。
	有了這個私鑰,我們就可以通過API來獲取天氣預報了,相關的API說明可以在這里查詢:
https://seniverse.yuque.com/books/share/f4f9bf1a-d3d9-4a68-8996-950f8c88400e/sl6gvt#d29hl
先用網(wǎng)絡調(diào)試助手測試一下:
	
	可以看到,通過TCP連接服務器后,發(fā)送GET請求就可以收到天氣預報數(shù)據(jù),接下來就是解析數(shù)據(jù)了。
4.解析數(shù)據(jù)。
	接收的數(shù)據(jù)是JSON格式的字符串,在單片機中我們可以移植cJSON來進行解析。cJSON是一個開源的C語音解析庫,只有cJSON.c、cJSON.h兩個文件,直接添加到工程中就可以使用相關函數(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鍵對應的值,是一個對象
            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[i].Weathcode = atoi(weather_tmp);
                    //weather_tmp = cJSON_GetObjectItem(forecast_json, "code_night") -> valuestring;//晚上天氣代碼
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "high") -> valuestring;//最高溫度
                    memset(Weather_Dat[i].HighT,0,4);
                    memcpy(Weather_Dat[i].HighT,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "low") -> valuestring;//最低溫度
                    memset(Weather_Dat[i].LowT,0,4);
                    memcpy(Weather_Dat[i].LowT,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_direction") -> valuestring;//風向
                    memset(Weather_Dat[i].Wind_Dir,0,10);
                    memcpy(Weather_Dat[i].Wind_Dir,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "wind_scale") -> valuestring;//風力
                    memset(Weather_Dat[i].WindScale,0,4);
                    memcpy(Weather_Dat[i].WindScale,weather_tmp,strlen(weather_tmp));
                  
                    weather_tmp = cJSON_GetObjectItem(forecast_json, "humidity") -> valuestring;//濕度
                    memset(Weather_Dat[i].Humi,0,4);
                    memcpy(Weather_Dat[i].Humi,weather_tmp,strlen(weather_tmp));
                }
            }
            else
            {
                //printf("daily json格式錯誤
");
                Weather_Dat[0].Flag = 0;
}
        }
        else
        {
            Weather_Dat[0].Flag = 0;
            //printf("results格式錯誤:%s
", cJSON_GetErrorPtr());
        }
    }
    else
    {
        Weather_Dat[0].Flag = 0;
        //printf("JSON格式錯誤
");
    }
    cJSON_Delete(root);  
}
解析后,將有用數(shù)據(jù)轉(zhuǎn)換為自己想要的格式存儲在變量中。需要注意的是,cJSON可能占用較大的堆棧,因此堆棧需要設大一些。
總結(jié)一下,獲取天氣預報的步驟如下:
1.注冊賬號。
2.獲取私鑰。
3.連接服務器。
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ù),并解析。
	以上就是單片機通過AT指令訪問WIFI模塊獲取網(wǎng)絡時間和天氣預報的方法,需要注意的是上述所有指令后面別忘了加回車換行符。 
	審核編輯:劉清
- 
                                單片機
                                +關注
關注
6072文章
45277瀏覽量
661630 - 
                                觸摸屏
                                +關注
關注
42文章
2422瀏覽量
120493 - 
                                wifi模塊
                                +關注
關注
60文章
388瀏覽量
76246 - 
                                ESP8266
                                +關注
關注
51文章
965瀏覽量
48850 
原文標題:單片機通過WIFI模塊(ESP8266)獲取網(wǎng)絡時間與天氣預報
文章出處:【微信號:嵌入式技術(shù)開發(fā),微信公眾號:嵌入式技術(shù)開發(fā)】歡迎添加關注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
怎樣去設計一種基于rt-thread帶有顯示時間和天氣預報功能的桌面小盒子
基于ESP32 WiFi連接天氣預報機的設計方案
【Banana PI Leaf S3開發(fā)板試用體驗】基于Banana PI Leaf S3的天氣預報系統(tǒng)
【國民技術(shù)N32項目移植】5.項目提交-天氣顯示及預報系統(tǒng)介紹以及演示
由MQTT進行的天氣預報ESPWatch 遠程控制本地儀器
基于STM32 ESP8266的WIFI TFT自動校時天氣預報設計
基于SWM32單片機+LVGL的4.3寸觸摸屏設計
ESP8266獲取天氣預報信息,并使用CJSON解析天氣預報數(shù)據(jù)
AWTK 開源串口屏開發(fā)(11) - 天氣預報
    
          
        
        
觸摸屏WIFI獲取時間和天氣預報相關的功能是怎樣實現(xiàn)的
                
 
    
           
            
            
                
            
評論