摘要
本文主要内容包括: 使用 DFRobot FireBeetle ESP32-E 开发板实现以下功能,
- DHT11传感器、模拟声音传感器的数据读取。
- 当声音响度阈值时触发警报并启动警报器。
- MQTT通信并上传数据到Adafruit 平台,实现在物联网平台上的数据汇总显示。
本文介绍的内容对应于 Funpack第二季第三期活动规则中的任务五:
用FireBeetle ESP32-E开发板为控制单元的智能家居及物联网信息显示控制项目。
建议搭配:声/光/气/液等传感器 + 电机/继电器等执行器等硬件配合完成。此外, 此任务中声音传感器来自于DFRobot
一、基本功能拆分:
如上图所示为整个系统的连接示意图,对工作内容进行拆分,得到如下几个部分:
- 读取DHT11 传感器的温湿度数据。
- 对模拟声音传感器数据进行读取。
- 对模拟声音传感器的数据进行判断,如果超过阈值则触发警报器发出警报声
- 利用Adafruit平台实现MQTT通信,实现周期性上传数据至Adafruit 物联网数据平台。
- 在Adafruit平台创建dashboard,展示温湿度和警报器状态。
- 发出警报后实现警报器远程解除并重置,
整个系统实物图:
二、功能实现:
1.读取DHT11 传感器的温湿度数据
配置dht11数据输出引脚为 D12, 为了更方便读取数据,引用 dht11库文件 ,直接调用read方法读取数据。这部分功能的代码如下:
#include <dht11.h>
dht11 DHT11;//定义传感器类型
#define DHT11PIN D12//定义传感器连接引脚
DHT11.read(DHT11PIN); //更新传感器所有信息
Serial.print("当前湿度 (%): ");
Serial.println((float)DHT11.humidity, 2);
Serial.print("当前温度 (℃): ");
Serial.println((float)DHT11.temperature, 2);
2. 对模拟声音传感器数据进行读取
此处使用的传感器为: Gravity: 模拟声音传感器(Arduino兼容) 由DFRobot 生产,此传感器可以将声音响度转换为模拟电压值,电压值代表声音的大小。使用ESP32配置模拟io,直接读取模拟量即可。对应部分程序如下:
int val;
val=analogRead(A1); //connect mic sensor to Analog 1
Serial.print("Voice level : ");
Serial.println(val,DEC);//print the sound value to serial
Serial.print(" \r\n ");
3. 对模拟声音传感器的数据进行判断,如果超过阈值则触发警报器发出警报声
前一步已经读取了声音的强度对应的模拟输出量,在这里加以判断,并配置数字引脚D9为输出引脚。当判断声音强度对应输出数值大于20时,把数字输出拉高,警报器即可发出警报声。此项目中使用的警报器只需要接入电源即可发出警报。
pinMode(D9, OUTPUT); // Define the pin of alarm as input pin
if(val>20){
voice_high=1;
digitalWrite(D9, HIGH);
Serial.println("alarm high\n");
}
else{
voice_high=0;
}
4. 利用Adafruit平台实现MQTT通信,实现周期性上传数据至Adafruit 物联网数据平台。
这部分的功能实现基于Adafruit IO平台,此平台提供免费的MQTT服务器和显示面板(dashboard),设定数据源(feeds)和格式后即可配置面板上的显示模块,实时更新数据。
唯一的缺点是,由于是免费的平台,Adafruit 限制了MQTT topic 的数量(Feeds: 10)和每分钟可以发送的数据量(30 / minute)。但是可以理解,毕竟是免费的,而带宽和流量是实打实要花钱的。
Adafruit 的MQTT的官方文档链接在这里, 简要的来说,用户名就是账户的用户名,密码是单独的 Adafruit IO Key,服务器地址:io.adafruit.com 连接端口:1883 (不安全)
使用EspMQTTClient实现MQTT通信,连接配置如下所示:
#include "EspMQTTClient.h"
EspMQTTClient client(
"WIFI-SSID",
"WIFI-PWD",
"io.adafruit.com", // MQTT Broker server ip
"user name", // Adafruit的用户名
"aio_*************", // IO Key
"Device ID", // Client name that uniquely identify your device
1883 // The MQTT port, default to 1883. this line can be omitted
);
向Adafruit 平台上传数据只需要指定Topic和Payload即可
client.publish("username/feeds/topic", "Payload");
需要注意的是,发布的Topic是由具体格式要求的,必须是 username/feeds/topic 这个格式,否则不会在面板上显示。但是可以在平台的log里面查看到具体的警告和报错,遵循提示修改程序即可。
面板的配置很简单,将对应的数据与面板显示控件链接即可实现数据的刷新。
如下图所示,即为配置好的显示面板,包括温湿度和警报系统状态,以及一个开关,可以实现远程设防和接触警报。
5. 发出警报后实现警报器远程解除并重置
这部分的逻辑实现依靠对于系统状态的转换来实现,控制面板上的开关切换状态后,将发布消息至ESP32,ESP32接收到开关切换后的状态后,在本地切换状态变量实现系统在不同状态(常规状态、警报发出、警报被关闭)间的转换。
client.subscribe("username/feeds/alarm_mode", [](const String & payload) {
if (payload=="ON"){
mode=1;
client.publish("username/feeds/notification", "已设防");
}
else{
mode=3;
digitalWrite(D9, LOW);
client.publish("username/feeds/notification", "已解除设防");
}
});
三、对本活动的心得体会:
Funpack活动办的真的很不错,又是一年即将过去,希望funpack活动在2023年办的更好!