ESP8266連接機智雲實現手機控制和顯示

         本次博客主要實現通過stm32f407和esp8266實現機智雲的訪問和手機端數據的顯示和控制。

         由於網上的資源太亂,有的根本無法實現機智雲的訪問,本次博主走了彎路,花了半天時間才搞定機智雲的訪問,這裏總結一下,從零開始記錄。供大家學習。

        首先博主使用的是ESP8266-01模塊和ESP8266-12F 開發板均實現了對應的功能。兩個模塊如下圖所示。硬件還需要一個usb-ttl模塊就最常用的ch340G就就可以。除此之外,還需要用到兩個軟件,FLASH_DOWNLOAD_TOOLS_v2.4_150924和機智雲串口調試助手v2.3.5。其中前一個用來做固件的下載,後一個用來做固件下載後的調試。

                   

固件下載

         固件的下載可參見http://docs.gizwits.com/zh-cn/deviceDev/ESP8266%E4%B8%B2%E5%8F%A3%E7%83%A7%E5%86%99%E8%AF%B4%E6%98%8E.html這篇文章。 可以完成相應的固件下載。在我們用的ESP8266-01是SPI-Flash 選擇8M,ESP8266-12F是32M,選擇32M-C,這個參數在我們購買的商品明細中就可以看到。

        對於ESP8266-01,要將GPIO0引腳接低電平,使其處於下載模式,其他的VCC接3.3V(注意這裏 電壓過高會燒壞模塊),gnd接CH340G的GND,RXD接CH340G的TXD,TXD接RXD,EN管教接3.3V使能,之後打開上述的固件下載軟件,選擇對應的Flash,選擇對應的串口號,點擊下載按鈕,給ESP8266VCC拔掉重新上電,即可完成固件的下載。下載完成之後將GPIO0管腳的低電平撤去,即可。到此就完成了固件下載。

        ESP8266-12F開發板下載類似,直接按一下復位鍵即可,(有時候需要長按flash之後再按rst纔可以)。

機智雲端的設置

        在機智雲端,需要完成一個項目的建立和數據點的配置,這方面的介紹網上很多都可以實現功能。可以參考官方的文檔

http://docs.gizwits.com/zh-cn/quickstart/UseMCU.html。我定義的數據點如下

設備與手機連接

       上述完成了固件下載之後,然後繼續使用CH340G模塊連接電腦,將下載固件的軟件關閉,打開機智雲串口助手,切換到如下界面之後,填寫下邊在機智雲建立項目的key和密鑰,之後選擇對應的串口,之後打開串口,將手機下載機智雲app之後,添加新設備(一鍵配置),輸入當前的wifi賬號和密碼,下一步選擇對應的型號(我的設備是樂鑫選擇即可),將CH340G重新上電,此時在串口調試助手中選擇指令界面,點擊AirLink,之後ESP8266就處於待連接狀態,在手機上選擇我已完成以上操作即可等待串口助手和ESP8266通信完成wifi的連接。成功後接區會出現ECU發送的指令,就表示連接成功。

