STM32連接WIFI-ESP8266獲取天氣信息---STA模式運用

1. 小白入門STA模式運用

   前面章節講解了AP模式運用,這節來探索STA模式如何使用。何謂STA模式呢?通俗來講就是我們的WIFI模塊,連接到可用的無線網絡(如手機發射出來的熱點或者家裏路由器的熱點),連接上無線網絡後,相當於模塊也是可以上網了,就跟手機連路由器WIFI上網,這時我們就可以利用模塊去訪問某些服務器進行通信,來獲取我們想要的信息。比如獲取天氣服務器的天氣信息等等。

1.1資源環境:

 ESP8266 WIFI模塊一個

 STM32開發板(本例程採用STM32F103ZET6開發板)

 SD卡一張(沒有也可以,此處用來獲取顯示天氣狀態的圖標)

 可上網的熱點(ssid和密碼)

1.2 ESP82266與開發板引腳連接說明:

ESP82266   開發板引腳

VCC    ------    5V

GND   ------    GND

TXD    ------    PB11

RXD    ------    PB10

RST    ------     PA4(可不接)

IO_0   ------     PA15(可不接)


2. STA子模式的配置說明

 在AP模式章節也講到,每種模式又可以設置爲三種不同子模式進行數據通信,STA模式也不例外。即模塊可以配置爲TCP服務器子模式、TCP客戶端子模式、UDP子模式。下面分別說下配置成這三種模式的必要配置:

TCP服務器的配置:

TCP客戶端的配置:

UDP模式配置:

3. 詳解使用說明

首先我們要配置WIFI模塊連上熱點,這裏我們採取配置爲TCP客戶端子模式,便於後面獲取天氣預報信息:

atk_8266_send_cmd("AT+CWMODE=1","OK",50);	//配置STA模式
atk_8266_send_cmd("AT+RST","OK",20);		//重啓模塊
delay_ms(1000);        
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
//設置無線參數:ssid和密碼
sprintf((char*)p,"AT+CWJAP=\"%s\",\"%s\"",wifista_ssid,wifista_password);
	while(atk_8266_send_cmd(p,"WIFI GOT IP",300));	//連接目標路由器,獲取ip

開發板上設置好要連接的ssid和密碼:

當模塊連接上熱點後,就可以開始建立要訪問的目標服務器的TCP連接了:這裏以訪問心知天氣服務器爲例

心知天氣文檔瞭解入口:https://docs.seniverse.com/api/start/start.html

獲取一次實時天氣信息如下:以獲取廣州天氣信息爲例,這裏涉及到http相關知識和cjson格式數據解析

//心知天氣端口號
#define WEATHER_PORTNUM 	"80"
//心知天氣IP
#define WEATHER_SERVERIP 	"api.seniverse.com"

sprintf((char*)p,"AT+CIPSTART=\"TCP\",\"%s\",%s",WEATHER_SERVERIP,WEATHER_PORTNUM);  //配置心知天氣的ip和端口
res = atk_8266_send_cmd(p,"OK",200);//連接到目標tcp服務器
delay_ms(300);
atk_8266_send_cmd("AT+CIPMODE=1","OK",100);      //設置傳輸模式爲透傳

atk_8266_send_cmd("AT+CIPSEND","OK",100);         //開始透傳
u3_printf("GET https://api.seniverse.com/v3/weather/now.json?key=x3owc7bndhbvi8oq&location=guangzhou&language=zh-Hans&unit=c\n\n");	

當WIFI模塊獲取心知服務器一次實時天氣成功後,會返回對應的cjson格式數據,可以通過串口打印出返回的信息如下:

