320|2

34

帖子

4

TA的资源

一粒金砂(中级)

楼主
 

【Follow me第二季第2期】智能家居之智能书房 [复制链接]

  本帖最后由 鲜de芒果 于 2024-10-2 17:28 编辑

1. 任务要求

  1. 通过外部LTR-329 环境光传感器,上传温湿度到HA,通过HA面板显示数据
  2. 通过外部AHT20温湿度传感器,上传温湿度到HA,通过HA面板显示数据
  3. 使用板载LED模拟台灯,可通过HA面板控制其开关与亮度调节
  4. 书房自动光线调节是一个智能书房的重要组成部分,它能够根据环境光线的变化自动调整台灯的亮度或开关状态,以确保阅读或工作时的光线既充足又舒适

    

2. 硬件准备

 

3. HomeAssistant集成

**MQTT** 设备的发现将使人们能够在 [HomeAssistant](https://www.home-assistant.io) 方面只需要很少的配置工作就可以使用 **MQTT** 设备。配置是在设备本身和设备使用的主题上完成的。

 

> MQTT 发现默认启用,但可以禁用。发现主题的前缀(默认:`homeassistant`)可以更改。配置详情请参阅 [MQTT 选项部分](https://www.home-assistant.io/integrations/mqtt#configure-mqtt-options)

 

3.1 配置主题

向 MQTT 发送配置主题后, HomeAssistant 会自动发现当前传感器。 当前任务中使用了一个板载LED灯,作为 HomeAssistant 中的 Light 组件。该组件在 HomeAssistant 的 仪表盘 中可以远程控制板载LED的开和关。使用 MQTT 客户端向配置主题发送消息即可。本项目中使用了三个传感器 + 一个台灯,具体配置主题如下:

  • // 台灯 消息
  • {
  • "name":"table-lamp",
  • "device_class": "light",
  • "command_topic":"homeassistant/light/FollowMe2-2-table-lamp/switch",
  • "state_topic":"homeassistant/sensor/FollowMe2-2/state",
  • "brightness_command_topic": "homeassistant/light/FollowMe2-2-table-lamp/brightness/set",
  • "brightness_state_topic": "homeassistant/sensor/FollowMe2-2/state",
  • "state_value_template": "{{ value_json.builtinLed }}",
  • "brightness_value_template": "{{ value_json.brightness }}",
  • "unique_id":"FollowMe2-2-table-lamp",
  • "device":{
  • "identifiers":[
  • "Arduino UNO R4 WiFi"
  • ],
  • "name":"UNO R4 WiFi",
  • "manufacturer": "Arduino",
  • "model": "UNO R4 WiFi",
  • "hw_version": "1.0"
  • }
  • }
  • // 书房 温度传感器 消息
  • {
  • "device_class":"temperature",
  • "state_topic":"homeassistant/sensor/FollowMe2-2/state",
  • "unit_of_measurement":"°C",
  • "value_template":"{{ value_json.temperature}}",
  • "unique_id":"FollowMe2-2-study-temperature",
  • "device":{
  • "identifiers":[
  • "Arduino UNO R4 WiFi"
  • ],
  • "name":"UNO R4 WiFi",
  • "manufacturer": "Arduino",
  • "model": "UNO R4 WiFi",
  • "hw_version": "1.0"
  • }
  • }
  • // 书房 湿度传感器 消息
  • {
  • "device_class":"humidity",
  • "state_topic":"homeassistant/sensor/FollowMe2-2/state",
  • "unit_of_measurement":"%",
  • "value_template":"{{ value_json.humidity}}",
  • "unique_id":"FollowMe2-2-study-humidity",
  • "device":{
  • "identifiers":[
  • "Arduino UNO R4 WiFi"
  • ],
  • "name":"UNO R4 WiFi",
  • "manufacturer": "Arduino",
  • "model": "UNO R4 WiFi",
  • "hw_version": "1.0"
  • }
  • }
  • // 书房 环境光传感器 消息
  • {
  • "device_class":"illuminance",
  • "state_topic":"homeassistant/sensor/FollowMe2-2/state",
  • "unit_of_measurement":"lx",
  • "value_template":"{{ value_json.ambientLight}}",
  • "unique_id":"FollowMe2-2-study-illuminance",
  • "device":{
  • "identifiers":[
  • "Arduino UNO R4 WiFi"
  • ],
  • "name":"UNO R4 WiFi",
  • "manufacturer": "Arduino",
  • "model": "UNO R4 WiFi",
  • "hw_version": "1.0"
  • }
  • }

 

4. 代码实现

  • /**
  • * FollowMe 2-2 任务4:
  • * 1. 通过Wi-Fi,利用MQTT协议接入到开源的智能家居平台HA(HomeAssistant)
  • */
  • #include <Wire.h>
  • #include <WiFiS3.h>
  • #include <ArduinoMqttClient.h>
  • #include <ArduinoJson.h>
  • #include <Adafruit_AHTX0.h>
  • #include <Adafruit_LTR329_LTR303.h>
  • #include "arduino_secrets.h"
  • #define LOOP_DELAY 10 // loop函数延时(单位:毫秒)
  • #define SENSOR_REPORT_INTERVAL 5 // 传感器数据更新间隔(单位:秒)
  • #define STATE_ON "ON" // HA LED开状态
  • #define STATE_OFF "OFF" // HA LED关状态
  • char ssid[] = SECRET_SSID; // WIFI SSID
  • char pass[] = SECRET_PASS; // WIFI PASSWD
  • int status = WL_IDLE_STATUS; // WIFI 状态
  • // MQTT
  • WiFiClient wifiClient;
  • MqttClient mqttClient(wifiClient);
  • const char broker[] = "192.168.2.120"; // HomeAssistant MQTT服务器地址
  • int port = 1883; // HomeAssistant MQTT服务器端口
  • char mqtt_user[] = MQTT_USER; // MQTT 用户名
  • char mqtt_pass[] = MQTT_PASS; // MQTT 密码
  • // 订阅主题(接收 HomeAssistant 控制板载LED开关指令)
  • const char switch_subscribe_topic[] = "homeassistant/light/FollowMe2-2-table-lamp/switch";
  • // 订阅主题(接收 HomeAssistant 控制板载LED亮度调节指令)
  • const char brightness_subscribe_topic[] = "homeassistant/light/FollowMe2-2-table-lamp/brightness/set";
  • bool isNeedReportState = true; // 是否需要更新状态到HA
  • bool ledState = false; // 板载LED状态
  • // 发布主题(上报板载LED状态至 HomeAssistant的状态主题)
  • const char publish_topic[] = "homeassistant/sensor/FollowMe2-2/state";
  • uint32_t tick = 0; // loop循环次数
  • uint8_t brightness = 0; // 灯亮度调节
  • Adafruit_AHTX0 aht; // AHT20 传感器
  • float temperature = 0; // AHT20 采集到的温度值
  • float humidity = 0; // AHT20 采集到的湿度值
  • Adafruit_LTR329 ltr = Adafruit_LTR329(); // LTR329传感器
  • float ambientLight = 0; // 环境光强度
  • ltr329_gain_t gain = LTR3XX_GAIN_1; // ALS增益
  • ltr329_integrationtime_t integrationTime = LTR3XX_INTEGTIME_100; // 积分时间
  • float integrationTimeVal = 0.1;
  • uint16_t visible_plus_ir; // 可见光
  • uint16_t infrared; // 红外
  • /**
  • * 设置板载LED状态
  • */
  • void setLightState() {
  • if (ledState) {
  • if(0 == brightness) {
  • brightness = 255;
  • }
  • analogWrite(LED_BUILTIN, brightness);
  • } else {
  • analogWrite(LED_BUILTIN, 0);
  • }
  • }
  • void setup() {
  • // 初始化串口
  • Serial.begin(115200);
  • pinMode(LED_BUILTIN, OUTPUT); // 初始化板载LED引脚为输出
  • // 初始化 QWIIC 接口的 I2C 总线
  • Wire1.begin();
  • // 检查WIFI模块
  • if (WiFi.status() == WL_NO_MODULE) {
  • Serial.println("WiFi模块通信失败!");
  • while (true);
  • }
  • // 连接到WIFI
  • Serial.print("尝试连接到 WIFI SSID: ");
  • Serial.println(ssid);
  • while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
  • Serial.print(".");
  • delay(5 * 1000);
  • }
  • Serial.println("WIFI 连接成功!");
  • // 连接MQTT
  • mqttClient.setUsernamePassword(mqtt_user, mqtt_pass);
  • Serial.print("尝试连接到MQTT服务器: ");
  • Serial.println(broker);
  • if (!mqttClient.connect(broker, port)) {
  • Serial.print("MQTT 连接失败! ");
  • Serial.println(mqttClient.connectError());
  • while (1);
  • }
  • Serial.println("MQTT连接成功!");
  • // 订阅主题
  • mqttClient.onMessage(onMqttMessage);
  • mqttClient.subscribe(switch_subscribe_topic);
  • mqttClient.subscribe(brightness_subscribe_topic);
  • // AHT20 初始化
  • if (!aht.begin(&Wire1)) {
  • Serial.println("未找到 AHTX0 传感器!");
  • while (1) delay(10);
  • }
  • Serial.println("AHTX0 传感器初始化成功!");
  • if (!ltr.begin(&Wire1)) {
  • Serial.println("未找到 LTR329 传感器!");
  • while (1) delay(10);
  • }
  • Serial.println("LTR329 传感器初始化成功!");
  • }
  • void loop() {
  • if(isNeedReportState) {
  • // 汇报当前板载LED状态到HA
  • char msg[100] = {0};
  • sprintf(msg, "{\"builtinLed\": \"%s\", \"brightness\": %d,\"temperature\":%.2f,\"humidity\":%.2f, \"ambientLight\":%.2f}",
  • ledState ? STATE_ON : STATE_OFF, brightness, temperature, humidity, ambientLight);
  • mqttClient.beginMessage(publish_topic);
  • mqttClient.print(msg);
  • mqttClient.endMessage();
  • isNeedReportState = false; // 上报板载LED状态到HA后重置汇报状态
  • }
  • if(0 == (tick % (SENSOR_REPORT_INTERVAL * 1000 / LOOP_DELAY))) { // 根据传感器数据更新间隔 SENSOR_REPORT_INTERVAL 宏定义进行上报传感器数据
  • // 读取 AHT20 传感器数据
  • sensors_event_t humi, temp;
  • aht.getEvent(&humi, &temp);
  • temperature = temp.temperature;
  • humidity = humi.relative_humidity;
  • // 读取 LTR329 传感器数据
  • if (ltr.newDataAvailable()) {
  • ltr.readBothChannels(visible_plus_ir, infrared);
  • // 环境光照度计算
  • float ratio = infrared / (visible_plus_ir + infrared);
  • if(ratio < 0.45) {
  • ambientLight = (1.7743 * visible_plus_ir + 1.1059 * infrared) / (1 << gain) / integrationTimeVal;
  • } else if(ratio < 0.64 && ratio >= 0.45) {
  • ambientLight = (4.2785 * visible_plus_ir - 1.9548 * infrared) / (1 << gain) / integrationTimeVal;
  • } else if(ratio < 0.85 && ratio >= 0.64) {
  • ambientLight = (0.5926 * visible_plus_ir + 0.1185 * infrared) / (1 << gain) / integrationTimeVal;
  • } else {
  • ambientLight = 0;
  • }
  • }
  • // 更新状态,更新传感器数据到HA
  • isNeedReportState = true;
  • }
  • // 更新板载LED状态
  • setLightState();
  • mqttClient.poll(); // 定期检查新MQTT消息
  • delay(LOOP_DELAY); // 主循环延时时长
  • tick ++;
  • }
  • // MQTT 订阅消息回调,接收HA控制板载LED的指令(ON:开,OFF:关)
  • void onMqttMessage(int messageSize) {
  • char topic[100] = {0};
  • String message;
  • // 打印消息主题
  • Serial.print("Received message from topic: ");
  • strcpy(topic, mqttClient.messageTopic().c_str());
  • Serial.println(topic);
  • // 读取消息内容
  • for (int i = 0; i < messageSize; i++) {
  • message += (char)mqttClient.read();
  • }
  • // 打印消息的内容
  • Serial.print("Received message: ");
  • Serial.println(message);
  • if(0 == strcmp(switch_subscribe_topic, topic)) {
  • // 开关
  • if(0 == strcmp(STATE_ON, message.c_str())) {
  • if(false == ledState) {
  • // 需要更新板载LED状态到HA
  • isNeedReportState = true;
  • }
  • ledState = true;
  • } else {
  • if(true == ledState) {
  • // 需要更新板载LED状态到HA
  • isNeedReportState = true;
  • }
  • ledState = false;
  • }
  • } else if(0 == strcmp(brightness_subscribe_topic, topic)) {
  • // 亮度
  • uint8_t b = message.toInt();
  • if (brightness < 0 || brightness > 255) { // 范围校验
  • // do nothing...
  • return;
  • } else {
  • brightness = b;
  • setLightState();
  • isNeedReportState = true;
  • }
  • }
  • }

 

5. 智能家居自动化

本项目中结合 Adafruit LTR-329 Light Sensor 环境光传感器模块作为书房环境光照监测。当光照低于阀值时,自动打开台灯(本例中没有对接真实的智能台灯,使用板载LED模拟,可以控制开关与亮度)。光照充足时自动关闭台灯。实现自动调整书房光线,无需手动干预。在节能方面,避免不必要的照明,节省电力。同时保持书房光线在最佳水平,保护眼睛,提高阅读和工作效率。

 

6. 效果展示

 

7. 演示视频


 

 

8. 结语

Arduino Uno R4 WiFi智能书房是一个基于Arduino Uno R4开发板和ESP8266 Wi-Fi模块的智能家居项目。这个项目的主要功能是通过Wi-Fi连接,实现对书房内环境以及各种设备的远程控制和管理。

通过这个项目,我们不仅提高了对物联网技术的理解和运用能力,也学会了如何将理论转化为解决实际问题的应用。希望这些经验和心得能为未来的项目提供参考和启发。

 

9. 参考资料

 

10. 传送门

 

11. 项目源码

源码.zip (7.76 KB, 下载次数: 2)



 

最新回复

UUC
创意和设计很好,分享的也很详细。学习了~~~   详情 回复 发表于 2024-10-2 20:42
点赞 关注
 
 

回复
举报

701

帖子

4

TA的资源

纯净的硅(高级)

沙发
 

感谢楼主分享的智能家居的技术知识,非常详细,通俗易懂,值得收藏学习

 
 
 

回复

996

帖子

0

TA的资源

纯净的硅(高级)

板凳
 

创意和设计很好,分享的也很详细。学习了~~~

个人签名

没有特别的幸运,就要特别的努力

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
报名最后2天:ADI 最新低功耗 MCU 及其解决方案详解
直播时间:3月20日(本周四) 上午10:00
活动奖励:双肩包、充电宝、小夜灯

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 1

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表