單片機通信分析   

         此時我們已經完成了ESP8266的固件下載和聯網工作,之後只需要實現單片機的控制即可。

        由於系統生成的stm32的代碼默認是hal庫的,而博主一直使用的是正點原子的例程,修改起來較困難,因此博主直接通過解析協議實現通信。相應的移植程序的方式請大家參考其他博主吧。

         我們可以在機智雲上述數據點那張圖左側選擇開發嚮導,找到MCU開發資源。,下載《窗簾控制 - 機智雲獨立MCU方案接入通信協議文檔》本文檔就是我們的通信協議。我們本次需要實現的是和實現窗簾開關狀態,光照強度,是否檢測到人,以及燈光開啓與否的上傳和手機顯示。

        首先,我們可以用剛纔的串口助手結合剛纔的開發文檔,進行單片機和WIFI模塊的通信分析 ,博主發現通信包括髮送和應答兩部分,一方發送之後另一方必須進行應答,主要包括這幾種。

  1. 上電之後WIFI請求單片機發送當前的id號和對應的雲端密鑰。
  2. WIFI模塊狀態變化(比如連接至雲端連上路由器這些變化)均會發送出一個命令。
  3. 單片機主動向WIFI模塊發送目前的狀態(即遠端顯示)。
  4. WIFI模塊發送給單片機當前的數據(即遠端設備控制單片機)。
  5. WIFI模塊每隔大約一分鐘會向單片機發送一個心跳包,單片機進行迴應即可,長時間不迴應就相當於設備離線。   

     根據上述分析,我們在看一下之前的開發文檔,可以看到協議格式如下

          

        拿單片機主動發送數據來看,如下圖,也就是我們要發送當前狀態爲LED-1.curtain-1,people-1,light-2,即0x07,0x02時,需要發送FF FF 00 08 05 00 00 00 04 07 02 1A,即可。通過程序可以很方便的實現上述的功能。

        當接收到WIFI模塊的數據,比如心跳包,如下圖所示,例如收到 FF FF 00  05 07 00 00 00 0C時,我們回覆FF FF 00 05 08 00 00 00 0D,即可,其他的類似。

         此時我們通過STM32串口和ESP8266進行通信即可。我們寫出的代碼如下,這裏只貼出了main.c供大家參考。

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "timer.h"

/*
typedef enum {FALSE = 0,TRUE = 1} bool;
*/
u8 light_flag=1;//¹âÏßÇ¿¶È ±£´æÖÁ 0-Èõ  1-ÖÐµÈ 2-Ç¿
u8 LED_flag=0;//LED±£´æÖµ 0¹Ø±Õ1´ò¿ª
u8 motor_flag=0;//µç»úÔËÐÐ״̬  1-Õýת 2-·´×ª  0-Í£Ö¹
u8 curtain_flag=0;//³õÊÔĬÈÏ´°Á±´ò¿ª  0-´ò¿ª 1-¹Ø±Õ
u8 people_flag=0;//¼ì²âµ½µ½ÈË 0ÿÈË 1ÓÐÈË
u8 usart_flag=0;//´®¿Ú ·¢ËͱêÖ¾ ±£Ö¤Ö»·¢ËÍÒ»´Î
u8 rec_state=0;//±£´æ ´®¿Ú½ÓÊÕµ½µÄÐÅÏ¢µÄ״̬ 
u8 send_num_flag=0;//±£Ö¤·¢ËÍ´ÎÊýΪһ´Î

u16 motor_num=0;//±£Ö¤ µç»úÔËÐÐÒ»¶Îʱ¼äÍ£Ö¹
u8 send_num=0;
u8 my_state[12]={0xff,0xff,0x00,0x08,0x05,0x00,0x00,0x00,0x04,0x07,0x02,0x1A};//½«µ±Ç°µÄ״̬·¢³ö 
u8 my_reley[9]={0xff,0xff,0x00,0x05,0x0E,0x01,0x00,0x00,0x14};
u8 usart_rec[6]={0x00};
u8 zhangtai_state[9]={0xFF,0xFF,0x00,0x05,0x0E,0x01,0x00,0x00,0x14};
u8 xintiao_state[9]={0xFF,0xFF,0x00,0x05,0x08,0x00,0x00,0x00,0x0D};
u8 shangbao_state[12]={0xff,0xff,0x00,0x08,0x04,0x00,0x00,0x00,0x03,0x07,0x02,0x18};
u8  xinghao_send[115]={0xFF,0xFF,0x00,0x6F,0x02,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x34,0x30,0x30,0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x30,0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x30, 0x30, 0x30,
0x30, 0x30, 0x30, 0x30, 0x35, 0x36, 0x61, 0x35, 0x61, 0x63, 0x33, 0x35, 0x39, 0x31, 0x66, 0x32, 0x38, 0x34, 0x64, 0x33, 0x38, 0x61, 0x37, 0x36, 0x39, 0x39, 0x65, 0x34, 0x62, 0x30, 0x34, 0x34, 0x30, 0x31, 0x35, 0x63, 0x34, 0x00, 
0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00, 0x02, 0x65, 0x32, 0x36, 0x61, 0x33, 0x32, 0x32, 0x66, 0x62, 0x32, 0x31, 0x65, 0x34, 0x31, 0x38, 0x34, 0x61, 0x64, 0x32, 0x32, 0x63, 0x66, 0x32,0x37, 0x63, 0x31, 0x30, 0x30, 0x35, 
0x33 ,0x61 ,0x64, 0x5D };//Éϵçºó Ðͺŷµ»ØÖµ