{"results":[{"location":{"id":"WS0E9D8WN298","name":"騫垮窞","country":"CN","path":"騫垮窞,騫垮窞,騫誇笢,涓浗","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"now":{"text":"澶氫簯","code":"4","temperature":"29"},"last_update":"2020-04-19T13:49:00+08:00"}]}

對應部分的cjson格式數據解析如下:

pSub = cJSON_GetObjectItem(root,"results");
if(pSub != NULL)
{
	arrayItem = cJSON_GetArrayItem(pSub,0);  
	pr = cJSON_Print(arrayItem);  
	pItem = cJSON_Parse(pr);       
	if(pItem != NULL)
	{
   		pSubItem = cJSON_GetObjectItem(pItem,"now");
		if(pSubItem != NULL)
		{
		   pChildItem = cJSON_GetObjectItem(pSubItem,"code");      //獲取氣象代碼
		   if(pChildItem != NULL)
		   {
			   gbkstr = pChildItem->valuestring;
               curwer_buf[0]=str2int((u8 *)gbkstr);
		   }
			pChildItem = cJSON_GetObjectItem(pSubItem,"temperature");     //獲取實時溫度值
			if(pChildItem != NULL)
			{
				gbkstr = pChildItem->valuestring;
				curwer_buf[1] = str2int((u8 *)gbkstr);
			}			
	     }
      }
}

我們還可以繼續獲取今、明、後三天的天氣信息,具體看你的心知服務器的api接口:對應的訪問接口如下

u3_printf("GET https://api.seniverse.com/v3/weather/daily.json?key=x3owc7bndhbvi8oq&location=guangzhou&language=zh-Hans&unit=c&start=0&days=5\n\n");

返回的cjson格式數據如下:

"results":[{"location":{"id":"WS0E9D8WN298","name":"騫垮窞","country":"CN","path":"騫垮窞,騫垮窞,騫誇笢,涓浗","timezone":"Asia/Shanghai","timezone_offset":"+08:00"},"daily":[{"date":"2020-04-19","text_day":"澶氫簯","code_day":"4","text_night":"澶氫簯","code_night":"4","high":"29","low":"22","rainfall":"0.0","precip":"","wind_direction":"鏃犳寔緇鍚?","wind_direction_degree":"0","wind_speed":"16.20","wind_scale":"3","humidity":"78"},{"date":"2020-04-20","text_day":"澶氫簯","code_day":"4","text_night":"澶氫簯","code_night":"4","high":"29","low":"22","rainfall":"0.0","precip":"","wind_direction":"鍗?","wind_direction_degree":"198","wind_speed":"25.20","wind_scale":"4","humidity":"79"},{"date":"2020-04-21","text_day":"涓洦","code_day":"14","text_night":"澶ч洦","code_night":"15","high":"28","low":"20","rainfall":"10.0","precip":"","wind_direction":"鍗?","wind_direction_degree":"179","wind_speed":"25.20","wind_scale":"4","humidity":"89"}],"last_update":"2020-04-19T11:17:53+08:00"}]}

當獲取成功後,就可以在我們的開發板上展示如下的天氣信息:可知當前的風力、風速、和溫度,以及今明後三天的最高溫度和最低溫度。

大家應該也觀察到了,這裏會顯示出對應天氣狀態的小圖標,是根據獲取到氣象代碼,從SD卡里讀取對應氣象代碼的圖片,顯示出來的。

SD卡里面的氣象小圖標如下所示:

具體實現如下:

void Weather_Icon_Show(void)
{
    u8 i=0;
    u8 res;
    u16 temp;
	
    pic_info.totpicnum=pic_get_tnum((u8 *)"0:/wc"); //得到總有效文件數
	pic_info.picfileinfo.lfsize=30*2+1;						//長文件名最大長度 , _MAX_LFN換成30
	pic_info.picfileinfo.lfname=mymalloc(SRAMIN,pic_info.picfileinfo.lfsize);	//爲長文件緩存區分配內存
	pic_info.pname=mymalloc(SRAMIN,pic_info.picfileinfo.lfsize);				//爲帶路徑的文件名分配內存
	pic_info.picindextbl=mymalloc(SRAMIN,2*pic_info.totpicnum);				//申請2*totpicnum個字節的內存,用於存放圖片索引	
	res=f_opendir(&pic_info.picdir,"0:/wc"); //打開目錄
	if(res==FR_OK)
	{
		pic_info.curindex=0;//當前索引爲0
		while(1)//全部查詢一遍
		{
			 temp=pic_info.picdir.index;								//記錄當前index
			 res=f_readdir(&pic_info.picdir,&pic_info.picfileinfo);       		//讀取目錄下的一個文件
			 if(res!=FR_OK||pic_info.picfileinfo.fname[0]==0)break;	//錯誤了/到末尾了,退出		  
			 pic_info.fn=(u8*)(*pic_info.picfileinfo.lfname?pic_info.picfileinfo.lfname:pic_info.picfileinfo.fname);			 
			 res=f_typetell(pic_info.fn);	
			if((res&0XF0)==0X50)//取高四位,看看是不是圖片文件	
			{
				pic_info.picindextbl[pic_info.curindex]=temp;//記錄索引 ,若是分配的內存空間不夠,就會導致索引亂序
				pic_info.curindex++;
			}	    
		} 
	}
	delay_ms(1500);
	piclib_init();										//初始化畫圖	   	   
										
	res=f_opendir(&pic_info.picdir,(const TCHAR*)"0:/wc"); 	//打開目錄
	if(res==FR_OK)  pic_info.picstatus|=(1<<3);
		
	if(pic_info.picstatus&0X08)//打開成功
	{				
			for(i=0;i<4;i++)
			{
				dir_sdi(&pic_info.picdir,pic_info.picindextbl[iconbuf[i]]);			//改變當前目錄索引	 
				f_readdir(&pic_info.picdir,&pic_info.picfileinfo);       		//讀取目錄下的一個文件
				pic_info.fn=(u8*)(*pic_info.picfileinfo.lfname?pic_info.picfileinfo.lfname:pic_info.picfileinfo.fname);			 
				strcpy((char*)pic_info.pname,"0:/wc/");				//複製路徑(目錄)
				strcat((char*)pic_info.pname,(const char*)pic_info.fn);  			//將文件名接在後面
				if(i<=2)	ai_load_picfile(pic_info.pname,105+i*265,320,60,60,1);//顯示圖片   lcddev.width 
				else ai_load_picfile(pic_info.pname,565,90,60,60,1);//顯示圖片   lcddev.width 
			   delay_ms(500);
		 }
		
	}
	
	if(pic_info.picfileinfo.lfname!=NULL ||pic_info.pname!=NULL || pic_info.picindextbl!=NULL)
	{
       myfree(SRAMIN,pic_info.picfileinfo.lfname);	//釋放內存			    
	 myfree(SRAMIN,pic_info.pname);				//釋放內存			    
	 myfree(SRAMIN,pic_info.picindextbl);			//釋放內存		
		
	}
 
	
}

4.總結

 通過對WIFI--ESP8266模塊STA模式獲取天氣信息學習應用,不僅可以瞭解到STA模式原理,還可以加深對HTTP協議,CJSON格式數據解析使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章