本文正在参加星光计划3.0–夏日挑战赛
1. 前言
智能系统作为新兴产业,是国家重点发展产业之一。国外自美国在1984年建设出真正的智能建筑至今为止已经有30多年的历史了。由于智能家居的安全、高效、便捷以,及智能化等独特魅力,使智能家居行业在2003年逐步进入我国的家居市场,但是由于我国起步晚,使得智能家居行业标准在我国家居市场上并不统一。随着全球资源的不断减少以及环境的破坏,“节能环保”成为了全球科技发展的首要要求,而“全球智能化”在节能环保方面的优势使得智能家居成为了发展主流,因此具有十分广阔的市场前景。同时,随着科技的进步,传统建筑已经不能满足现代人对生活方面舒适度的需求,而智能系统也在不知不觉间渗入我们的生活。
智能家居(smart home)以住宅为平台,利用嵌入式单片机为核心控制器来实现无 线通信、安全防范及自动控制技术的智能家居环境的系统集成,用以实现对智能家居 环境的远程安防监控,环境监测以及各个子系统的控制,构建了高效智能的住宅设施 与家庭安全的管理系统,家居智能性、安全性,便利性和舒适性等都有显著提高,有效的提高了人们生活品质。
智能家居不仅提供舒适宜人且高品位的家庭生活空间,实现更智能的家庭安防系统;还将家居环境由原来的被动静止结构转变为具有能动智慧的工具,提供全方位的信息交互功能。物联网中的无线传感器应用对家庭的智能防灾,灯光控制,以及家电联网都提供了一种很好的解决办法。而且使用GPRS通信模块,可以将家庭中的突发事件信息告知户主,并且进行智能报警。这样就极大降低了家庭意外灾难的损失。
本次设计结合现代生活的具体需求,设计出一套基于华为云IOT设计的云平台监控系统,可以远程实时查看家里光照强度、温湿度等信息,支持在云端控制家里的电器设备,实现远程控制。
2. 具体需求
主要实现对光照强度、温湿度等信息的实时监测,将相关信息、设备状态信息等实时显示,通过ESP8266wifi模块进行联网可实现远程数据传输,利用华为云IOT物联网云平台,MQTT传输协议,调用华为云IOT平台提供的接口设计上位机实现远程控制显示。
硬件选项要求:
(1)ESP8266 串口WIFI,用来与OneNet进行远程通信。
(2)DHT11 温度传感器,检测本地环境的温度湿度信息。
(3)继电器,来模拟控制家里的电器。
(4)BH1750 光敏传感器,检测环境光强度
(5)MQ135 空气质量传感器。可以检测可燃气体、烟雾浓度,实现火警预警。
(6)OLED显示屏显示本地的传感器的参数情况,实时展示









3. 硬件选型
3.1 继电器

3.2 ESP8266 WIFI
(1)模块采用串口(LVTTL)与MCU(或其他串口设备)通信,内置TCP/IP协议栈,能够实现串口与WIFI之间的转换
(2)模块支持LVTTL串口,兼容3.3V和5V单片机系统
(3)模块支持串口转WIFI STA、串口转AP和WIFI STA+WIFIAP的模式,从而快速构建串口-WIFI数据传输方案

3.3 MQ-135空气质量传感器
MQ135传感器对氨气、硫化物、苯系蒸汽的灵敏度高,对烟雾和其它有害的监测也很理想。这种传感器可检测多种有害气体,是一款适合多种应用的低成本传感器。



3.4 DHT11温湿度传感器
DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有可靠性与卓越的长期稳定性,成本低、相对湿度和温度测量、快响应、抗干扰能力强、信号传输距离长、数字信号输出、精确校准。传感器包括一个电容式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。可用于暖通空调、除湿器、测试及检测设备、消费品、汽车、自动控制、数据记录器、气象站、家电、湿度调节器、医疗、其他相关湿度检测控制。
特点如下:
1、可以检测周围环境的湿度
2、可以检测周围环境的温度
3、湿度测量范围:20%-95%(0度-50度范围)湿度测量误差:±5%4、温度测量范围:o度-50度温度测量误差:±2度
4、工作电压3.3V-5V
5、输出形式数字输出


