Smart home control system based on Huawei cloud design (STM32+ESP8266)

1. Function introduction

This is a smart home control system (model) designed based on Huawei cloud Internet of things platform. The hardware adopts STM32+ESP8266 to complete the cloud combination; Through the cloud platform, you can remotely control various electrical switches at home, and remotely collect information such as home gas, natural gas, smoke, illumination, temperature and humidity.

Hardware introduction:

Main control MCU: STM32F103ZET6

Smoke detection sensor: MQ2

Natural gas detection sensor: MQ5

Temperature and humidity detection sensor: DHT11

Light intensity detection sensor: BH1750

IOT cloud platform: Huawei cloud IOT platform

Electrical switch simulation adopts on-board LED lamp and relay.

WIFI: ESP8266 this is a WIFI module that supports serial port AT command control. Networking is more convenient.

Protocol for communication with Huawei cloud Internet of things platform: MQTT

Note: the MQTT protocol code in the current program is written with reference to the official MQTT document and does not use the built-in ESP8266. Therefore, the program does not rely on the special or specified SDK of ESP8266. It can be applied with any network card that can access the Internet. It is not necessary to use ESP8266.

2. Log in to Huawei cloud to create cloud devices

2.1 creating products

Huawei transport official website: https://www.huaweicloud.com/

Here you can view the port number and address of the access protocol.

MQTT (1883)	a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com	

MQTT is selected as the protocol for equipment access, and the corresponding port is 1883

Next, continue to create the product, click the product page, and click the upper right corner to create the product:

2.2 creating equipment

This is my device information:

equipment ID
61a580fad28ce3028832c2d8_esp8266_iot

Device key
1126626497
    
{
    "device_id": "61a580fad28ce3028832c2d8_esp8266_iot",
    "secret": "1126626497"
}

2.3 product model definition

This step is to set the attributes of the reporting device, that is, the data type definition of the device.

2.4 generate MQTT login key

After creating products and devices, you need to know how to log in to Huawei ECS through MQTT protocol.

The official details are here: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112

MQTT device login key generation address: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

The parameters of MQTT protocol device login are obtained below.

2.5 log in using MQTT client software

All parameters have been obtained. Next, log in to Huawei cloud using MQTT client for testing.

The following software is developed by ourselves to facilitate the test of MQTT protocol login.

The domain name of Huawei cloud Internet of things platform is a161a58a78.iot-mqtts.cn-north-4.myhuawei cloud.com

The IP address of Huawei cloud Internet of things platform is 121.36.42.100

After the parameters in the software are filled correctly, you can see that the device has been successfully connected.

Next, open the device page and you can see that the device is online.

2.6 reporting data

Official documents: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112

This document describes the format of MQTT reported data.

Format of summary:

//Subscription subject: the platform sends messages to devices
$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/messages/down

//Equipment reporting data
$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/properties/report

//Reported attribute message (multiple attributes can be reported at a time, just add them in json)
{"services": [{"service_id": "dht11","properties":{"DHT11-C":50}}]}

MQTT software is used to report data below:

At this point, the equipment data has been reported successfully. If more attributes need to be added, continue to add them according to the process.

3. STM32+ESP8266 report data to Huawei cloud

3.1 hardware equipment renderings

3.2 BH1750.c illuminance sensor

#include "bh1750.h"
float Read_BH1750_Data()
{
    unsigned char t0;
    unsigned char t1;
    float t;
    u8 r_s=0;
    IIC_Start(); //Send start signal
    IIC_WriteOneByteData(0x46);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:1\r\n");
    IIC_WriteOneByteData(0x01);
    r_s=IIC_GetACK();//Get response
     if(r_s)printf("error:2\r\n");
    IIC_Stop(); //Stop signal 
    
    IIC_Start(); //Send start signal
    IIC_WriteOneByteData(0x46);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:3\r\n");
    IIC_WriteOneByteData(0x01);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:4\r\n");
    IIC_Stop(); //Stop signal 
    
    IIC_Start(); //Send start signal
    IIC_WriteOneByteData(0x46);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:5\r\n");
    IIC_WriteOneByteData(0x10);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:6\r\n");
    IIC_Stop(); //Stop signal 
    
    DelayMs(300); //wait for
    
    IIC_Start(); //Send start signal
    IIC_WriteOneByteData(0x47);
    r_s=IIC_GetACK();//Get response
    if(r_s)printf("error:7\r\n");
    
    t0=IIC_ReadOneByteData(); //receive data 
    IIC_SendACK(0); //Send response signal
    t1=IIC_ReadOneByteData(); //receive data 
    IIC_SendACK(1); //Send non reply signal
    IIC_Stop(); //Stop signal
    
     t=(((t0<<8)|t1)/1.2);
     return t;  
}

