本次博客主要实现通过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模块的通信分析 ,博主发现通信包括发送和应答两部分,一方发送之后另一方必须进行应答,主要包括这几种。
- 上电之后WIFI请求单片机发送当前的id号和对应的云端密钥。
- WIFI模块状态变化(比如连接至云端连上路由器这些变化)均会发送出一个命令。
- 单片机主动向WIFI模块发送目前的状态(即远端显示)。
- WIFI模块发送给单片机当前的数据(即远端设备控制单片机)。
- 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
}
全部文件下载地址:链接:https://pan.baidu.com/s/1IDSWDzqW6hCIS0HtObwvWg 提取码:hp8i