void motor_add(){//µç»úÕýתº¯Êý
	Motor_A=1;
	Motor_B=1;
	Motor_C=0;
	Motor_D=0;
	delay_ms(2);
		Motor_A=0;
	Motor_B=1;
	Motor_C=1;
	Motor_D=0;
	delay_ms(2);
		Motor_A=0;
	Motor_B=0;
	Motor_C=1;
	Motor_D=1;
	delay_ms(2);
		Motor_A=1;
	Motor_B=0;
	Motor_C=0;
	Motor_D=1;
	delay_ms(2);	
}


void motor_dec(){//µç»ú·´×ª º¯Êý
	Motor_A=1;
	Motor_B=1;
	Motor_C=0;
	Motor_D=0;
	delay_ms(2);
	
	Motor_A=1;
	Motor_B=0;
	Motor_C=0;
	Motor_D=1;
	delay_ms(2);
	Motor_A=0;
	Motor_B=0;
	Motor_C=1;
	Motor_D=1;
	delay_ms(2);
		Motor_A=0;
	Motor_B=1;
	Motor_C=1;
	Motor_D=0;
	delay_ms(2);	
}

void motor_stop(){//µç»úÍ£Ö¹
	Motor_A=0;
	Motor_B=0;
	Motor_C=0;
	Motor_D=0;
	delay_ms(2);	
}


void ligth_scan(){//¸ßµçƽ ¹âÈõÓÚÉ趨ֵ µÍµçƽ Ç¿ÓÚÉ趨ֵ
	if(Light_low==1){
		light_flag=0;//¹âÈõ
	}else{//±ÈµÍ¹âÕÕÉ趨ֵ¸ß
		if(Light_high==1){//ÖмäÖµ
			light_flag=1;
		}else{
			light_flag=2;//Ç¿ÓÚÁ½¸öÖµ
		}
	}
}

void motor_auto(){//µç»úÔËÐÐ °´ÕÕµç»ú±ê־λ½øÐÐÔËÐÐ
	if(motor_flag==1){
		motor_add();
	}else if(motor_flag==2){
		motor_dec();
	}else{
		motor_stop();
	}
}
void motor_run(){//´°Á±¿ØÖƺ¯Êý ¹âÕÕÊÊÒË ´ò¿ª´°Á± ¹ýÇ¿»òÕß¹ýÈõ ¹Ø±Õ´°Á±
	if(light_flag!=1&&curtain_flag==0){//´°Á±´ò¿ª×´Ì¬
		motor_flag=1;
		motor_num++;
		if(motor_num>1000){//ÑÓʱһ¶Îʱ¼ä  Èõç»ú תһ¶Îʱ¼äÍ£Ö¹ ´°Á±×ª»»×´Ì¬
			motor_num=0;
			motor_flag=0;
			curtain_flag=1;
		}
	}else if(light_flag==1&&curtain_flag==1){
		motor_flag=2;
		motor_num++;
		if(motor_num>1000){
			motor_num=0;
			motor_flag=0;
			curtain_flag=0;
		}
	}
	else{
		motor_flag=0;
	}
}
void check_sun_cal(){
	u8 i;
	u16 sum=0;
	for(i=2;i<11;i++){
		sum+=my_state[i];//¼ÆËãÊý×éÄÚ²¿µÄÖµ УÑéλ
	}
	my_state[11]=sum%256;
}