3.3 ESP8266.c WIFI code

#include "esp8266.h"
u8 ESP8266_IP_ADDR[16]; //255.255.255.255
u8 ESP8266_MAC_ADDR[18]; //hardware address
/*
Function function: ESP8266 command sending function
 Function return value: 0 means success, 1 means failure
*/
u8 ESP8266_SendCmd(char *cmd)
{
    u8 i,j;
    for(i=0;i<10;i++) //Number of detections -- number of instructions sent
    {
        USARTx_StringSend(USART3,cmd);
        for(j=0;j<100;j++) //Waiting time
        {
            delay_ms(50);
            if(USART3_RX_FLAG)
            {
                USART3_RX_BUFFER[USART3_RX_CNT]='\0';
                USART3_RX_FLAG=0;
                USART3_RX_CNT=0;
                if(strstr((char*)USART3_RX_BUFFER,"OK"))
                {
                    return 0;
                }
            }
        }
    }
    return 1;
}

/*
Function: ESP8266 hardware initialization detection function
 Function return value: 0 means success, 1 means failure
*/
u8 ESP8266_Init(void)
{
    //Exit transparent mode
    USARTx_StringSend(USART3,"+++");
    delay_ms(50);
    return ESP8266_SendCmd("AT\r\n");
}


/*
Function: sending function in TCP server mode
 Send command: 
*/
u8 ESP8266_ServerSendData(u8 id,u8 *data,u16 len)
{
    u8 i,j,n;
    char ESP8266_SendCMD[100]; //Combine commands during sending
    for(i=0;i<10;i++)
    {
        sprintf(ESP8266_SendCMD,"AT+CIPSEND=%d,%d\r\n",id,len);
        USARTx_StringSend(USART3,ESP8266_SendCMD);
        for(j=0;j<10;j++)
        {
            delay_ms(50);
            if(USART3_RX_FLAG)
            {
                USART3_RX_BUFFER[USART3_RX_CNT]='\0';
                USART3_RX_FLAG=0;
                USART3_RX_CNT=0;
                if(strstr((char*)USART3_RX_BUFFER,">"))
                {
                    //Continue sending data
                    USARTx_DataSend(USART3,data,len);
                    //Wait for data to be sent successfully
                    for(n=0;n<200;n++)
                    {
                        delay_ms(50);
                        if(USART3_RX_FLAG)
                        {
                            USART3_RX_BUFFER[USART3_RX_CNT]='\0';
                            USART3_RX_FLAG=0;
                            USART3_RX_CNT=0;
                            if(strstr((char*)USART3_RX_BUFFER,"SEND OK"))
                            {
                                return 0;
                            }
                         }            
                    }   
                }
            }
        }
    }
    return 1;
}