3.5 STM32系统板
主控CPU采用STM32F103RCT6,这颗芯片包括48 KB SRAM、256 KB Flash、2个基本定时器、4个通用定时器、2个高级定时器、51个通用IO口、5个串口、2个DMA控制器、3个SPI、2个I2C、1个USB、1个CAN、3个12位ADC、1个12位DAC、1个SDIO接口,芯片属于大容量类型,配置较高,整体符合硬件选型设计。当前选择的这款开发板自带了一个1.4寸的TFT-LCD彩屏,可以显示当前传感器数据以及一些运行状态信息。

3.6 OLED显示屏

特点:
3.7 母对母杜邦线

3.8 BH1750光敏传感器

4. 登录华为云创建云端产品与设备
4.1 创建产品
华为运官网: https://www.huaweicloud.com/




我们设备接入的协议选择MQTT,端口对应是1883
接下来继续创建产品,点击产品页面,点击右上角创建产品:



4.2 创建设备


4.3 产品模型定义
这一步就是设置上报设备的属性,也就是设备的数据类型定义。




4.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/

4.5 使用MQTT客户端软件登录
所有的参数已经得到,接下来采用MQTT客户端登录华为云进行测试。
下面这个软件是自己开发的,为了方便测试MQTT协议登录。
华为云物联网平台的域名是: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
华为云物联网平台的IP地址是: 121.36.42.100


4.6 上报数据
官方文档: https://support.huaweicloud.com/devg-iothub/iot_01_2127.html#ZH-CN_TOPIC_0240834853__zh-cn_topic_0251997880_li365284516112
在这个文档里介绍了MQTT上报数据的格式。



总结的格式:

5. STM32设备端代码
串口上会输出当前程序运行的状态信息,可以打开串口调试助手查看。

5.1 LCD汉字取模
LCD上需要显示汉字,使用点阵字模取模软件进行取模。

5.2 硬件连线

5.2 keil工程布局
工程Get地址: https://download.csdn.net/download/xiaolong1126626497/81993720


