一、项目介绍
利用Teensy 4.1进行智能家居点灯控制,展示了其在物联网领域的可行性和高效性。该项目增强了对智能设备互联互通的理解,为进一步拓展智能家居方案提供了坚实基础。未来可以考虑集成更多的传感器和智能设备,提高系统的可扩展性和功能多样性。
1.1 硬件介绍
Teensy 4.1 是一款高性能微控制器开发板,它基于ARM Cortex-M7内核,主频可达600 MHz,具备丰富的外设接口和强大的计算能力。它在智能家居应用中能够胜任复杂的控制任务。Teensy开发板是一款很成熟的开发板,并且具有完整的Arduino开发环境,易于开发。Teensy 4.1 就是这款广受欢迎的开发平台的最新迭代产品,它采用恩智浦的i.MX RT1062芯片,闪存容量是4.0版本的4倍。Teensy 4.1 的尺寸和形状与 Teensy 3.6 相同(2.4 英寸 x 0.7 英寸),但是提供更强的输入/输出能力,包括以太网 PHY、SD 卡插槽和 USB 主机端口。
1.2 功能概览
本项目旨在实现一个基于Teensy 4.1的智能家居点灯系统。用户可以通过手机APP远程控制LED灯的开关状态,并可以调节灯光的亮度。系统还支持定时开关灯功能,用户可以设置定时任务,实现自动化控制。以下为主要功能介绍:
- 智能灯光控制
- 有线连接至家居网络
- 用户通过移动设备远程开关灯光
- 灯光状态反馈
1.3 设计思路
利用Teensy 4.1的强大处理能力和丰富的接口,设计一个能被集成到现有智能家居系统的灯光控制器。通过以太网模块连接到家庭网络并接入智能家居平台,实现远程控制。使用简单的用户界面进行开关灯操作,并获取反馈。
二、功能实现
2.1 软件流程图
为了清晰地展示软件实现过程,我绘制了软件流程图。流程图主要包括以下几个部分:Arduino 初始化、WiFi 连接与配置、MQTT连接、控制命令接收和执行。Arduino 初始化负责配置硬件参数和初始化变量;WiFi 连接与配置负责连接到WiFi网络;MQTT连接负责接收来自手机APP的控制指令与灯状态的上报;控制命令接收根据MQTT接收到的控制指令生成相应的控制信号;执行则负责驱动LED灯进行相应的操作。
2.2 实现过程
项目基于 VSCode 的 PlatformIO 插件建立工程,具体步骤不在此文详细展开,可查看PlatformIO 文档,使用 khoih-prog/AsyncMQTT_Generic@^1.8.1 库进行 MQTT 通信。以下是实现过程中的关键代码说明。
2.2.1 Arduino 初始化
在 Arduino 初始化阶段主要负责 Teensy 4.1 开发板硬件的初始化,主要有 LED 驱动引脚初始化、串口初始化等。关键代码如下所示:
...
Serial.begin(115200); // 串口初始化
delay(1500);
pinMode(LED_BUILTIN, OUTPUT); // 初始化板载LED引脚为输出
// 打印板卡名称和硬件版本信息
Serial.print("Starting FullyFeatured_QNEthernet on ");
Serial.println(BOARD_NAME);
Serial.println(ASYNC_MQTT_GENERIC_VERSION);
...
2.2.2 网络连接与配置
Arduino 初始化完成后,紧接着就是以太网模块初始化。使用自制的以太网模块连接到 Teensy 4.1 开发板 的 ETHERNET 接口上,就可以为 Teensy 4.1 开发板扩展以太网连接能力。以太网模块的初始化代码如下所示:
...
#if USING_DHCP
// 使用DHCP启动以太网连接
Serial.print("Initialize Ethernet using DHCP => ");
Ethernet.begin();
#else
// 使用静态IP启动以太网连接
Serial.print("Initialize Ethernet using static IP => ");
Ethernet.begin(myIP, myNetmask, myGW);
Ethernet.setDNSServerIP(mydnsServer);
#endif
if (!Ethernet.waitForLocalIP(5000)) {
Serial.println(F("以太网初始化失败!"));
if (!Ethernet.linkStatus()) {
Serial.println(F("以太网未连接!"));
}
// 连接失败,程序停止在这
while (true) {
delay(1);
}
} else {
Serial.print(F("Connected! IP address:"));
Serial.println(Ethernet.localIP());
}
...
2.2.3 MQTT连接
MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅范式的轻量级即时通讯协议,专为低带宽和不可靠网络环境下的远程设备通讯而设计。
MQTT因其轻量级、高效和可靠的特性,已成为物联网领域最受欢迎的通信协议之一。它不仅适用于各种规模的物联网应用,还因其低功耗和高效率的特点,成为移动设备消息推送的理想选择。
通过 MQTT 可以很方便简单地接入到智能家居平台,只需要订阅两个控制主题以及向指定主题上报设备的状态信息即可完成接入。以下为MQTT连接的关键代码展示。
...
// 初始化 MQTT 客户端
AsyncMqttClient mqttClient;
...
// 注册 MQTT 事件回调函数
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
mqttClient.onSubscribe(onMqttSubscribe);
mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onMessage(onMqttMessage);
mqttClient.onPublish(onMqttPublish);
// 设置 MQTT Broker 连接参数
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
mqttClient.setCredentials(MQTT_USER, MQTT_PASS);
// 连接到 MQTT Broker
connectToMqtt();
2.2.4 板载 LED 灯状态数据上报
智能家居平台中灯的状态需要和开发板板载LED的状态保持一致,在智能家居平台的控制面板中对板载LED灯进行控制后,才能直观地感受到当前灯的状态。板载 LED 灯状态数据上报即是实时将开发板上板载 LED 灯状态数据上报至智能家居平台。根据智能家居平台接入的协议说明,只需要上报灯的开关状态和亮度信息即可,消息格式如下:
{
"builtinLed": "OFF", /* 板载 LED 灯的开关状态,ON:表示打开,OFF:表示关闭。 */
"brightness": 145 /* 板载 LED 灯的亮度信息,取值区间为 0 ~ 255。 */
}
根据上述定义的板载 LED 灯状态数据格式定义,生成相应的JSON文本使用 MQTT 将文本发送至 MQTT Broker 相应的主题即可,关键代码如下:
/**
* 上报板载LED状态,包含LED开关状态和亮度信息
*/
void publishBuiltinLedState() {
// 汇报当前板载LED状态到 HomeAssistant
char msg[42] = {0};
sprintf(msg, "{\"builtinLed\": \"%s\", \"brightness\": %d}", ledState ? STATE_ON : STATE_OFF, brightness);
uint16_t packetIdPub = mqttClient.publish(publish_topic, 0, true, msg);
Serial.print("Publishing at QoS 0, packetId: ");
Serial.println(packetIdPub);
isNeedReportState = false; // 上报板载LED状态到 HomeAssistant 后重置汇报状态
}
2.2.5 板载 LED 灯控制指令接收
板载 LED 灯控制指令接收主要由 MQTT 消息回调函数处理,接收到智能家居平台发出的控制指令。MQTT 客户端的消息回调函数将被调用。
控制指令分为两种:开关和亮度控制。分别使用两个不同的主题接收。因此,在 MQTT 客户端的消息回调函数中需要先判断消息来自哪个主题,根据主题判断控制指令是开关控制还是亮度控制。关键代码如下:
...
if(0 == strcmp(switch_subscribe_topic, topic)) {
// 开关
if(0 == strcmp(STATE_ON, message)) {
if(false == ledState) {
// 需要更新板载LED状态到 HomeAssistant
isNeedReportState = true;
}
ledState = true;
} else {
if(true == ledState) {
// 需要更新板载LED状态到 HomeAssistant
isNeedReportState = true;
}
ledState = false;
}
setBuiltinLedState();
} else if(0 == strcmp(brightness_subscribe_topic, topic)) {
// 亮度
uint8_t b = String(message).toInt();
if (b < 0 || b > 255) { // 范围校验
// do nothing...
return;
} else {
brightness = b;
setBuiltinLedState();
isNeedReportState = true;
}
}
...
2.2.6 板载 LED 灯控制指令处理
如 板载-led-灯控制指令接收 章节中的关键代码所示,将接收到的控制指令写入到全局变量中。因此,在执行相应的指令处理就非常地简单,只需要在每次循环时,调用设置板载 LED 灯状态函数 setBuiltinLedState()
即可,setBuiltinLedState()
函数实现如下:
/**
* 设置板载LED状态
*/
void setBuiltinLedState() {
if (ledState) {
if(0 == brightness) {
brightness = 255;
}
analogWrite(LED_BUILTIN, brightness);
} else {
analogWrite(LED_BUILTIN, LOW);
}
}
2.3 HomeAssistant集成
MQTT 设备的发现将使人们能够在 HomeAssistant 方面只需要很少的配置工作就可以使用 MQTT 设备。配置是在设备本身和设备使用的主题上完成的。
MQTT 发现默认启用,但可以禁用。发现主题的前缀(默认:
homeassistant
)可以更改。配置详情请参阅 MQTT 选项部分
2.3.1 配置主题
向 MQTT 发送配置主题后, HomeAssistant 会自动发现当前传感器。 当前任务中使用了一个板载LED,作为 HomeAssistant 中的 Light 组件。该组件在 HomeAssistant 的 仪表盘 中可以远程控制板载LED的开关和亮度。使
用 MQTT 客户端向配置主题发送消息即可,配置主题如下:
// 灯板 主题
homeassistant/light/Funpack3-5-Teensy41/Funpack3-5-Teensy41-LED_BUILTIN/config
// 灯板 消息
{
"name":"Funpack3-5-Teensy41-LED_BUILTIN",
"device_class": "light",
"command_topic":"homeassistant/light/Funpack3-5-Teensy41-LED_BUILTIN/switch",
"state_topic":"homeassistant/sensor/Funpack3-5-Teensy41/state",
"brightness_command_topic": "homeassistant/light/Funpack3-5-Teensy41-LED_BUILTIN/brightness/set",
"brightness_state_topic": "homeassistant/sensor/Funpack3-5-Teensy41/state",
"state_value_template": "{{ value_json.builtinLed }}",
"brightness_value_template": "{{ value_json.brightness }}",
"unique_id":"Funpack3-5-Teensy41-LED_BUILTIN",
"device":{
"identifiers":[
"Funpack3-5-Teensy41"
],
"name":"Teensy41",
"manufacturer": "Arduino",
"model": "Teensy41",
"hw_version": "1.0"
}
}
三、功能展示
经过一系列的设计与实现工作,我成功完成了基于 Teensy 4.1 的智能家居点灯功能。以下是功能展示的具体内容:
- 远程控制:用户可以通过手机APP远程控制LED灯的开关状态和亮度。只需在APP上点击相应的按钮或滑动条即可实现对LED灯的控制。同时,APP还提供了实时反馈功能,可以显示当前LED灯的状态和亮度信息。
- 定时开关灯:用户可以在APP上设置定时任务来控制LED灯的开关状态。例如,可以设置每天晚上6点自动打开LED灯并在晚上6点自动关闭。这样不仅可以方便用户的生活还可以节省能源消耗。
- 场景模式:为了满足不同场景下的照明需求,我实现并提供了多种场景模式供用户选择。例如阅读模式、影院模式等。每种模式都有对应的亮度和色温设置以适应不同的环境和需求。
四、总结
遇到的问题
- 网口模块接口问题,参考官网的网口模块电路图,自行制作了一个网口模块。制作出来成品才发现开发板上的接口是 2.00 mm 规格的接口,模块上却是使用的 2.54 mm 规格的接口。市面上比较好买到的端子连接线都是 2.00 mm 转 2.00 mm 或者 2.54 mm 转 2.54 mm 的端子线。这种情况下,解决方案有两种,一是重新打板制作 2.00 mm 的网口模块。二是定制 2.54 mm 转 2.00 mm 的端子线。这里我使用的是DIY一根 2.54 mm 转 2.00 mm 的端子线(需要有一定的动手能力,简称有手就行)。
心得体会
本次基于Teensy 4.1的智能家居点灯系统项目取得了圆满成功。我们不仅实现了预期的功能还积累了丰富的实践经验和技术知识。通过本项目的实施我们深刻认识到物联网技术在智能家居领域的重要性和潜力同时也看到了未来智能家居市场的广阔前景。在未来的工作中我们将继续深入研究物联网技术探索更多创新应用为智能家居领域的发展贡献自己的力量。同时我们也将不断总结经验教训提高项目的质量和效率为用户提供更加优质、便捷的服务体验。
最后,感谢硬禾学堂联合 DigiKey 推出的这次活动,使我的设计能力进一步提升!