/*
Function function: configure WIFI to STA mode + TCP client mode
 Function parameters:
char *ssid  Created hotspot name
char *pass  Created hotspot password (minimum 8 digits)
char *p     The IP address of the server to which you will connect
u16 port    The port number of the server to which you will connect
u8 flag     1 Indicates that the transparent transmission mode is turned on, and 0 indicates that the transparent transmission mode is turned off
 Function return value: 0 indicates success, and other values indicate corresponding errors
*/
u8 ESP8266_STA_TCP_Client_Mode(char *ssid,char *pass,char *ip,u16 port,u8 flag)
{
    char ESP8266_SendCMD[100]; //Combine commands during sending
    //Exit transparent mode
    //USARTx_StringSend(USART3,"+++");
    //delay_ms(50);
    /*1. Test hardware*/
    if(ESP8266_SendCmd("AT\r\n"))return 1;
    /*2. Turn off echo*/
    if(ESP8266_SendCmd("ATE0\r\n"))return 2;
    /*3. Set WIFI mode*/
    if(ESP8266_SendCmd("AT+CWMODE=1\r\n"))return 3;
    /*4. reset*/
    ESP8266_SendCmd("AT+RST\r\n");
    delay_ms(1000);
    delay_ms(1000);
    delay_ms(1000);
    /*5. Turn off echo*/
    if(ESP8266_SendCmd("ATE0\r\n"))return 5;
    /*6. Configure WIFI hotspot information to be connected*/
    sprintf(ESP8266_SendCMD,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pass);
    if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;
    /*7. Set up single connection*/
    if(ESP8266_SendCmd("AT+CIPMUX=0\r\n"))return 7;
    /*8. Configure the TCP server information to connect to*/
    sprintf(ESP8266_SendCMD,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",ip,port);
    if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;
    /*9. Turn on transparent transmission mode*/
    if(flag)
    {
       if(ESP8266_SendCmd("AT+CIPMODE=1\r\n"))return 9; //open
       if(ESP8266_SendCmd("AT+CIPSEND\r\n"))return 10;  //Start transmission
       if(!(strstr((char*)USART3_RX_BUFFER,">")))
       {
            return 11;
       }
        //If you want to quit sending: "+ + +"
    }
    
     //Print general information
    USART1_Printf("WIFI pattern:STA+TCP client\n");
    USART1_Printf("Connect_WIFI Hotspot name:%s\n",ssid);
    USART1_Printf("Connect_WIFI Hotspot password:%s\n",pass);
    USART1_Printf("TCP Server port number:%d\n",port);
    USART1_Printf("TCP The server IP address:%s\n",ip);
    return 0;
}


/*
Function: sending function in TCP client mode
 Send command: 
*/
u8 ESP8266_ClientSendData(u8 *data,u16 len)
{
    u8 i,j,n;
    char ESP8266_SendCMD[100]; //Combine commands during sending
    for(i=0;i<10;i++)
    {
        sprintf(ESP8266_SendCMD,"AT+CIPSEND=%d\r\n",len);
        USARTx_StringSend(USART3,ESP8266_SendCMD);
        for(j=0;j<10;j++)
        {
            delay_ms(50);
            if(USART3_RX_FLAG)
            {
                USART3_RX_BUFFER[USART3_RX_CNT]='\0';
                USART3_RX_FLAG=0;
                USART3_RX_CNT=0;
                if(strstr((char*)USART3_RX_BUFFER,">"))
                {
                    //Continue sending data
                    USARTx_DataSend(USART3,data,len);
                    //Wait for data to be sent successfully
                    for(n=0;n<200;n++)
                    {
                        delay_ms(50);
                        if(USART3_RX_FLAG)
                        {
                            USART3_RX_BUFFER[USART3_RX_CNT]='\0';
                            USART3_RX_FLAG=0;
                            USART3_RX_CNT=0;
                            if(strstr((char*)USART3_RX_BUFFER,"SEND OK"))
                            {
                                return 0;
                            }
                         }            
                    }   
                }
            }
        }
    }
    return 1;
}

3.4 main.c main function

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include "esp8266.h"
#include "mqtt.h"
#include "oled.h"
#include "fontdata.h"
#include "bh1750.h"
#include "iic.h"
#include "sht3x.h"


#define ESP8266_ WIFI_ AP_ SSID "CMCC cqvn" / / the name of the router to be connected -- do not appear Chinese, spaces and other special characters
#define ESP8266_AP_PASSWORD "99pu58cb" / / password of the router to be connected


//Device information of Huawei ECS
#define MQTT_ClientID "61a580fad28ce3028832c2d8_esp8266_iot_0_0_2021113002"
#define MQTT_UserName "61a580fad28ce3028832c2d8_esp8266_iot"
#define MQTT_PassWord "74af3bf3024cf9c41b13d6c63fc86e25012b54141ecfcdff3516f08665140e6f"

//Topics for subscriptions and publications
#define SET_ Topic "$OC / devices / 61a580fad28ce3028832c2d8_esp8266_iot / sys / messages / down" / / subscribe
#define POST_TOPIC "$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/properties/report" / / publish


char mqtt_message[200];//Report data buffer
char OLED_ShowBuff[100];
u8 ESP8266_Stat=0;


/*
Function: temperature and humidity \ light intensity display
*/
void ShowTemperatureAndHumidity(float temp,float humi,float light)
{
    sprintf(OLED_ShowBuff,"T: %.2f",temp);
	OLED_ShowString(40,16*0,16,OLED_ShowBuff); 
    sprintf(OLED_ShowBuff,"H: %.2f%%",humi);
	OLED_ShowString(40,16*1,16,OLED_ShowBuff);
    sprintf(OLED_ShowBuff,"L: %.2f%%",light);
	OLED_ShowString(40,16*2,16,OLED_ShowBuff); 
}

/*
Function function: ESP8266 display page
*/
void ESP8266_ShowPageTable(void)
{
    if(ESP8266_Stat)OLED_ShowString(0,16*0,16,"WIFI STAT:ERROR");
    else OLED_ShowString(0,16*0,16,"WIFI STAT:OK");

    //display string
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_WIFI_AP_SSID);
    OLED_ShowString(0,16*1,16,OLED_ShowBuff);	
    
    sprintf((char*)OLED_ShowBuff,"%s",ESP8266_AP_PASSWORD);   
    OLED_ShowString(0,16*2,16,OLED_ShowBuff);    
}


