Zigbee 智能家居网关实战:ESP32 + CC2652 打造开源中枢

Zigbee 智能家居网关实战:ESP32 + CC2652 打造开源中枢

为什么需要 Zigbee 网关?

智能家居设备越来越多,但很多都依赖云端服务。一旦断网,家里的开关、传感器就全废了。Zigbee 协议的优势在于本地组网、低功耗、自愈合,配合开源网关可以实现完全本地化的智能控制。

市面上的 Zigbee 网关要么贵(Aqara 网关 ¥200+),要么功能受限。今天我们就用 ESP32 + CC2652 自己做一个,成本不到 ¥50,还能深度定制。

需要准备什么?

物品 型号/规格 价格
开发板 ESP32-WROOM-32 ¥25
Zigbee 模块 CC2652P (USB 版) ¥35
天线 2.4GHz PCB 天线 ¥5
外壳 3D 打印/塑料盒 ¥10
USB 线 Micro-USB 数据线 ¥5
总计 ¥80

可选配件:

  • 温湿度传感器 (Aqara) ¥50
  • 人体传感器 (Aqara) ¥60
  • 智能开关 (涂鸦 Zigbee) ¥40

💡 为什么选 CC2652P? 相比老款 CC2531,CC2652P 支持 Zigbee 3.0,信号更强,带 PA 功放,覆盖范围提升 3 倍。

步骤 1:硬件连接

CC2652P USB 版本身就是独立模块,插上电脑就能用。但我们要做成独立网关,需要 ESP32 通过 UART 与 CC2652 通信。

接线图

ESP32          CC2652P
GPIO16 (TX)  →  RX (GPIO3)
GPIO17 (RX)  →  TX (GPIO2)
3.3V         →  VCC
GND          →  GND

注意事项: ⚠️

  • CC2652 工作电压 3.3V,不要接 5V
  • 如果 ESP32 供电不足,建议外接 5V/2A 电源
  • 天线要拧紧,否则信号衰减严重

固件烧录

CC2652P 需要刷入 Zigbee 固件。我们使用 zigbee2xye 的 Coordinator 固件。

# 下载固件
wget https://github.com/Koenkk/Z-Stack-firmware/raw/master/coordinator/Z-Stack_3.x.0/bin/CC1352P2_CC2652P_launchpad_coordinator_20240710.zip

# 解压
unzip CC1352P2_CC2652P_launchpad_coordinator_20240710.zip

# 使用 cc2538-bsl 工具烧录 (需要 Python)
pip install pyserial intelhex

python cc2538-bsl.py -evw -p /dev/ttyUSB0 \
  CC1352P2_CC2652P_launchpad_coordinator_20240710.hex

烧录成功后,LED 会闪烁表示 Zigbee 网络已启动。

步骤 2:ESP32 固件开发

ESP32 负责运行网关逻辑,通过 UART 与 CC2652 通信,并通过 WiFi 连接 Home Assistant。

开发环境

# 安装 ESP-IDF (ESP32 官方开发框架)
git clone --recursive https://github.com/espressif/esp-idf.git
cd esp-idf
./install.sh esp32
. ./export.sh

# 创建项目
idf.py create-project zigbee-gateway
cd zigbee-gateway

核心代码

// main.c - Zigbee 网关主程序
#include 
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/uart.h"
#include "esp_wifi.h"
#include "esp_mqtt_client.h"

#define TX_PIN 16
#define RX_PIN 17
#define UART_BUF_SIZE 1024

// Zigbee 数据帧处理
static void zigbee_rx_task(void *arg)
{
    uint8_t buf[UART_BUF_SIZE];

    while (1) {
        int len = uart_read_bytes(UART_NUM_1, buf, UART_BUF_SIZE, 100);
        if (len > 0) {
            // 解析 Zigbee 帧 (ZNP 协议)
            parse_znp_frame(buf, len);

            // 通过 MQTT 发送到 Home Assistant
            mqtt_publish("zigbee2mqtt/device", buf, len);
        }
    }
}

