丈夫志四海,万里犹比邻。这篇文章主要讲述#yyds干货盘点# 基于STM32+ESP8266+华为云设计的智能家居控制系统相关的知识,希望能为你提供帮助。
1. 功能介绍这是基于华为云物联网平台设计智能家居控制系统(模型),硬件采用STM32+ESP8266完成上云组合;通过云平台可以远程控制家里的各种电器开关,并且可以远程收集家里煤气、天然气、烟雾、光照度、温度湿度等信息。
硬件介绍:
主控MCU:STM32F103ZET6
烟雾检测传感器: MQ2
天然气检测传感:MQ5
温度湿度检测传感器: DHT11
光照强度检测传感器:BH1750
物联网云平台: 华为云物联网平台
电器开关模拟采用板载的LED灯、继电器。
【#yyds干货盘点# 基于STM32+ESP8266+华为云设计的智能家居控制系统】WIFI:ESP8266
这是支持串口AT指令控制的WIFI模块,联网比较方便。
与华为云物联网平台通信的协议: MQTT
2. 登录华为云创建云端设备
2.1 创建产品
华为运官网: https://www.huaweicloud.com/
文章图片
文章图片
文章图片
在这里可以查看接入的协议的端口号和地址。
文章图片
文章图片
MQTT (1883) a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
我们设备接入的协议选择MQTT,端口对应是1883
接下来继续创建产品,点击产品页面,点击右上角创建产品:
文章图片
文章图片
文章图片
2.2 创建设备
文章图片
文章图片
这是我的设备信息:
设备ID
61a580fad28ce3028832c2d8_esp8266_iot设备密钥
1126626497"device_id": "61a580fad28ce3028832c2d8_esp8266_iot",
"secret": "1126626497"
2.3 产品模型定义
这一步就是设置上报设备的属性,也就是设备的数据类型定义。
文章图片
文章图片
文章图片
文章图片
2.4 生成MQTT登录密匙
创建完产品、设备之后,接下来就需要知道如何通过MQTT协议登陆华为云服务器。
官方的详细介绍在这里: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112
文章图片
文章图片
MQTT设备登陆密匙生成地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/
文章图片
下面就得到了MQTT协议设备登录的参数。
2.5 使用MQTT客户端软件登录
所有的参数已经得到,接下来采用MQTT客户端登录华为云进行测试。
下面这个软件是自己开发的,为了方便测试MQTT协议登录。
华为云物联网平台的域名是:
a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
华为云物联网平台的IP地址是:
121.36.42.100
文章图片
在软件里参数填充正确之后,就看到设备已经连接成功了。
接下来打开设备页面,可以看到设备已经在线了。
文章图片
2.6 上报数据
官方文档: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112
在这个文档里介绍了MQTT上报数据的格式。
文章图片
文章图片
文章图片
总结的格式:
//订阅主题: 平台下发消息给设备
$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/messages/down//设备上报数据
$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/properties/report//上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
"services": ["service_id": "dht11","properties":"DHT11-C":50]
下面采用MQTT软件上报数据:
文章图片
文章图片
到此,设备数据已经上报成功,如果需要增加更多的属性,按照流程继续增加即可。
3. STM32+ESP8266上报数据到华为云 3.1 硬件设备效果图
文章图片
文章图片
3.2 BH1750.c光照度传感器
#include "bh1750.h"
float Read_BH1750_Data()unsigned char t0;
unsigned char t1;
float t;
u8 r_s=0;
IIC_Start();
//发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:1\\r\\n");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:2\\r\\n");
IIC_Stop();
//停止信号 IIC_Start();
//发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:3\\r\\n");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:4\\r\\n");
IIC_Stop();
//停止信号 IIC_Start();
//发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:5\\r\\n");
IIC_WriteOneByteData(0x10);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:6\\r\\n");
IIC_Stop();
//停止信号 DelayMs(300);
//等待IIC_Start();
//发送起始信号
IIC_WriteOneByteData(0x47);
r_s=IIC_GetACK();
//获取应答
if(r_s)printf("error:7\\r\\n");
t0=IIC_ReadOneByteData();
//接收数据
IIC_SendACK(0);
//发送应答信号
t1=IIC_ReadOneByteData();
//接收数据
IIC_SendACK(1);
//发送非应答信号
IIC_Stop();
//停止信号t=(((t0<
<
8)|t1)/1.2);
return t;
3.3 ESP8266.cWIFI代码
#include "esp8266.h"
u8 ESP8266_IP_ADDR[16];
//255.255.255.255
u8 ESP8266_MAC_ADDR[18];
//硬件地址
/*
函数功能: ESP8266命令发送函数
函数返回值:0表示成功1表示失败
*/
u8 ESP8266_SendCmd(char *cmd)u8 i,j;
for(i=0;
i<
10;
i++) //检测的次数--发送指令的次数USARTx_StringSend(USART3,cmd);
for(j=0;
j<
100;
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,"OK"))return 0;
return 1;
/*
函数功能: ESP8266硬件初始化检测函数
函数返回值:0表示成功1表示失败
*/
u8 ESP8266_Init(void)//退出透传模式
USARTx_StringSend(USART3,"+++");
delay_ms(50);
return ESP8266_SendCmd("AT\\r\\n");
/*
函数功能: TCP服务器模式下的发送函数
发送指令:
*/
u8 ESP8266_ServerSendData(u8 id,u8 *data,u16 len)u8 i,j,n;
char ESP8266_SendCMD[100];
//组合发送过程中的命令
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,">
"))//继续发送数据
USARTx_DataSend(USART3,data,len);
//等待数据发送成功
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;
/*
函数功能: 配置WIFI为STA模式+TCP客户端模式
函数参数:
char *ssid创建的热点名称
char *pass创建的热点密码 (最少8位)
char *p将要连接的服务器IP地址
u16 port将要连接的服务器端口号
u8 flag1表示开启透传模式 0表示关闭透传模式
函数返回值:0表示成功其他值表示对应的错误
*/
u8 ESP8266_STA_TCP_Client_Mode(char *ssid,char *pass,char *ip,u16 port,u8 flag)char ESP8266_SendCMD[100];
//组合发送过程中的命令
//退出透传模式
//USARTx_StringSend(USART3,"+++");
//delay_ms(50);
/*1. 测试硬件*/
if(ESP8266_SendCmd("AT\\r\\n"))return 1;
/*2. 关闭回显*/
if(ESP8266_SendCmd("ATE0\\r\\n"))return 2;
/*3. 设置WIFI模式*/
if(ESP8266_SendCmd("AT+CWMODE=1\\r\\n"))return 3;
/*4. 复位*/
ESP8266_SendCmd("AT+RST\\r\\n");
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
/*5. 关闭回显*/
if(ESP8266_SendCmd("ATE0\\r\\n"))return 5;
/*6. 配置将要连接的WIFI热点信息*/
sprintf(ESP8266_SendCMD,"AT+CWJAP=\\"%s\\",\\"%s\\"\\r\\n",ssid,pass);
if(ESP8266_SendCmd(ESP8266_SendCMD))return 6;
/*7. 设置单连接*/
if(ESP8266_SendCmd("AT+CIPMUX=0\\r\\n"))return 7;
/*8. 配置要连接的TCP服务器信息*/
sprintf(ESP8266_SendCMD,"AT+CIPSTART=\\"TCP\\",\\"%s\\",%d\\r\\n",ip,port);
if(ESP8266_SendCmd(ESP8266_SendCMD))return 8;
/*9. 开启透传模式*/
if(flag)if(ESP8266_SendCmd("AT+CIPMODE=1\\r\\n"))return 9;
//开启
if(ESP8266_SendCmd("AT+CIPSEND\\r\\n"))return 10;
//开始透传
if(!(strstr((char*)USART3_RX_BUFFER,">
")))return 11;
//如果想要退出发送:"+++"//打印总体信息
USART1_Printf("WIFI模式:STA+TCP客户端\\n");
USART1_Printf("Connect_WIFI热点名称:%s\\n",ssid);
USART1_Printf("Connect_WIFI热点密码:%s\\n",pass);
USART1_Printf("TCP服务器端口号:%d\\n",port);
USART1_Printf("TCP服务器IP地址:%s\\n",ip);
return 0;
/*
函数功能: TCP客户端模式下的发送函数
发送指令:
*/
u8 ESP8266_ClientSendData(u8 *data,u16 len)u8 i,j,n;
char ESP8266_SendCMD[100];
//组合发送过程中的命令
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,">
"))//继续发送数据
USARTx_DataSend(USART3,data,len);
//等待数据发送成功
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主函数
#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"//将要连接的路由器名称 --不要出现中文、空格等特殊字符
#define ESP8266_AP_PASSWORD "99pu58cb"//将要连接的路由器密码//华为云服务器的设备信息
#define MQTT_ClientID "61a580fad28ce3028832c2d8_esp8266_iot_0_0_2021113002"
#define MQTT_UserName "61a580fad28ce3028832c2d8_esp8266_iot"
#define MQTT_PassWord "74af3bf3024cf9c41b13d6c63fc86e25012b54141ecfcdff3516f08665140e6f"//订阅与发布的主题
#define SET_TOPIC"$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/messages/down"//订阅
#define POST_TOPIC "$oc/devices/61a580fad28ce3028832c2d8_esp8266_iot/sys/properties/report"//发布char mqtt_message[200];
//上报数据缓存区
char OLED_ShowBuff[100];
u8 ESP8266_Stat=0;
/*
函数功能: 温湿度\\光强度显示
*/
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);
/*
函数功能: ESP8266显示页面
*/
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");
//显示字符串
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初始化
OLED_Init(0xc8,0xa1);
//OLED显示屏初始化--正常显示;
//清屏
OLED_Clear(0);
USART1_Init(115200);
TIMER1_Init(72,20000);
//超时时间20msUSART3_Init(115200);
//串口-WIFI
TIMER3_Init(72,20000);
//超时时间20msInit_SHT30();
USART1_Printf("正在初始化WIFI请稍等.\\n");
if(ESP8266_Init())ESP8266_Stat=1;
USART1_Printf("ESP8266硬件检测错误.\\n");
else//非加密端口
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协议初始化
MQTT_Init();
//3. 连接华为云IOT服务器
while(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord))USART1_Printf("服务器连接失败,正在重试...\\n");
delay_ms(500);
USART1_Printf("服务器连接成功.\\n");
//3. 订阅主题
if(MQTT_SubscribeTopic(SET_TOPIC,0,1))USART1_Printf("主题订阅失败.\\n");
elseUSART1_Printf("主题订阅成功.\\n");
while(1)//按键可以测试
key=KEY_Scan(0);
if(key==1)//清屏
OLED_Clear(0);
//翻页
if(page>
=1)page=0;
elsepage++;
LED1=!LED1;
//LEd状态灯else if(key==2)LED1=!LED1;
//LEd状态灯
time_cnt=0;
//电机状态改变
MOTOR_DEV=!MOTOR_DEV;
//电机状态
motor_state=MOTOR_DEV;
//补光灯
LIGHT_DEV=!LIGHT_DEV;
//接收WIFI返回的数据
if(USART3_RX_FLAG)USART3_RX_BUFFER[USART3_RX_CNT]=\\0;
//向串口打印返回的数据
for(i=0;
i<
USART3_RX_CNT;
i++)USART1_Printf("%c",USART3_RX_BUFFER[i]);
USART3_RX_CNT=0;
USART3_RX_FLAG=0;
//定时与保持与华为云物联网的同步--1秒一次
delay_ms(10);
time_cnt++;
if(time_cnt==50)time_cnt=0;
//状态灯 --表示程序还活着
LED2=!LED2;
//读取光强度
light=Read_BH1750_Data();
//读取温湿度
SHT3x_ReadData(&
Humidity,&
Temperature);
humi=Humidity;
temp=Temperature;
//上传数据--温度
sprintf(mqtt_message,"\\"services\\": [\\"service_id\\": \\"dht11\\",\\"properties\\":\\"DHT11-C\\":%d]",temp);
MQTT_PublishData(POST_TOPIC,mqtt_message,0);
//根据湿度自动灌溉
if(humi<
50.0)//小于50自动灌溉motor_state=1;
//电机状态更新
MOTOR_DEV=1;
//开电机//OLED显示屏
if(page==0)ShowTemperatureAndHumidity(temp,humi,light);
else if(page==1)ESP8266_ShowPageTable();
项目源码:https://download.csdn.net/download/xiaolong1126626497/81993720
推荐阅读
- HarmonyOS-基于canvas绘制复古钟表
- #yyds干货盘点# 超全面Git知识总结!
- XtraBackup实现MySQL数据库全量+增量+Binlog恢复库
- MyCAT实现MySQL数据库读写分离
- 在linux中如果查看进程,不懂得点进来吧!另外附加了如何静态启动进程!
- Kubernetes集群实践-排错(01)Node节点证书过期
- 花式营销不奏效(一文助您轻松读懂海量用户)
- WGCLOUD支持监测虚拟机云主机吗
- 常用的Linux服务器管理软件(轻量高效)——WGCLOUD