5.3 main.c代码
MQTT协议连接华为云IOT源码工程参考: https://download.csdn.net/download/xiaolong1126626497/81993720
#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 "motor.h"
#include "oled.h"
#include "dht11.h"
#include "adc.h"
#include <string.h>
#include <stdlib.h>
#include "font.h"
#include "mqtt.h"
#include "iic.h"
#include "bh1750.h"
#define MQTT_ClientID "61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510"
#define MQTT_UserName "61b9ba3a2b2aa20288c1e7f1_QQ1126626497"
#define MQTT_PassWord "385ce91dfe7da5b7431868d5d87e7998163c493344040935d5a00024d6324242"
#define SET_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/messages/down"
#define POST_TOPIC "$oc/devices/61b9ba3a2b2aa20288c1e7f1_QQ1126626497_0_0_2021121510/sys/properties/report"
#define CONNECT_WIFI "Xiaomi_meizi6"
#define CONNECT_PASS "12170307yu"
#define CONNECT_SERVER_IP "121.36.42.100"
#define CONNECT_SERVER_PORT 1883
#define JTAG_SWD_DISABLE 0X02
#define SWD_ENABLE 0X01
#define JTAG_SWD_ENABLE 0X00
void JTAG_Set(u8 mode)
{
u32 temp;
temp=mode;
temp<<=25;
RCC->APB2ENR|=1<<0;
AFIO->MAPR&=0XF8FFFFFF;
AFIO->MAPR|=temp;
}
u8 motor_flag=0;
u8 led_flag=0;
u16 MQ135_data=0;
u8 DHT11_T=0;
u8 DHT11_H=0;
u8 BH1750_data=0;
char request_id[100];
char mqtt_message[100];
char data_buff[300];
int main()
{
u8 esp8266_state=0;
u8 key;
u8 i;
u32 time_cnt=0;
u32 timer_hour_cnt=0;
JTAG_Set(JTAG_SWD_DISABLE);
LED_Init();
KEY_Init();
USART1_Init(115200);
Moto_Init();
USART2_Init(115200);
TIMER2_Init(72,20000);
DHT11_Init();
Lcd_Init();
Lcd_Clear(0);
LCD_LED_SET;
AdcInit();
IIC_Init();
printf("正在初始化WIFI请稍等.\r\n");
for(i=0;i<5;i++)
{
if(ESP8266_Init()==0)
{
esp8266_state=1;
break;
}
else
{
esp8266_state=0;
printf("ESP8266硬件检测错误.\n");
}
}
if(esp8266_state)
{
printf("准备连接服务器....\r\n");
printf("WIFI:%d\n",ESP8266_STA_TCP_Client_Mode(CONNECT_WIFI,CONNECT_PASS,CONNECT_SERVER_IP,CONNECT_SERVER_PORT,1));
MQTT_Init();
for(i=0;i<5;i++)
{
if(MQTT_Connect(MQTT_ClientID,MQTT_UserName,MQTT_PassWord)==0)
{
esp8266_state=1;
break;
}
esp8266_state=0;
printf("服务器连接失败,正在重试...\n");
delay_ms(500);
}
printf("服务器连接成功.\n");
if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
{
printf("主题订阅失败.\n");
}
else
{
printf("主题订阅成功.\n");
}
}
LCD_ShowChineseFont(0,0,16,HZ_FONT_16[0],RED,0);
LCD_ShowChineseFont(16*1,0,16,HZ_FONT_16[1],RED,0);
LCD_ShowChineseFont(16*2,0,16,HZ_FONT_16[2],RED,0);
LCD_ShowChineseFont(16*3,0,16,HZ_FONT_16[3],RED,0);
LCD_ShowChineseFont(0,16*1,16,HZ_FONT_16[4],RED,0);
LCD_ShowChineseFont(16*1,16*1,16,HZ_FONT_16[5],RED,0);
LCD_ShowChineseFont(16*2,16*1,16,HZ_FONT_16[6],RED,0);
LCD_ShowChineseFont(16*3,16*1,16,HZ_FONT_16[7],RED,0);
LCD_ShowChineseFont(0,16*2,16,HZ_FONT_16[8],RED,0);
LCD_ShowChineseFont(16,16*2,16,HZ_FONT_16[9],RED,0);
LCD_ShowChineseFont(16*2,16*2,16,HZ_FONT_16[10],RED,0);
LCD_ShowChineseFont(16*3,16*2,16,HZ_FONT_16[11],RED,0);
LCD_ShowChineseFont(0,16*3,16,HZ_FONT_16[12],RED,0);
LCD_ShowChineseFont(16,16*3,16,HZ_FONT_16[13],RED,0);
LCD_ShowChineseFont(16*2,16*3,16,HZ_FONT_16[14],RED,0);
LCD_ShowChineseFont(16*3,16*3,16,HZ_FONT_16[15],RED,0);
LCD_ShowChineseFont(0,16*4,16,HZ_FONT_16[16],RED,0);
LCD_ShowChineseFont(16,16*4,16,HZ_FONT_16[17],RED,0);
LCD_ShowChineseFont(16*2,16*4,16,HZ_FONT_16[18],RED,0);
LCD_ShowChineseFont(16*3,16*4,16,HZ_FONT_16[19],RED,0);
LCD_ShowChineseFont(0,16*5,16,HZ_FONT_16[20],RED,0);
LCD_ShowChineseFont(16,16*5,16,HZ_FONT_16[21],RED,0);
LCD_ShowChineseFont(16*2,16*5,16,HZ_FONT_16[22],RED,0);
LCD_ShowChineseFont(16*3,16*5,16,HZ_FONT_16[23],RED,0);
while(1)
{
key=KEY_Scan();
if(key)printf("key=%d\r\n",key);
if(key==2)
{
led_flag=!led_flag;
if(led_flag)
{
LED_OUT=1;
}
else
{
LED_OUT=0;
}
}
if(key==1)
{
motor_flag=!motor_flag;
if(motor_flag)
{
MOTOR_OUT=1;
}
else
{
MOTOR_OUT=0;
}
}
if(time_cnt>=100)
{
time_cnt=0;
LED1=!LED1;
BH1750_data=Read_BH1750_Data();
printf("环境光强度:%d\r\n",BH1750_data);
if(DHT11_Read_Data(&DHT11_T,&DHT11_H))
{
printf("温度读取失败.\r\n");
}
printf("环境温度:%d\r\n环境湿度:%d\r\n",DHT11_T,DHT11_H);
MQ135_data=GetAdcCHxDATA(1);
printf("空气质量:%d\r\n",MQ135_data);
sprintf(data_buff,"%d",DHT11_T);
Gui_DrawFont_GBK16(72,16*0,RED,0,(u8*)data_buff);
sprintf(data_buff,"%d",DHT11_H);
Gui_DrawFont_GBK16(72,16*1,RED,0,(u8*)" ");
Gui_DrawFont_GBK16(72,16*1,RED,0,(u8*)data_buff);
sprintf(data_buff,"%d",BH1750_data);
Gui_DrawFont_GBK16(72,16*2,RED,0,(u8*)" ");
Gui_DrawFont_GBK16(72,16*2,RED,0,(u8*)data_buff);
sprintf(data_buff,"%d",MQ135_data);
Gui_DrawFont_GBK16(72,16*3,RED,0,(u8*)" ");
Gui_DrawFont_GBK16(72,16*3,RED,0,(u8*)data_buff);
sprintf(data_buff,"%d",led_flag);
Gui_DrawFont_GBK16(72,16*4,RED,0,(u8*)" ");
Gui_DrawFont_GBK16(72,16*4,RED,0,(u8*)data_buff);
sprintf(data_buff,"%d",motor_flag);
Gui_DrawFont_GBK16(72,16*5,RED,0,(u8*)" ");
Gui_DrawFont_GBK16(72,16*5,RED,0,(u8*)data_buff);
sprintf(data_buff,"{\"services\":{\"BH1750\":[{\"v\":%d}],\"DHT11_H\":[{\"v\":%d}],\"DHT11_T\":[{\"v\":%d}],\"MQ135\":[{\"v\":%d}],\"motor\":[{\"v\":%d}],\"LED\":[{\"v\":%d}]}}",
BH1750_data,DHT11_H,DHT11_T,MQ135_data,motor_flag,led_flag);
MQTT_PublishData(POST_TOPIC,data_buff,0);
printf("更新数据.\r\n");
}
if(USART2_RX_FLAG)
{
USART2_RX_BUFFER[USART2_RX_CNT]='\0';
printf("WIFI收到数据:\r\n");
for(i=0;i<USART2_RX_CNT;i++)
{
printf("%c",USART2_RX_BUFFER[i]);
}
if(USART2_RX_CNT>5)
{
if(strstr((char*)&USART2_RX_BUFFER[5],"cmd/request/"))
{
char *p=NULL;
p=strstr((char*)&USART2_RX_BUFFER[5],"cmd/request/");
if(p)
{
strncpy(request_id,p+12,36);
}
sprintf(mqtt_message,"success");
sprintf(data_buff,"$sys/501579/dev1/cmd/response/%s",request_id);
MQTT_PublishData(data_buff,mqtt_message,0);
printf("发布主题:%s\r\n",data_buff);
printf("发布数据:%s\r\n",mqtt_message);
}
if(strstr((char*)&USART2_RX_BUFFER[5],"LED:0"))
{
LED_OUT=0;
led_flag=0;
}
else if(strstr((char*)&USART2_RX_BUFFER[5],"LED:1"))
{
LED_OUT=1;
led_flag=1;
}
else if(strstr((char*)&USART2_RX_BUFFER[5],"MOTOR:0"))
{
MOTOR_OUT=0;
motor_flag=0;
}
else if(strstr((char*)&USART2_RX_BUFFER[5],"MOTOR:1"))
{
MOTOR_OUT=1;
motor_flag=1;
}
}
USART2_RX_CNT=0;
USART2_RX_FLAG=0;
}
DelayMs(10);
time_cnt++;
timer_hour_cnt++;
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
如果需要整个工程源码的话,评论区留下邮箱即可。