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(); } } }