void led_run(){//LEDÔËÐÐ״̬ 
	if(curtain_flag==1){//´°Á±¹Ø±Õ ÇÒ ¼ì²âµ½ÈË´ò¿ªLED ·ñÔò¹Ø±ÕLED
		LED1=!People;
		people_flag=People;
		LED_flag=people_flag;
	}else{//´°Á±´ò¿ª µÆ¹â¹Ø±Õ
		LED1=1;
		LED_flag=0;
		people_flag=People;
	}
}


void UartA1SendStr(u8 *pucStr,u8 ulNum) //´®¿Ú1·¢ËÍÓïÒôÃüÁî
{ 
	u8 i; 
	for(i = 0;i<ulNum;i++) 
	{ 
	while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET) ; 
			USART_SendData(USART1,*pucStr++); 
	}  
} 
//µ±Ç°µÄ״̬ ·¢ËÍ
void send_state(){
	my_state[5]=send_num;
	my_state[9]=LED_flag+2*people_flag+4*(!curtain_flag);
	my_state[10]=light_flag;
	check_sun_cal();
	UartA1SendStr(my_state,12);
	send_num++;
}
//¼ìÑéλ¼ÆËã
void check_sun_cal_zhuangtai(){
	u8 i;
	u16 sum=0;
	for(i=2;i<8;i++){
		sum+=zhangtai_state[i];
	}
	zhangtai_state[8]=sum%256;
}
//ÐÄÌø°üµÄ¼ìÑéλ
void check_sun_cal_xintiao(){
	u8 i;
	u16 sum=0;
	for(i=2;i<8;i++){
		sum+=xintiao_state[i];
	}
	xintiao_state[8]=sum%256;
}
//Éϱ¨¹ý³ÌÖРУÑéλ¼ÆËã
void check_sun_cal_shangbao(){
	u8 i;
	u16 sum=0;
	for(i=2;i<11;i++){
		sum+=shangbao_state[i];
	}
	shangbao_state[11]=sum%256;
}
//¼ÆÊýλÿ´Î¼ÓÒ»
void zhangtai_state_change(){
	zhangtai_state[5]=send_num;
	check_sun_cal_zhuangtai();
	
	send_num++;
}
//ÐÄÌø°ü¼ÆÊýλÿ´Î¼ÓÒ»
void xintiao_state_change(){
	xintiao_state[5]=send_num;
	check_sun_cal_xintiao();
	
	send_num++;
}

//¼ÆÊýλÿ´Î¼ÓÒ»
void shangbao_state_change(){
	shangbao_state[5]=send_num;
	check_sun_cal_shangbao();
	
	send_num++;
}

int main(void)
{       
		
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2
	delay_init(168);  //³õʼ»¯ÑÓʱº¯Êý
	uart_init(9600);		//³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200
	TIM3_Int_Init(20000-1,8400-1);//¶¨Ê±Æ÷ʱÖÓ84M£¬·ÖƵϵÊý8400£¬ËùÒÔ84M/8400=10KhzµÄ¼ÆÊýƵÂÊ£¬¼ÆÊý5000´ÎΪ500ms 
	LED_Init();					//³õʼ»¯LED  
 	KEY_Init();					//°´¼ü³õʼ»¯  
	send_state();//Ö÷¶¯·¢ËÍÒ»´Î µ±Ç°µÄ״̬
	while(1)
	{
		//key=KEY_Scan(0);
		ligth_scan();
		motor_run();
		motor_auto();
		led_run();
		//delay_ms(1000);
		if(rec_state==1&&send_num_flag==0){//
			UartA1SendStr(xinghao_send,115);//Éϵçºó ·¢Ë͵±Ç°µÄÉ豸״̬
			send_num_flag=1;
		}else if(rec_state==2&&send_num_flag==0){//WiFi״̬¸Ä±äÖ®ºó·¢ËÍÓ¦´ðÐźŠ±ÈÈçÁ¬ÉÏwifiÖ®ºó 
			zhangtai_state_change();
			UartA1SendStr(zhangtai_state,9);
			send_num_flag=1;
		}else if(rec_state==3&&send_num_flag==0){//ÊÕµ½ÐÄÌø°ü Ö®ºó ·¢ËÍÏàÓ¦ÐźÅ
			xintiao_state_change();
			UartA1SendStr(xintiao_state,9);
			send_num_flag=1;
		}else if(rec_state==4&&send_num_flag==0){//ÊÕµ½Ô¶³ÌµÄÐźŠÈç¹ûÐèÒªÔ¶³Ì¿ØÖÆÉ豸ÔÚÕâÀï½øÐм´¿É
			shangbao_state_change();
			UartA1SendStr(shangbao_state,12);//ÕâÀï½ö½øÐÐ Ó¦´ð ÒòΪ±¾Éè¼ÆÖ»½øÐÐÁËÔ¶³ÌÏÔʾ ²»ÐèÒªÔ¶³Ì¿ØÖÆ
			send_num_flag=1;
		}
}
	}
  