int main()
{
   u32 time_cnt=0;
   u32 i;
   u8 key;
   u8 page=0;
   float temp=0;
   float humi=0;
   float light=0;
   u8 motor_state=0;
   float Humidity;
   float Temperature;
    
   delay_ms(1000);
   delay_ms(1000);
    
   LED_Init();
   KEY_Init();
   IIC_Init();
    
    //OLED initialization
   OLED_Init(0xc8,0xa1); //OLED display initialization - normal display;
     //Clear screen
   OLED_Clear(0);
    
   USART1_Init(115200);
   TIMER1_Init(72,20000); //Timeout 20ms

   USART3_Init(115200);//Serial WIFI
   TIMER3_Init(72,20000); //Timeout 20ms
    
   Init_SHT30();
    
   USART1_Printf("Initializing WIFI One moment please.\n");
   
   if(ESP8266_Init())
   {
      ESP8266_Stat=1;
      USART1_Printf("ESP8266 Hardware detection error.\n");  
   }
   else
   {
      //Unencrypted port
      USART1_Printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(ESP8266_WIFI_AP_SSID,ESP8266_AP_PASSWORD,"121.36.42.100",1883,1));
   }
   
    //2. MQTT protocol initialization	
    MQTT_Init(); 
   
    //3. Connect Huawei cloud IOT server        
    while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))
    {
        USART1_Printf("Server connection failed,Retrying...\n");
        delay_ms(500);
    }
    USART1_Printf("Server connection succeeded.\n");
    
    
    //3. Subscribe to topics
    if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
    {
        USART1_Printf("Topic subscription failed.\n");
    }
    else
    {
        USART1_Printf("Topic subscription succeeded.\n");
    }        
        
    while(1)
    {    
        //The key can be tested
        key=KEY_Scan(0);
        if(key==1)
        {
            //Clear screen
            OLED_Clear(0);
            
            //Turn pages
            if(page>=1)
            {
                page=0;
            }
            else
            {
                 page++;
            }         
        
            LED1=!LED1;  //LEd status light
        }
        else if(key==2)
        {
            LED1=!LED1;  //LEd status light
            time_cnt=0;
            //Motor status change
            MOTOR_DEV=!MOTOR_DEV;
            //Motor status
            motor_state=MOTOR_DEV;
            //fill-in light
            LIGHT_DEV=!LIGHT_DEV;      
        }  
        
        //Receive data returned by WIFI
        if(USART3_RX_FLAG)
        {
            USART3_RX_BUFFER[USART3_RX_CNT]='\0';
            
            //Print the returned data to the serial port
            for(i=0;i<USART3_RX_CNT;i++)
            {
                USART1_Printf("%c",USART3_RX_BUFFER[i]);
            }
            
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
        }
              
        //Keep synchronization with Huawei cloud Internet of things -- once a second
        delay_ms(10);
        time_cnt++;
        if(time_cnt==50)
        {
            time_cnt=0;
            
            //Status light -- indicates that the program is still alive
            LED2=!LED2;
            
            //Read light intensity
            light=Read_BH1750_Data();
           
            //Read temperature and humidity
            SHT3x_ReadData(&Humidity,&Temperature);
            humi=Humidity;
            temp=Temperature;
            
            //Upload data - temperature
			sprintf(mqtt_message,"{\"services\": [{\"service_id\": \"dht11\",\"properties\":{\"DHT11-C\":%d}}]}",temp);
			
            MQTT_PublishData(POST_TOPIC,mqtt_message,0);
            //Automatic irrigation according to humidity
            if(humi<50.0)  //Less than 50 automatic irrigation
            {
                 motor_state=1; //Motor status update
                 MOTOR_DEV=1;  //Turn on the motor
            } 
        }
         
        //OLED display
        if(page==0)
        {
            ShowTemperatureAndHumidity(temp,humi,light);
        }
        else if(page==1)
        {
            ESP8266_ShowPageTable();
        }
    }
}

Tags: C++ Linux Qt

Posted on Tue, 30 Nov 2021 09:30:54 -0500 by ehmer