项目介绍
本项目旨在利用Arduino UNO R4和MQTT协议构建一个可调亮度的LED矩阵灯,能够通过Home Assistant进行控制。借助EMQX作为MQTT代理,实现了物联网设备与智能家居系统的无缝连接。用户可以在Home Assistant的界面上轻松调节LED矩阵的亮度,提升家庭智能化程度和用户体验。
设计思路
本项目的核心设计思路是将Arduino UNO R4作为控制单元,通过MQTT协议与Home Assistant进行通信。具体流程如下:
- MQTT协议:项目使用MQTT协议,选择EMQX作为MQTT代理,方便设备之间的通信。Arduino订阅特定的主题(topic),从而接收来自Home Assistant的亮度调整指令。
- Home Assistant配置:在Home Assistant中,通过
configuration.yaml
文件配置可调亮度的灯。在该配置中,将MQTT主题与LED矩阵控制逻辑关联,实现亮度调节功能。 - 数据交互:用户在Home Assistant上通过滑块调整亮度,Home Assistant将更新后的数据通过MQTT发送给EMQX。Arduino接收到指令后,控制LED矩阵的亮度,反馈用户的操作。
简单的硬件介绍
本项目所需的硬件主要包括:
- Arduino UNO R4:作为项目的主控板,板载LED矩阵和WiFi模块。负责处理MQTT消息和用LED矩阵显示亮度。并通过板载ESP32连接到WiFi网络,实现与EMQX的MQTT通信。
- 运行Homeassistant的硬件:这里在电脑的虚拟机上运行一个HAOS。
- USB线:用于连接Arduino和电脑烧录代码和供电。
流程图
实现过程
HomeAssistant端配置
安装EMQX
因为这里是HAOS,直接在加载项里安装就可以了。装完以后创建一个用户,我这里名字叫sensor,密码a1234567
安装MQTT
如果没有安装的话需要先安装MQTT集成,代理填127.0.0.1
,用户名和密码填EMQ中的设置的。
配置configuration.yaml
在configuration.yaml里面写入下面的配置,注意缩进,因为yaml对缩进非常敏感。
mqtt:
- light:
name: "Office light"
state_topic: "office/light/status"
command_topic: "office/light/switch"
brightness_state_topic: 'office/light/brightness'
brightness_command_topic: 'office/light/brightness/set'
qos: 0
payload_on: "ON"
payload_off: "OFF"
optimistic: false
重启后就能看到多出来一个设备,点击这个设备就可以看到调整亮度的滑动条。
到这里HA的配置就结束了,在界面上可以看到一个可以调整亮度的灯,并且调整亮度的时候会下发相应的数值(0~255)到mqtt broker中特定的topic上,就是在configuration.yaml中brightness_command_topic填入的值。
Arduino代码实现
Arduino工程是一个,platformio工程,解压后用vscode打开解压后的文件夹,然后vscode里安装platformio,会自动安装一个ArduinoMqttClient库,用于mqtt通信。
板载LED点阵的驱动
在最上面#include <Arduino_LED_Matrix.h>
引入头文件,然后创建一个对象ArduinoLEDMatrix matrix
。在setup里面matrix.begin();
初始化,就可以控制了。
MQTT的连接
引入头文件
#include <WiFiS3.h>
#include <ArduinoMqttClient.h>,
然后创建对应变量。
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
然后在setup里面初始化变量,连接wifi,连接MQTT broker,注册回调,订阅对应topic。
Serial.print("Attempting to connect to WPA SSID: ");
Serial.println(ssid);
while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
// failed, retry
Serial.print(".");
delay(5000);
}
Serial.println("You're connected to the network");
Serial.print("IP address:");
Serial.println(WiFi.localIP().toString().c_str());
Serial.println();
mqttClient.setId("clientId");
mqttClient.setUsernamePassword("sensor", "a1234567");
Serial.print("Attempting to connect to the MQTT broker: ");
Serial.println(broker);
while (!mqttClient.connect(broker, port)) {
Serial.print("MQTT connection failed! Error code = ");
Serial.println(mqttClient.connectError());
delay(1000);
}
// set the message receive callback
mqttClient.onMessage(onMqttMessage);
// subscribe to a topic
mqttClient.subscribe(topic);
Serial.println("You're connected to the MQTT broker!");
Serial.println();
最后在loop里面不断轮询mqtt是否收到数据,收到的话改变全局变量lightValue
,如果并且在loop里面如果发现值发生了变化就调用函数画出对应的led矩阵图案。
最终效果
在网页上调整灯光亮度,arduino的led点阵会实时变化,并且亮度大于90%的时候,led点阵会显示一个太阳(不过分辨率太低看起来像是一个方块。。。)