//¶¨Ê±Æ÷3ÖжϷþÎñº¯Êý
	//ÿ¸ô2Ãë Ö÷¶¯·¢ËÍÒ»´Îµ±Ç°µÄ״̬
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //Òç³öÖжÏ
	{
		//LED1=!LED1;//DS1·­×ª
		send_state();//·¢Ë͵±Ç°µÄ״̬
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //Çå³ýÖжϱê־λ
}


void USART1_IRQHandler(void)                	//´®¿Ú1ÖжϷþÎñ³ÌÐò
{
	u8 Res,buf_i;
#ifdef OS_TICKS_PER_SEC	 	//Èç¹ûʱÖÓ½ÚÅÄÊý¶¨ÒåÁË,˵Ã÷ҪʹÓÃucosIIÁË.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //½ÓÊÕÖжÏ(½ÓÊÕµ½µÄÊý¾Ý±ØÐëÊÇ0x0d 0x0a½áβ)
	{
		Res =USART_ReceiveData(USART1);//(USART1->DR);	//¶ÁÈ¡½ÓÊÕµ½µÄÊý¾Ý
		//printf("here");
		usart_rec[5]=Res;	
		if(Res==0xFF&&usart_flag==0){
			usart_flag=1;
		}
		if(usart_flag){
			for(buf_i=0;buf_i<5;buf_i++){
			usart_rec[buf_i]=usart_rec[buf_i+1];
				//printf("1");
		}
			if(usart_rec[0]==0xff&&usart_rec[1]==0xff&&usart_rec[4]==1){//Éϵçºó»ñÈ¡É豸ÐÅÏ¢ 
				rec_state=1;
				usart_flag=0;
				send_num_flag=0;
				//printf("dejdjei");
			}else if(usart_rec[0]==0xff&&usart_rec[1]==0xff&&usart_rec[4]==0x0D){//?WiFi״̬¸Ä±äÖ®ºó ½«×´Ì¬ÍÆË͸øµ¥Æ¬»ú
				rec_state=2;
				usart_flag=0;
				send_num_flag=0;
				//printf("2");
			}else if(usart_rec[0]==0xff&&usart_rec[1]==0xff&&usart_rec[4]==0x07){//ÊÕµ½ÐÄÌø°ü ´óÔ¼Ò»·ÖÖÓ·¢Ò»´Î 
				rec_state=3;
				usart_flag=0;
				send_num_flag=0;
				//printf("2");
			}else if(usart_rec[0]==0xff&&usart_rec[1]==0xff&&usart_rec[4]==0x03){//wifiÄ£×é¿ØÖÆÉ豸 Ô¶³ÌÊÖ»ú¿ØÖÆʱºò Àï±ßÓÐÖµ
				rec_state=4;
				usart_flag=0;
				send_num_flag=0;
				//printf("2");
			}
			
		}
	   		 
  } 
#ifdef OS_TICKS_PER_SEC	 	//Èç¹ûʱÖÓ½ÚÅÄÊý¶¨ÒåÁË,˵Ã÷ҪʹÓÃucosIIÁË.
	OSIntExit();  											 
#endif
}


 

         相應的STM32工程下載 地址爲:

        機智雲工具打包下載地址爲:

        全部文件下載地址:鏈接:https://pan.baidu.com/s/1IDSWDzqW6hCIS0HtObwvWg 提取碼:hp8i

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