// MQTT 回调 - 接收 Home Assistant 命令
static void mqtt_callback(void *handler, esp_event_base_t base, 
                          int32_t event_id, void *event_data)
{
    esp_mqtt_event_handle_t event = event_data;

    if (event->event_id == MQTT_EVENT_DATA) {
        // 将命令转发给 Zigbee 设备
        uart_write_bytes(UART_NUM_1, event->data, event->data_len);
    }
}

void app_main(void)
{
    // 初始化 UART
    uart_config_t uart_config = {
        .baud_rate = 115200,
        .data_bits = UART_DATA_8_BITS,
        .parity = UART_PARITY_DISABLE,
        .stop_bits = UART_STOP_BITS_1,
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
    };
    uart_param_config(UART_NUM_1, &uart_config);
    uart_set_pin(UART_NUM_1, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
    uart_driver_install(UART_NUM_1, UART_BUF_SIZE, 0, 0, NULL, 0);

    // 创建 Zigbee 接收任务
    xTaskCreate(zigbee_rx_task, "zigbee_rx", 4096, NULL, 5, NULL);

    // 连接 WiFi 和 MQTT
    connect_wifi();
    connect_mqtt();
}

原理解析:
ESP32 作为"翻译官",一端通过 UART 与 CC2652 通信(ZNP 协议),另一端通过 MQTT 与 Home Assistant 通信。所有 Zigbee 设备的数据都转换成 MQTT 消息,实现协议转换。

步骤 3:Home Assistant 集成

安装 Zigbee2MQTT

# 在 Home Assistant 中添加插件
# 进入:设置 → 插件 → 插件商店 → 搜索 "Zigbee2MQTT"

# 或者 Docker 手动安装
docker run -d \
  --name zigbee2mqtt \
  --restart=unless-stopped \
  -v /opt/zigbee2mqtt/data:/app/data \
  -v /opt/zigbee2mqtt/log:/app/log \
  -v /dev/ttyUSB0:/dev/ttyUSB0 \
  --device=/dev/ttyUSB0 \
  koenkk/zigbee2mqtt

配置文件

# configuration.yaml
mqtt:
  broker: 192.168.1.100
  port: 1883
  username: homeassistant
  password: your_password

# 自动发现 Zigbee 设备
homeassistant:
  discovery_prefix: homeassistant

设备配对

  1. 在 Zigbee2MQTT 界面点击 "Permit join (所有设备)"
  2. 将 Zigbee 设备进入配对模式(通常是长按 5 秒)
  3. 设备会自动出现在 Home Assistant 中

测试验证

配对成功后,在 Home Assistant 中可以看到:

传感器:温湿度、人体移动、门窗状态
开关:智能插座、灯光控制
调光:LED 灯带、色温调节

效果展示:

  • 响应延迟 < 200ms(本地网络)
  • 断网仍可本地控制
  • 支持 50+ 设备同时在线

常见问题排查

问题 1: CC2652 无法识别

  • 原因: USB 供电不足或驱动问题
  • 解决: 使用带外接电源的 USB Hub,安装 CH340 驱动

问题 2: Zigbee 设备配对失败

  • 原因: 距离太远或有干扰
  • 解决: 靠近网关配对,避开 WiFi 路由器(2.4GHz 干扰)

问题 3: MQTT 连接断开

  • 原因: broker 地址错误或认证失败
  • 解决: 检查 MQTT 服务器配置,确认用户名密码

问题 4: ESP32 频繁重启

  • 原因: 看门狗超时或内存不足
  • 解决: 增加 CONFIG_ESP32_DEFAULT_CPU_FREQ_240,优化代码内存占用

进阶扩展

添加 Web 管理界面

#include 

AsyncWebServer server(80);

server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html);
});

server.begin();

访问 ESP32 的 IP 地址即可管理设备。

支持 Matter 协议

未来可以升级固件支持 Matter,实现跨平台兼容(Apple HomeKit、Google Home、Alexa)。

总结

自己制作 Zigbee 网关不仅省钱,更重要的是完全掌控数据隐私。所有设备数据都在本地处理,无需上传云端。配合 Home Assistant,可以实现高度定制化的智能场景。

下一步可以尝试:

  • 添加语音控制(离线语音识别)
  • 集成小爱同学/天猫精灵
  • 制作 Zigbee 信号中继器扩展覆盖

希望这篇博客文章对您有所帮助!


相关资源: