基于STM32设计的智能家居控制系统(华为云IOT+语音控制+环境检测)【玩转华为云】

举报
DS小龙哥 发表于 2022/06/19 13:32:31 2022/06/19
【摘要】 这是基于物联网设计的语音和环境检测的控制系统,支持本地语音控制、支持云端远程控制,支持本地环境检测自动执行控制,根据环境检测结果控制相应的执行机构协作当光照低于一定程度(比如低于5OLux)且有人在家里自动开灯,没人在家时自动关灯等等。

1. 前言

如今的智能家居越来越深入人心,越来越受人们的欢迎。智能家居作为与人们日常生活息息相关的科技智能产物,可以给我们的生活带来舒适便利。随着物联网、云计算、无线通信等新技术的发展,智能家居得到了快速发展,能让用户利用智能手机来控制家中的设备,实现远程控制、场景控制、联动控制和定时控制等功能。在安全防护上,智能家居安防系统则够在原来的基础上提供立体化防护,帮助用户时刻守护住宅安全,更符合人们的安全需求。节能减排方面的也有积极作用。比如说,智能家居照明系统,它充分利用了自然光的照明作用,自动调节灯具的亮度,在保证室内明亮度的同时,将能耗降到最低,而对于洗手间、储藏室等地方,更是做到了人来灯亮、人走灯灭,一方面方便了用户的日常生活,另一方面也能防止用户忘记及时关灯而造成浪费。

2. 设计要求总结

设计题目:基于物联网的语音和环境检测的智能家居控制系统设计

第一种:控制方式需经结合语音命令控制, 控制开关门、灯、电视、开关空调、开关电扇、开关窗帘等。

第二种:控制方式是基于环境检测自动执行控制,根据环境检测结果控制相应的执行机构协作,比如: 当光照低于一定程度(比如低于5OLux)且有人在家里自动开灯,没人在家时自动关灯;如温度高于阈值并且有人在家时打开空调,没人在家时自动关闭等;如光照强度低于一定程度会自动关闭窗帘。电脑和手机APP两端云平台可以展示温湿度,光照等信息,还有各家居的状态,可以在云平台控制家居的开关,可以在云平台进行两种控制方式的切换。

技术选项总结:

(1)物联网平台采用华为云IOT:华为云IOT是华为旗下的物联网开放平台。平台能够帮助开发者轻松实现设备接入与设备连接,快速完成产品开发部署,为智能硬件、智能家居产品提供完善的物联网解决方案。

(2)主控芯片采用:STM32F103C8T6

(3)语音控制芯片采用:LD3320 支持普通话识别。

(4)开关空调、开关风扇 采用继电器模拟:两个1路5V继电器控制

(5)开关窗帘采用步进电机模拟: 28BYJ4步进电机模拟

(6)室内照明灯(卧室、客厅):2盏 3W大功率LED灯模拟

(7)环境光检测检测:BH1750数字传感器

(8)联网的WIFI :选择ESP8266

(9)OLED屏幕:模拟电视显示

(11)温湿度检测:DHT11模块

其中:

(1)STM32主控芯片、语音控制芯片LD3320、室内照明大功率LED灯、环境光检测BH1750、ESP8266-WIFI 通过排母插在PCB板子上。

(2)步进电机UL2003驱动板、继电器 使用排针外接。

image.png

上位机运行效果:
image.png

3. 硬件选型

3.1 STM32F103C8T6

STM32F103C8T6是一款基于ARM Cortex-M 内核STM32系列的32位的微控制器,程序存储器容量是64KB,需要电压2V~3.6V,工作温度为-40°C ~ 85°C。
image.png

3.2 语音识别模块: LD3320

image.png

3.3 ESP8266 -串口WIFI

image.png

3.4 LED灯-RGB灯

image.png

3.5 3W大功率LED灯

image.png

3.6 OLED模块

image.png

3.7 步进电机模块

image.png

3.8 继电器模块

image.png

3.9 杜邦线(母对母)

image.png

3.10 红外寻迹/循迹模块

image.png

3.11 温湿度-DHT11

image.png

3.12 BH1750光敏传感器

image.png

4. 华为云创建产品与设备

4.1 创建产品、配置产品模型

华为云官网: https://www.huaweicloud.cn/
在产品选项框里找到华为云的IOT产品。选择设备接入 IoTDA

image.png

设备接入 IoTDA:

https://www.huaweicloud.cn/product/iothub.html

image.png

点击产品页面,先创建产品。产品一个项目的模型,产品下面可以创建多个具体的设备。

image.png

根据自己的实际产品信息填充。

image.png

创建成功。

image.png

查看产品的详情。

image.png

在详情页,创建产品的模型。这个产品的模型就是传感器数据的属性,根据自己上传的传感器数据实际创建。

image.png

创建自定义模型。

image.png

服务ID  SmartHome    服务类型  SmartHome    服务描述 智能家居

添加属性。

image.png

接来来根据自己设备的实际情况添加属性即可。

image.png

所有的属性创建完毕,属性的名字可以使用中文。但是要注意,设备上传时,中文数据的编码要正确,否则会乱码。

image.png

4.2 创建设备

接在在左边选项页面选择设备,创建一个设备。
设备可以调用API在程序里自动创建也可以的。

地址: https://console.huaweicloud.cn/iotdm/?region=cn-north-4#/dm-portal/device/all-device
image.png

单设备注册。
image.png

注册之后,保存设备信息,接下来生成MQTT参数需要。
image.png

{
    "device_id": "62aead8b538e623c4287ef43_Smart_home_dev_1",
    "secret": "12345678"
}

5. MQTT协议登录

5.1 MQTT服务器地址信息

华为云物联网平台的域名是: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com

华为云物联网平台的IP地址是: 121.36.42.100

端口号是  1883 

5.1 MQTT订阅主题,发布主题

帮助文档:https://support.huaweicloud.cn/iothub/index.html

image.png

格式: $oc/devices/{device_id}/sys/messages/down
//订阅主题: 平台下发消息给设备
$oc/devices/62aead8b538e623c4287ef43_Smart_home_dev_1/sys/messages/down

格式: $oc/devices/{device_id}/sys/properties/report
//设备上报数据
$oc/devices/62aead8b538e623c4287ef43_Smart_home_dev_1/sys/properties/report

上属性的数据格式:
//上报的属性消息 (一次可以上报多个属性,在json里增加就行了)
{"services": [{"service_id": "SmartHome","properties":{"空调":1}}]}

5.2 MQTT参数生成

设备创建完成接来下生成MQTT登录账号、密匙,方便设备登录云端平台。

官网工具地址: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

image.png

image.png

ClientId   62aead8b538e623c4287ef43_Smart_home_dev_1_0_0_2022061905
Username   62aead8b538e623c4287ef43_Smart_home_dev_1
Password   1052c27bd7ccce57b316005a677f50291cf4a50fc90e0bb1c33dee6beda1ae53

5.3 MQTT客户端模拟登录测试

MQTT客户端下载地址:

https://download.csdn.net/download/xiaolong1126626497/18784012

在MQTT工具里填上MQTT的登录参数,主题发布、订阅信息进行登录测试。

image.png

然后打开设备页面,可以看到设备已经在线了。

image.png

并且在设备页面详情里可以看到刚才上传的数据。

image.png

主题发布时,一次可以上传多个状态。

例如:

{"services": [{"service_id": "SmartHome","properties":{"空调":1,"风扇":1,"电视":0,"卧室灯":1}}]}

image.png

6. LD3320语音识别模块编程

image.png
下载程序示例。 将开发板的串口通过USB转TTL模块连接电脑即可。
image.png
波特率是9600,语音识别时,想要说小杰,唤醒语音识别,然后再说出指令,唤醒语音识别就,模块上有一个红色的LED灯会亮。
image.png
当前支持的指令如下:

小杰,开卧室灯
小杰,关卧室灯
小杰,开客厅灯
小杰,关客厅灯
小杰,打开电视
小杰,关闭电视
小杰,打开风扇
小杰,关闭风扇
小杰,打开窗帘
小杰,关闭窗帘
小杰,打开空调
小杰,关闭空调

image.png

7. STM32设备端开发

7.1 程序下载

image.png

7.2 原理图

image.png

7.3 硬件接线

本设计的硬件接线说明:1OLED显示屏接线:
D0----(SCK)------------------->>PB14
D1----(MOSI)------------------>>PB13
RES(复位脚低电平有效)-------->>PB12
DC--(数据和命令控制管脚)------>>PB1
CS--(片选引脚)---------------->>PA7
GND--------------------------->>GND
VCC--------------------------->>3.3V或者5V


(2ATK-ESP8266 WIFI接线
PA2(TX)--RXD 模块接收脚
PA3(RX)--TXD 模块发送脚
GND---GNDVCC---VCC 电源(3.3V~5.0V)


(3LD3320语音识别模块接线说明
GND----GND
VCC---3.3V
PB11----LD3320语音模块_TX
PB10----LD3320语音模块_RX


(4)开关空调:15V继电器控制
PA6------LED5)开关风扇:15V继电器控制
PA4------LED6)开关窗帘采用步进电机模拟: 28BYJ4步进电机模拟
ULN2003接线:
 IN-D: PB5   d
 IN-C: PB4   c
 IN-B: PB3   b
 IN-A: PB2   a
+  : 5V
-  : GND7)卧室照明灯:一盏3W大功率LED灯模拟
PB8------LED8)客厅照明灯:一盏3W大功率LED灯模拟
PB9------LED9)环境光检测检测:BH1750数字传感器
SDA-----PB7
SCL-----PB6
GND---GNDVCC---VCC 电源(3.3V~5.0V)


(10)温湿度传感器: DHT11
VCC--VCC
GND---GND
DAT---PA511)红外寻迹/循迹模块
VCC--3.3V
GND---GND
DAT---PA8--)板载LED:低电平亮
LED1--PC13  
BEEP2--PC14--)板载按键: 
KEY1--PA0  按下为高电平

7.4 核心代码

连接华为云服务器采用ESP8266WIFI,加上MQTT协议实现数据通信。标准的ESP8266本身不带MQTT协议栈,也就是说ESP8266默认是没有MQTT协议相关的指令,不能直接通过指令连接MQTT服务器通信,但是也可以自己烧写第三方的SDK,用于支持MQTT指令。 我这里的代码是自己实现的MQTT协议,包括我的其他物联网相关的文章里,只要用到ESP8266的都是自己写的MQTT协议,也就是在代码里实现了MQTT协议栈,使用ESP8266普通的TCP相关的指令就可以完成数据传输,不依赖于ESP8266的SDK版本,任何ESP8266都可以直接使用,为的就是方便移植,通用–通用-通用。

ESP82+STM32实现的MQTT协议栈工程在这里,如果需要带完整MQTT协议工程的可以去这里下载。
这份工程里实现了ESP8266与华为云IOT平台实现数据交互,数据通信,也就是登录、主题发布、订阅,心跳包等操作。
https://download.csdn.net/download/xiaolong1126626497/58012912

image.png

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <stdlib.h>
#include "timer.h"
#include "oled.h"
#include "fontdata.h"
#include "esp8266.h"
#include "app.h"
#include "mqtt.h"
#include "iic.h"
#include "bh1750.h"
#include "dht11.h"
#include "motor.h"

/*
本设计的硬件接线说明: 

(1)OLED显示屏接线:
D0----(SCK)------------------->>PB14
D1----(MOSI)------------------>>PB13
RES—(复位脚低电平有效)-------->>PB12
DC--(数据和命令控制管脚)------>>PB1
CS--(片选引脚)---------------->>PA7
GND--------------------------->>GND
VCC--------------------------->>3.3V或者5V


(2)ATK-ESP8266 WIFI接线
PA2(TX)--RXD 模块接收脚
PA3(RX)--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(3.3V~5.0V)


(3)LD3320语音识别模块接线说明
GND----GND
VCC---3.3V
PB11----LD3320语音模块_TX
PB10----LD3320语音模块_RX


(4)开关空调:1路5V继电器控制
PA6------LED

(5)开关风扇:1路5V继电器控制
PA4------LED

(6)开关窗帘采用步进电机模拟: 28BYJ4步进电机模拟
ULN2003接线:
 IN-D: PB5   d
 IN-C: PB4   c
 IN-B: PB3   b
 IN-A: PB2   a
+  : 5V
-  : GND

(7)卧室照明灯:一盏3W大功率LED灯模拟
PB8------LED

(8)客厅照明灯:一盏3W大功率LED灯模拟
PB9------LED

(9)环境光检测检测:BH1750数字传感器
SDA-----PB7
SCL-----PB6
GND---GND 地
VCC---VCC 电源(3.3V~5.0V)


(10)温湿度传感器: DHT11
VCC--VCC
GND---GND
DAT---PA5 

(11)红外寻迹/循迹模块
VCC--3.3V
GND---GND
DAT---PA8


(--)板载LED灯:低电平亮
LED1--PC13  
BEEP2--PC14

(--)板载按键: 
KEY1--PA0  按下为高电平

*/


//物联网服务器的设备信息
#define MQTT_ClientID "dev1"
#define MQTT_UserName "507546"
#define MQTT_PassWord "version=2018-10-31&res=products%2F507546%2Fdevices%2Fdev1&et=1680445911&method=md5&sign=qgaS0NCoxqSnIFZGL%2Fz81Q%3D%3D"

//订阅与发布的主题
#define SET_TOPIC  "$sys/507546/dev1/#"  //订阅
#define POST_TOPIC "$sys/507546/dev1/dp/post/json"  //发布

//设置连接的路由器信息
#define CONNECT_WIFI  "DS小龙哥"   //将要连接的路由器名称 --不要出现中文、空格等特殊字符
#define CONNECT_PASS "12345678"       //将要连接的路由器密码

#define CONNECT_SERVER_IP "183.230.40.96"   //服务器IP地址
#define CONNECT_SERVER_PORT 1883            //服务器端口号


char mqtt_message[100];

//WIFI发送数据存储区域
char data_buff[500];

u8 esp8266_state=0;

double Longitude=120.196517; //经度
double latitude=30.194493;  //纬度

float bh1750=0;
 
u8 dht11_temp;
u8 dht11_humidity;
u8 sw1=0;
u8 sw2=0;
u8 sw3=0;
u8 sw4=0;
u8 sw5=0;
u8 sw7=0;

