单片机给取:STM32F103C8T6
上网方式:给取ESP8266,也可以运用其余方法与代,只有撑持TCP和谈便可。比如:GSM模块、有线网卡等。
云平台: 给取中国挪动OneNet. 也可以给取腾讯、阿里云、华为云、百度天工物接入、机警云等等。 前面文章有解说。
和谈: 给取MQTT和谈
开发软件:keil5
完好名目源码下载: hts://download.csdn.net/download/Viaolong1126626497/19766925
二、包孕的硬件取真物图引见一个光敏电阻传感器
一个DHT11温湿度传感器
一个MQ-5 液化气/自然气/煤气监测传感器
一个MQ-2 烟雾传感器
3盏LED灯默示窗帘开关、空调开关、电室开关
联网WIFI给取: ESP8266
最小系统板: STM32F103C8T6
物联网效劳器: OneNet平台
物联网手机APP: 方法云
方法云APP下载地址(Android): hts://download.csdn.net/download/Viaolong1126626497/18697132
三、罪能引见那是基于STM32设想的智能家居控制系统,给取ESP8266连贯OneNet云平台。
方法端可以真时支罗烟雾浓度、温湿度、煤气自然气浓度到云平台,正在云平台网页端大概手机APP上可以远程查察数据,还可以点击云平台界面上的按钮,完成对家里的电器方法控制:窗帘开关、空调开关、电室开关(给取LED灯模拟)等。
四、OneNet创建立备从0初步创立OneNet方法,参考那里:hts://cloud.tencentss/deZZZeloper/article/1931954
首地址:hts://open.iot.10086ss/
那是STM32方法端连贯OneNet串口打印的提示信息:
登录乐成的成效:
数据流支到物联网末端上传的信息。
查察设想的网页界面:
五、步调下载引见点击初步编程之后,按下开发板上的RST按钮,便可启动下载。
六、STM32方法端代码6.1 esp8266.c代码语言:jaZZZascript
复制
#include "esp8266.h" struct ESP8266_WIFI esp8266_wifi; /* 函数罪能: 配置ESP8266WIFI为AP形式+TCP效劳器形式 函数参数: char *ssid :将要创立的WIFI热点称呼(英笔朱母) char *password :将要创立的WIFI热点暗码(最利害度8位) u16 port :TCP效劳器的端口号(0~65535) 返 回 值:0默示乐成,其余值默示失败 */ u8 ESP8266_AP_TCP_SerZZZerMode(const char *ssid,const char *password,u16 port) { u8 i; char *find_str=NULL; char cmd_buffer[100]; /*1. 发送测试指令,检测WIFI能否一般*/ printf("发送测试指令,检测WIFI能否一般...\n"); if(ESP8266_SendCmd("AT\r\n"))return 1; /*2. 封锁回显*/ printf("封锁回显...\n"); if(ESP8266_SendCmd("ATE0\r\n"))return 2; /*3. 设置当前WIFI的形式为AP形式*/ printf("设置当前WIFI的形式为AP形式...\n"); if(ESP8266_SendCmd("AT+CWMODE=2\r\n"))return 3; /*4. 复位模块,设置的形式必须复位之后才会生效*/ printf("复位模块...\n"); if(ESP8266_SendCmd("AT+RST\r\n"))return 4; DelayMs_72M(1000); DelayMs_72M(1000); DelayMs_72M(1000); DelayMs_72M(1000); /*5. 封锁回显*/ printf("封锁回显...\n"); if(ESP8266_SendCmd("ATE0\r\n"))return 5; /*6. 设置创立的热点信息*/ printf("设置创立的热点信息...\n"); snprintf(cmd_buffer,100,"AT+CWSAP=\"%s\",\"%s\",1,4\r\n",ssid,password); if(ESP8266_SendCmd(cmd_buffer))return 6; /*7. 开启多连贯,正在效劳器形式下才可开启*/ printf("开启多连贯...\n"); if(ESP8266_SendCmd("AT+CIPMUX=1\r\n"))return 7; /*8. 设置端口号(0~65535)*/ printf("设置端口号...\n"); snprintf(cmd_buffer,100,"AT+CIPSERxER=1,%d\r\n",port); if(ESP8266_SendCmd(cmd_buffer))return 8; /*9.查问原地IP地址*/ printf("查问原地IP地址...\n"); if(ESP8266_SendCmd("AT+CIFSR\r\n"))return 9; /*10. 保存WIFI的信息*/ esp8266_wifi.port=port; strcpy(esp8266_wifi.mode,"AP"); //提与IP地址 /* IP地址=+CIFSR:APIP,"192.168.4.1" +CIFSR:APMAC,"86:f3:eb:17:e6:86" */ find_str=strstr((char*)USART3_RX_BUFF,"APIP"); if(find_str) //判断能否查找乐成 { find_str+=6; for(i=0;*find_str!=V27;"V27;;i++) { esp8266_wifi.ip[i]=*find_str; find_str++; } esp8266_wifi.ip[i]=V27;\0V27;; } USART3_RX_FLAG=0; USART3_RX_CNT=0; printf("当前WIFI形式:%s\n",esp8266_wifi.mode); printf("当前网络和谈类型:%s\n","TCP"); printf("当前网络通信形式:%s\n","serZZZer"); printf("当前网络端口号:%d\n",esp8266_wifi.port); printf("原地网络IP地址:%s\n",esp8266_wifi.ip); return 0; } /* 函数罪能:向ESP8266wifi发送指令 注明:该函数只是折用于乐成后返回OK的指令 返回值: 0默示乐成 1默示失败 */ u8 ESP8266_SendCmd(char *cmd) { u8 i,j; for(i=0;i<5;i++) //测试的总次数 { USART3_RX_FLAG=0; USART3_RX_CNT=0; USART_X_SendString(USART3,cmd); for(j=0;j<200;j++) //等候的光阳(ms单位) { if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; printf("USART3_RX_BUFF=%s\r\n",USART3_RX_BUFF); if(strstr((char*)USART3_RX_BUFF,"OK\r\n")) { return 0; } else break; } DelayMs_72M(2); //一次的光阳 } } return 1; } /* 函数罪能:ESP8266wifi处于TCP效劳器形式下的数据发送函数 函数参数: u8 id :曾经连贯效劳器的客户端ID号 char *data :将要发送数据(字符串) 返回值: 0默示乐成 1默示失败 注明:只要正在TCP效劳器形式下才可运用该函数 OK > RecZZZ 12 bytes SEND OK */ u8 ESP8266_SerZZZerSendData(u8 id,char *data) { u32 i,j,n; char cmd[100]; snprintf(cmd,1024,"AT+CIPSEND=%d,%d\r\n",id,strlen(data)); for(i=0;i<5;i++) //测试的总次数 { USART3_RX_FLAG=0; USART3_RX_CNT=0; USART_X_SendString(USART3,cmd); for(j=0;j<200;j++) //等候的光阳(ms单位) { if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; if(strstr((char*)USART3_RX_BUFF,">")) //初步发送数据 { USART3_RX_FLAG=0; USART3_RX_CNT=0; USART_X_SendString(USART3,data); //发送数据 for(n=0;n<10000;n++) { if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; if(strstr((char*)USART3_RX_BUFF,"SEND OK")) //初步发送数据 { USART3_RX_FLAG=0; USART3_RX_CNT=0; return 0; } else return 1; } DelayMs_72M(1); //一次的光阳 } } else break; } DelayMs_72M(5); //一次的光阳 } } return 1; } /* 函数罪能: 设置STA形式下连贯的热点信息 返 回 值: 0默示乐成,1默示失败 连贯乐成的提示符: WIFI DISCONNECT WIFI CONNECTED WIFI GOT IP OK */ u8 ESP8266_STA_ModeConnectWIFI(char *cmd) { u32 i,j; for(i=0;i<3;i++) //测试的总次数 { USART3_RX_FLAG=0; USART3_RX_CNT=0; USART_X_SendString(USART3,cmd); for(j=0;j<30000;j++) //等候的光阳(ms单位) { if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; if(strstr((char*)USART3_RX_BUFF,"OK")) { return 0; } else { memset(USART3_RX_BUFF,0,sizeof(USART3_RX_BUFF)); USART3_RX_FLAG=0; USART3_RX_CNT=0; } } DelayMs_72M(1); //一次的光阳 } } return 1; } /* 函数罪能: 用于正在客户端形式下,连贯效劳器 返 回 值: 0默示乐成,1默示失败 连贯乐成的提示符:CONNECT */ u8 ESP8266_ConnectSerZZZer(char *cmd) { u32 i,j; for(i=0;i<5;i++) //测试的总次数 { USART3_RX_FLAG=0; USART3_RX_CNT=0; USART_X_SendString(USART3,cmd); for(j=0;j<10000;j++) //等候的光阳(ms单位) { if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; if(strstr((char*)USART3_RX_BUFF,"CONNECT")) { return 0; } else { memset(USART3_RX_BUFF,0,sizeof(USART3_RX_BUFF)); USART3_RX_FLAG=0; USART3_RX_CNT=0; } } DelayMs_72M(1); //一次的光阳 } } return 1; } /* 函数罪能: 配置ESP8266WIFI为STA形式+TCP客户端形式 函数参数: char *ssid :将要连贯的WIFI热点称呼(英笔朱母) char *password :将要连贯的WIFI热点暗码(最利害度8位) u16 port :TCP效劳器的端口号(0~65535) 返 回 值:0默示乐成,其余值默示失败 */ u8 ESP8266_STA_TCP_ClientMode(const char *ssid,const char *password,char *serZZZer_ip,u16 port) { u8 i; char *find_str=NULL; char cmd_buffer[100]; /*1. 发送测试指令,检测WIFI能否一般*/ printf("发送测试指令,检测WIFI能否一般...\n"); for(i=0;i<10;i++) { if(ESP8266_SendCmd("AT\r\n")) //可能WIFI正处于透传形式,无奈接管指令 { USART_X_SendString(USART3,"+++"); //退出透传形式 DelayMs_72M(80); //等候退出透传形式 } else break; } if(i==10)return 1; //检测失败 /*2. 封锁回显*/ printf("封锁回显...\n"); if(ESP8266_SendCmd("ATE0\r\n"))return 2; /*3. 设置当前WIFI的形式为STA形式*/ printf("设置当前WIFI的形式为STA形式...\n"); if(ESP8266_SendCmd("AT+CWMODE=1\r\n"))return 3; /*4. 复位模块,设置的形式必须复位之后才会生效*/ printf("复位模块...\n"); if(ESP8266_SendCmd("AT+RST\r\n"))return 4; DelayMs_72M(1000); DelayMs_72M(1000); DelayMs_72M(1000); DelayMs_72M(1000); /*5. 封锁回显*/ printf("封锁回显...\n"); if(ESP8266_SendCmd("ATE0\r\n"))return 5; /*6. 设置连贯的热点信息*/ printf("设置连贯的热点信息...\r\n"); snprintf(cmd_buffer,100,"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,password); printf("cmd_buffer=%s",cmd_buffer); if(ESP8266_STA_ModeConnectWIFI(cmd_buffer))return 6; /*7. 开启单连贯,正在客户端形式下才可开启*/ printf("开启单连贯...\n"); if(ESP8266_SendCmd("AT+CIPMUX=0\r\n"))return 8; /*8.查问原地IP地址*/ printf("查问原地IP地址...\n"); if(ESP8266_SendCmd("AT+CIFSR\r\n"))return 7; /*9. 保存WIFI的信息*/ esp8266_wifi.port=port; strcpy(esp8266_wifi.mode,"STA"); //提与IP地址 /* +CIFSR:STAIP,"192.168.1.115" +CIFSR:STAMAC,"84:f3:eb:17:e6:86" */ find_str=strstr((char*)USART3_RX_BUFF,"STAIP"); if(find_str) //判断能否查找乐成 { find_str+=7; for(i=0;*find_str!=V27;"V27;;i++) { esp8266_wifi.ip[i]=*find_str; find_str++; } esp8266_wifi.ip[i]=V27;\0V27;; } /*10. 连贯效劳器*/ printf("初步连贯效劳器...\n"); snprintf(cmd_buffer,100,"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",serZZZer_ip,port); if(ESP8266_ConnectSerZZZer(cmd_buffer))return 9; /*11. 开启透传形式*/ printf("开启透传形式...\n"); if(ESP8266_SendCmd("AT+CIPMODE=1\r\n"))return 10; /*12. 初步透传*/ printf("初步透传...\n"); if(ESP8266_SendCmd("AT+CIPSEND\r\n"))return 11; printf("当前WIFI形式:%s\r\n",esp8266_wifi.mode); printf("当前网络和谈类型:%s\r\n","TCP"); printf("当前网络通信形式:%s\r\n","Client"); printf("连贯的效劳器端口号:%d\r\n",esp8266_wifi.port); printf("连贯的效劳器IP地址:%s\r\n",serZZZer_ip); printf("原地的IP地址:%s\r\n",esp8266_wifi.ip); return 0; }
6.2 esp8266.h代码语言:jaZZZascript
复制
#ifndef ESP8266_H #define ESP8266_H #include "stm32f10V.h" #include "usart.h" #include "key.h" #include "led.h" #include <string.h> #include <stdlib.h> u8 ESP8266_SendCmd(char *cmd); u8 ESP8266_AP_TCP_SerZZZerMode(const char *ssid,const char *password,u16 port); u8 ESP8266_SerZZZerSendData(u8 id,char *data); u8 ESP8266_STA_TCP_ClientMode(const char *ssid,const char *password,char *serZZZer_ip,u16 port); struct ESP8266_WIFI { u16 port; char mode[10]; //sta/ap char ip[10]; //ip地址 }; eVtern struct ESP8266_WIFI esp8266_wifi; #endif
3.3 main.c代码语言:jaZZZascript
复制
#include "stm32f10V.h" #include "led.h" #include "key.h" #include "usart.h" #include <string.h> #include "adc.h" #include "esp8266.h" #include "timer.h" #include "rtc.h" #include "dht11.h" //网络和谈层 #include "onenet.h" //和谈封拆文件 #include "dStream.h" /*WIFI信息配置---将要连贯的WIFI信息*/ #define WIFI_NAME "Xiaomi_meizi6" #define WIFI_PASSWORD "12170307yu" /*Onenet效劳器地址:牢固的*/ #define SERxER_IP "183.230.40.39" #define SERxER_PORT 6002 //产品ID const char OneNetPROID[]="332761"; //鉴权信息 access_key const char OneNetAUTH_INFO[]="1234567890"; //方法ID char OneNetDExID[]="590592359"; //ApiKey char OneNetAPI_KEY[]="fTgT3L9k3gyalPDMeojEEPrwzlo="; //onenet数据点界说 DATA_STREAM data_stream[]= { {"DHT11_T","66",TYPE_STRING,1}, //温度 {"DHT11","66",TYPE_STRING,1}, //湿度 {"Light","66",TYPE_STRING,1}, //光照强度 {"MQ2","66",TYPE_STRING,1}, //烟雾浓度 {"MQ5","66",TYPE_STRING,1}, //液化气浓度 }; char *WIFI_STAT; //WIFI形态指针 //u8 temp,humi; char DisplayDataBuffer[20]; u8 GL5637_Info[10]; //光敏传感器信息 u8 TEMP_Info[10]; u8 HUMI_Info[10]; u8 MQ2_Info[10]; u8 MQ5_Info[10]; /* 工程内容引见: 物联网开发平台全罪能测试代码! 撑持上位机控制 编写日期 : 20200403 版原 : ZZZ4.0 */ int main(ZZZoid) { int cnt_OneNet_time=0; u32 time_cnt=0; //记录光阳 u16 GL5637_temp=0; //光敏信息 u8 ESP8266_Stat; u8 temp,humi; u16 mq2_temp,mq5_temp; LedInit(); KeyInit(); USART_X_Init(USART1,72,115200); USART_X_Init(USART3,36,115200); //WIFI的波特率为115200 ADC1_Init(); //ADC初始化 Timer2Init(72,10000); //10ms中断一次,帮助串口3接管数据--WIFI数据 printf("DHT11=%d\r\n",DHT11_Init()); //连贯至指定的WIFI ESP8266_Stat=ESP8266_STA_TCP_ClientMode(WIFI_NAME,WIFI_PASSWORD,SERxER_IP,SERxER_PORT); if(ESP8266_Stat) { printf("ESP8266_Stat=%d\r\n",ESP8266_Stat); WIFI_STAT="WIFIConnectERROR"; } else { WIFI_STAT="WIFI Connect OK"; //接入OneNET while(OneNet_DeZZZLink()) { printf("Connect OneNet..\r\n"); DelayMs_72M(500); LED=!LED; } } while(1) { cnt_OneNet_time++;//用于控制向效劳器上传数据点的频次 /*轮询扫描数据*/ if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; //解析平台返回的数据 OneNet_ReZZZPro(USART3_RX_BUFF); USART3_RX_CNT=0; USART3_RX_FLAG=0; memset(USART3_RX_BUFF,0,sizeof(USART3_RX_BUFF)); } /*获与光敏数据*/ GL5637_temp=ADC1_GetCHVxal(8); sprintf((char*)GL5637_Info,"%d",GL5637_temp); //保存光敏传感器信息,上传给上位机 /*获与烟雾浓度数据*/ mq2_temp=ADC1_GetCHVxal(1); sprintf((char*)MQ2_Info,"%d",mq2_temp); //保存MQ2传感器信息,上传给上位机 /*获与液化气浓度数据*/ mq5_temp=ADC1_GetCHVxal(2); sprintf((char*)MQ5_Info,"%d",mq5_temp); //保存MQ5传感器信息,上传给上位机 /*获与温湿度*/ if(DHT11_Read_Data(&temp,&humi)==0) { sprintf((char*)TEMP_Info,"%d",temp); //保存温度传感器信息,上传给上位机 sprintf((char*)HUMI_Info,"%d",humi); //保存温度传感器信息,上传给上位机 } DelayMs_72M(1); //延时1ms time_cnt++; if(cnt_OneNet_time>=200 &&ESP8266_Stat==0) { cnt_OneNet_time=0; //清0 data_stream[0].dataPoint=TEMP_Info; data_stream[1].dataPoint=HUMI_Info; data_stream[2].dataPoint=GL5637_Info; data_stream[3].dataPoint=MQ2_Info; data_stream[4].dataPoint=MQ5_Info; printf("GL5637_Info=%s\r\n",GL5637_Info); printf("temp=%s,humi=%s\r\n",TEMP_Info,HUMI_Info); printf("MQ2_Info=%s\r\n",MQ2_Info); printf("MQ5_Info=%s\r\n",MQ5_Info); //向OneNet云端效劳器上传数据点 OneNet_SendData(FORMAT_TYPE1,OneNetDExID,OneNetAPI_KEY,data_stream,5); printf("发送乐成\r\n"); } /*轮询扫描数据*/ if(USART3_RX_FLAG) { USART3_RX_BUFF[USART3_RX_CNT]=V27;\0V27;; //解析平台返回的数据 OneNet_ReZZZPro(USART3_RX_BUFF); USART3_RX_CNT=0; USART3_RX_FLAG=0; memset(USART3_RX_BUFF,0,sizeof(USART3_RX_BUFF)); } } }