产品功能:STM32单片机通过ESP8266与阿里云平台进行通信,接受到阿里云平台(具有配套的APP)的数据进而执行相应操作:打开LED、关闭LED

硬件设备:

STM32 C8T6单片机
ESP8266模块
USB转TTL模块
3.3V供电设备

一、整体思路:

①:首先STM32单片机通过ESP8266模块连接路由器进而和阿里云建立TCP连接
②:在阿里云平台创建设备和添加产品(获得三段码:产品ID、设备名称、设备秘钥 非常重要
③:STM32单片机通过ESP8266向阿里云发送连接和订阅报文
④:连接和订阅成功后,开始上发和接受数据,并执行相应的指令

二、硬件设备搭建:

使用STM32单片机的两个串口进行数据的传输:
①串口1:通过USB转TTL模块连接PC端,通过XCOM来显示一些信息
②串口和ESP8266模块进行连接
③LED灯使用的是C8T6单片机默认的PC13

三、阿里云平台的搭建:

放一个视频供大家参考

bilibili html5 player

基于STM32单片机ESP8266物联网阿里云MQTT多路继电器控制

链接: 视频链接

四、代码实现部分:

main.c

①:首先是串口1、串口2、LED、Wifi、MQTT等的初始化:

// An highlighted block
int main(void) 
{    
    Delay_Init();                   //延时功能初始化              
    Usart1_Init(9600);              //串口1功能初始化,波特率9600
    Usart2_Init(115200);            //串口2功能初始化,波特率115200    
    TIM4_Init(300,7200);            //TIM4初始化,定时时间 300*7200*1000/72000000 = 30ms
    LED_Init();                        //LED初始化
    KEY_Init();                     //按键初始化
    WiFi_ResetIO_Init();            //初始化WiFi的复位IO
    MQTT_Buff_Init();               //初始化接收,发送,命令数据的 缓冲区 以及各状态参数
    AliIoT_Parameter_Init();        //初始化连接阿里云IoT平台MQTT服务器的参数    

②进入while(1)循环中,首先是对ESP8266发送AT指令连接路由器并且和阿里云建立TCP连接

在wifi.h中定义了路由器的名称和密码,其他的是一些功能函数:

// An highlighted block
#define SSID   "MERCURY_725E"                     //路由器SSID名称
#define PASS   "15127963426"                 //路由器密码

void WiFi_ResetIO_Init(void);
char WiFi_SendCmd(char *cmd, int timeout);
char WiFi_Reset(int timeout);
char WiFi_JoinAP(int timeout);
char WiFi_Connect_Server(int timeout);
char WiFi_Smartconfig(int timeout);
char WiFi_WaitAP(int timeout);
char WiFi_Connect_IoTServer(void);

wifi.c中主要是对ESP8266发送AT指令,设置ESP8266的模式,从而连接路由器和与阿里云建立TCP连接:

源代码写的确实有点详细了,我也没有改动直接按这样用的。0.0

// An highlighted block
var foo = 'bar';
char WiFi_Connect_IoTServer(void)
{    
    u1_printf("准备复位模块\r\n");                     //串口提示数据
    if(WiFi_Reset(50)){                                //复位,100ms超时单位,总计5s超时时间
        u1_printf("复位失败,准备重启\r\n");           //返回非0值,进入if,串口提示数据
        return 1;                                      //返回1
    }else u1_printf("复位成功\r\n");                   //串口提示数据
    
    u1_printf("准备设置STA模式\r\n");                  //串口提示数据
    if(WiFi_SendCmd("AT+CWMODE=1",50)){                //设置STA模式,100ms超时单位,总计5s超时时间
        u1_printf("设置STA模式失败,准备重启\r\n");    //返回非0值,进入if,串口提示数据
        return 2;                                      //返回2
    }else u1_printf("设置STA模式成功\r\n");            //串口提示数据
    
    if(wifi_mode==0){                                      //如果联网模式=0:SSID和密码写在程序里 
        u1_printf("准备取消自动连接\r\n");                 //串口提示数据
        if(WiFi_SendCmd("AT+CWAUTOCONN=0",50)){            //取消自动连接,100ms超时单位,总计5s超时时间
            u1_printf("取消自动连接失败,准备重启\r\n");   //返回非0值,进入if,串口提示数据
            return 3;                                      //返回3
        }else u1_printf("取消自动连接成功\r\n");           //串口提示数据
                
        u1_printf("准备连接路由器\r\n");                   //串口提示数据    
        if(WiFi_JoinAP(30)){                               //连接路由器,1s超时单位,总计30s超时时间
            u1_printf("连接路由器失败,准备重启\r\n");     //返回非0值,进入if,串口提示数据
            return 4;                                      //返回4    
        }else u1_printf("连接路由器成功\r\n");             //串口提示数据            
    }else{                                                 //如果联网模式=1:Smartconfig方式,用APP发送
        if(KEY2_IN_STA==0){                                    //如果此时K2是按下的
            u1_printf("准备设置自动连接\r\n");                 //串口提示数据
            if(WiFi_SendCmd("AT+CWAUTOCONN=1",50)){            //设置自动连接,100ms超时单位,总计5s超时时间
                u1_printf("设置自动连接失败,准备重启\r\n");   //返回非0值,进入if,串口提示数据
                return 3;                                      //返回3
            }else u1_printf("设置自动连接成功\r\n");           //串口提示数据    
            
            u1_printf("准备开启Smartconfig\r\n");              //串口提示数据
            if(WiFi_SendCmd("AT+CWSTARTSMART",50)){            //开启Smartconfig,100ms超时单位,总计5s超时时间
                u1_printf("开启Smartconfig失败,准备重启\r\n");//返回非0值,进入if,串口提示数据
                return 4;                                      //返回4
            }else u1_printf("开启Smartconfig成功\r\n");        //串口提示数据

            u1_printf("请使用APP软件传输密码\r\n");            //串口提示数据
            if(WiFi_Smartconfig(60)){                          //APP软件传输密码,1s超时单位,总计60s超时时间
                u1_printf("传输密码失败,准备重启\r\n");       //返回非0值,进入if,串口提示数据
                return 5;                                      //返回5
            }else u1_printf("传输密码成功\r\n");               //串口提示数据

            u1_printf("准备关闭Smartconfig\r\n");              //串口提示数据
            if(WiFi_SendCmd("AT+CWSTOPSMART",50)){             //关闭Smartconfig,100ms超时单位,总计5s超时时间
                u1_printf("关闭Smartconfig失败,准备重启\r\n");//返回非0值,进入if,串口提示数据
                return 6;                                      //返回6
            }else u1_printf("关闭Smartconfig成功\r\n");        //串口提示数据
        }else{                                                 //反之,此时K2是没有按下
            u1_printf("等待连接路由器\r\n");                   //串口提示数据    
            if(WiFi_WaitAP(30)){                               //等待连接路由器,1s超时单位,总计30s超时时间
                u1_printf("连接路由器失败,准备重启\r\n");     //返回非0值,进入if,串口提示数据
                return 7;                                      //返回7    
            }else u1_printf("连接路由器成功\r\n");             //串口提示数据                    
        }
    }
    
    u1_printf("准备设置透传\r\n");                     //串口提示数据
    if(WiFi_SendCmd("AT+CIPMODE=1",50)){               //设置透传,100ms超时单位,总计5s超时时间
        u1_printf("设置透传失败,准备重启\r\n");       //返回非0值,进入if,串口提示数据
        return 8;                                      //返回8
    }else u1_printf("设置透传成功\r\n");               //串口提示数据
    
    u1_printf("准备关闭多路连接\r\n");                 //串口提示数据
    if(WiFi_SendCmd("AT+CIPMUX=0",50)){                //关闭多路连接,100ms超时单位,总计5s超时时间
        u1_printf("关闭多路连接失败,准备重启\r\n");   //返回非0值,进入if,串口提示数据
        return 9;                                      //返回9
    }else u1_printf("关闭多路连接成功\r\n");           //串口提示数据
    
    u1_printf("准备连接服务器\r\n");                   //串口提示数据
    if(WiFi_Connect_Server(100)){                      //连接服务器,100ms超时单位,总计10s超时时间
        u1_printf("连接服务器失败,准备重启\r\n");     //返回非0值,进入if,串口提示数据
        return 10;                                     //返回10
    }else u1_printf("连接服务器成功\r\n");             //串口提示数据    
    
    return 0;                                          //正确返回0
    
}

③:通过ESP8266向阿里云发送连接和订阅报文

这个完全不用改,直接用:

// An highlighted block

/*----------------------------------------------------------*/
/*函数名:连接服务器报文                                    */
/*参  数:无                                                */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_ConectPack(void)
{
 、、、、、、、因为很长就不复制粘贴了。
}

/*----------------------------------------------------------*/
/*函数名:SUBSCRIBE订阅topic报文                            */
/*参  数:QoS:订阅等级                                     */
/*参  数:topic_name:订阅topic报文名称                     */
/*返回值:无                                                */
/*----------------------------------------------------------*/
void MQTT_Subscribe(char *topic_name, int QoS)
{
、、、、、、、、、、
}

④:接受阿里云(有配套的APP)发送过来的消息,进而执行打开和关闭LED

代码:

// An highlighted block
if(MQTT_CMDOutPtr != MQTT_CMDInPtr){                             //if成立的话,说明命令缓冲区有数据了                   
        u1_printf("命令:%s\r\n",&MQTT_CMDOutPtr[2]);                 //串口输出信息
        if(strstr((char *)MQTT_CMDOutPtr+2,"\params\":{\"PowerSwitch\":1}")){
        LED1_ON;//接受到‘1’的命令,打开LED
        LED1_State();//并上传此时LED状态的信息
        }else if(strstr((char *)MQTT_CMDOutPtr+2,"\params\":{\"PowerSwitch\":0}")){
        LED1_OFF;//接受到‘0’的命令,关闭LED
        LED1_State();//并上传此时LED状态的信息
        }
        MQTT_CMDOutPtr += BUFF_UNIT;                                  //指针下移
        if(MQTT_CMDOutPtr==MQTT_CMDEndPtr)                            //如果指针到缓冲区尾部了
        MQTT_CMDOutPtr = MQTT_CMDBuf[0];                           //指针归位到缓冲区开头                
}//处理命令缓冲区数据的else if分支结尾    

LED1_State(); LED状态返回函数:

void LED1_State(void)
{
    char temp[256];
    if(LED1_IN_STA)
    sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"PowerSwitch\":0},\"version\":\"1.0.0\"}");  
    else
    sprintf(temp,"{\"method\":\"thing.event.property.post\",\"id\":\"203302322\",\"params\":{\"PowerSwitch\":1},\"version\":\"1.0.0\"}");  
}

APP界面:

在这里插入图片描述

在这里插入图片描述

文章知识点与官方知识档案匹配,可进一步学习相关知识