/*
主函数: 程序执行的入口
*/
int main(void)
{
    u8 dian_shi=0; //1表示电视开 0表示电视关
    u8 mode=0; //0 表示手动模式  1表示自动模式
    u32 i=0;
    u8 key_val;
	u32 TimeCnt=0;
    u32 wifi_TimeCnt=0;
    JTAG_Set();
    USART1_Init(115200);    //串口1的初始化
    USART2_Init(115200);    //串口-WIFI
    TIMER2_Init(72,20000);  //超时时间20ms
    USART3_Init(9600);      //串口-语音模块
    TIMER3_Init(36,20000);  //超时时间20ms
    
    //板载按键初始化
    KEY_Init();
    //板载LED灯初始化
    LED_Init();
    //外接LED初始化
    LED2_Init();
    //BH1750的IIC接口
    IIC_Init();
    //初始化DHT11
    DHT11_Init();
    //步进电机初始化	
    Moto_Init(); 
    //初始化
    APP_Init();
    

    printf("正在初始化OLED...\r\n");  
	OLED_Init(0xc8,0xa1); //OLED显示屏初始化--正常显示
	OLED_Clear(0x00);//清屏	
    
    printf("正在初始化ESP8266..\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));
         
        //2. MQTT协议初始化	
        MQTT_Init(); 

        //3. 连接服务器  
        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");

        //3. 订阅主题
        if(MQTT_SubscribeTopic(SET_TOPIC,0,1))
        {
           printf("主题订阅失败.\n");
        }
        else
        {
           printf("主题订阅成功.\n");
        } 
   }
  ........
   ........
    ........
     ........

8. QT上位机软件开发

8.1 应用层下发的指令

为了更方便的展示设备数据,与设备完成交互,还需要开发一个配套的上位机,官方提供了应用侧开发的API接口、SDK接口,为了方便通用一点,我这里采用了API接口完成数据交互,上位机软件采用QT开发。

帮助文档地址: https://support.huaweicloud.cn/usermanual-iothub/iot_01_0045.html
image.png

8.2 查询设备属性接口

设备属性就是设备上传的传感器状态数据信息,应用侧提供了API接口,可以主动向设备端下发请求指令;设备端收到指令之后需要按照约定的数据格式上报数据;所以,要实现应用层与设备端的数据交互,需要应用层与设备端配合才能完成。

应用层下发的指令:

帮助文档地址: https://support.huaweicloud.cn/api-iothub/iot_06_v5_0034.html

接口的在线调试地址: https://apiexplorer.developer.huaweicloud.cn/apiexplorer/debug?product=IoTDA&api=ListProperties
image.png

如果请求参数和返回值不清楚,写代码前,先使用在线调试接口体验一下,验证数据交互是否OK。
请求参数里比较总要的两个必填参数,是设备ID和服务ID,这两个参数在第3章节就介绍过如何获取了,在产品页面创建自定义属性时可以看到服务ID。

image.png

8.2 开发环境介绍

上位机软件采用Qt框架设计,Qt是一个跨平台的C++图形用户界面应用程序框架。Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单来说,QT可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。

QT官网: https://www.qt.io/
image.png
image.png
image.png

8.3 主要的代码

image.png

下面代码里介绍了更新token、获取token、查询设备属性,上传设备属性等主要请求代码。

/*
功能: 获取token
*/
void Widget::GetToken()
{
    //表示获取token
    function_select=3;

    QString requestUrl;
    QNetworkRequest request;

    //设置请求地址
    QUrl url;

    //获取token请求地址
    requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
                 .arg(SERVER_ID);

    //自己创建的TCP服务器,测试用
    //requestUrl="http://10.0.0.6:8080";

    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));

    //构造请求
    url.setUrl(requestUrl);

    request.setUrl(url);

    QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":"
    "{\"user\":{\"domain\": {"
    "\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}},"
    "\"scope\":{\"project\":{\"name\":\"%4\"}}}}")
            .arg(MAIN_USER)
            .arg(IAM_USER)
            .arg(IAM_PASSWORD)
            .arg(SERVER_ID);

    //发送请求
    manager->post(request, text.toUtf8());
}


//更新token
void Widget::on_pushButton_update_token_clicked()
{
    GetToken();
}

//查询设备属性
void Widget::Get_device_properties()
{
    //表示获取token
    function_select=0;

    QString requestUrl;
    QNetworkRequest request;

    //设置请求地址
    QUrl url;

    //获取token请求地址
    requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/properties?service_id=%4")
                 .arg(SERVER_ID)
            .arg(PROJECT_ID)
            .arg(device_id)
            .arg(service_id);

    //自己创建的TCP服务器,测试用
    //requestUrl="http://10.0.0.6:8080";

    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));

    //设置token
    request.setRawHeader("X-Auth-Token",Token);

    //构造请求
    url.setUrl(requestUrl);

    request.setUrl(url);

    //发送请求
    manager->get(request);
}

//更新设备属性
void Widget::on_pushButton_update_device_clicked()
{
    Get_device_properties();
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。