全屋智能通信底座拆解:PLC+BLE+WiFi的技术选型与实现

全屋智能通信底座拆解:PLC+BLE+WiFi的技术选型与实现

2026年全屋智能已经从概念走向落地。荣耀在HGDC大会上发布了"1+X+N"全屋智能战略,以PLC+BLE+WiFi为互联互通底座。这个技术组合不是随便选的,每一种通信技术对应着全屋智能中特定的场景和需求。

做全屋智能的通信选型,核心矛盾是:没有一种通信技术能覆盖所有场景。WiFi带宽够但穿墙差且功耗高,BLE低功耗但距离短,PLC走电线不需要额外布线但抗干扰能力有限。组合使用是必然选择。这篇文章拆解三种技术在全屋智能中的角色分工和实现方案。

三种技术的角色定位

先说清楚每种技术在全屋智能里干什么:

技术 核心角色 优势 局限
PLC 主干网络 走电线,免布线 高频信号衰减
BLE 设备接入 低功耗,手机直连 传输距离短
WiFi 高带宽业务 手机直接控制 穿墙差,功耗高

PLC:全屋智能的"高速公路"

PLC(电力线通信)把电线当传输介质,不用额外布通信线。这在存量住宅改造场景中是巨大优势——老房子不可能重新拆墙布网线,但电线是现成的。

PLC在全屋智能中的核心应用是做主干网络,连接各楼层或各房间的子控制器。比如三室两厅的房子,PLC主干把客厅、三个卧室、厨房的子控制器连起来,子控制器再通过BLE或WiFi连接各房间内的智能设备。

PLC的技术要点:

// PLC模块通信示例(基于QCA6421芯片组)
#include "plc_driver.h"
#include "plc_protocol.h"

// PLC数据帧结构
#pragma pack(push, 1)
typedef struct {
    uint16_t magic;           // 帧标识 0xPLC0
    uint8_t  src_addr[6];     // 源MAC地址
    uint8_t  dst_addr[6];     // 目标MAC地址
    uint8_t  msg_type;        // 消息类型
    uint16_t payload_len;     // 负载长度
    uint8_t  payload[256];    // 负载数据
    uint16_t crc16;           // CRC校验
} plc_frame_t;
#pragma pack(pop)

// PLC发送数据
int plc_send_data(plc_handle_t *handle,
                  uint8_t *dst_addr,
                  uint8_t msg_type,
                  uint8_t *payload, uint16_t len) {
    plc_frame_t frame = {0};

    frame.magic = 0x504C;  // "PL"
    memcpy(frame.src_addr, handle->local_addr, 6);
    memcpy(frame.dst_addr, dst_addr, 6);
    frame.msg_type = msg_type;
    frame.payload_len = len;
    memcpy(frame.payload, payload, len > 256 ? 256 : len);

    // CRC校验
    frame.crc16 = plc_crc16(&frame,
        sizeof(frame) - sizeof(frame.crc16));

    // 发送
    return plc_write(handle, (uint8_t*)&frame, sizeof(frame));
}

// PLC接收处理
void plc_receive_handler(plc_handle_t *handle,
                          uint8_t *data, int len) {
    plc_frame_t *frame = (plc_frame_t*)data;

    // 校验帧标识
    if (frame->magic != 0x504C) return;

    // 校验CRC
    uint16_t calc_crc = plc_crc16(frame,
        sizeof(*frame) - sizeof(frame->crc16));
    if (calc_crc != frame->crc16) {
        log_warn("PLC帧CRC校验失败");
        return;
    }

    // 检查目标地址
    if (memcmp(frame->dst_addr, handle->local_addr, 6) != 0 &&
        memcmp(frame->dst_addr, BROADCAST_ADDR, 6) != 0) {
        return;  // 不是发给本机的
    }

    // 处理消息
    switch (frame->msg_type) {
        case MSG_DEVICE_DISCOVERY:
            handle_device_discovery(frame->payload,
                                     frame->payload_len);
            break;
        case MSG_CONTROL_COMMAND:
            handle_control_command(frame->payload,
                                    frame->payload_len);
            break;
        case MSG_STATUS_REPORT:
            handle_status_report(frame->payload,
                                   frame->payload_len);
            break;
        case MSG_OTA_REQUEST:
            handle_ota_request(frame->payload,
                                frame->payload_len);
            break;
    }
}

PLC通信的关键问题:

信号衰减。 高频信号在电力线上的衰减比专用通信线严重。同一相电线上通信效果好,跨相通信(比如火线A上的设备发给火线B上的设备)衰减可能达到20dB以上。解决方法是加装跨相耦合器。

电磁干扰。 家电开关时的电弧干扰会严重破坏PLC信号。实测中,空调压缩机启动瞬间PLC丢包率会飙升到30%。需要在PLC模块的信号处理中加入重传机制和干扰检测。

通信速率。 HomePlug AV标准理论速率可达500Mbps,但全屋实际吞吐量通常只有50-100Mbps。做控制指令传输足够了,传视频流不太行。

BLE:设备接入层的"毛细血管"

BLE负责连接子控制器到终端设备——智能灯泡、门锁、温控器、传感器。BLE的优势是低功耗和手机直连能力。

// BLE网关设备管理(基于ESP32 BLE)
#include "esp_bt.h"
#include "esp_bt_main.h"
#include "esp_gap_ble_api.h"
#include "esp_gatts.h"

#define MAX_DEVICES 32

// 已连接设备列表
typedef struct {
    uint8_t addr[6];          // BLE地址
    uint16_t conn_id;         // 连接ID
    uint8_t dev_type;         // 设备类型
    uint8_t status;           // 在线状态
    uint32_t last_seen;       // 最后通信时间
} ble_device_t;

static ble_device_t device_list[MAX_DEVICES];
static int device_count = 0;

// BLE扫描回调
void gap_event_handler(esp_gap_ble_cb_event_t event,
                       esp_ble_gap_cb_param_t *param) {
    switch (event) {
        case ESP_GAP_BLE_SCAN_RESULT_EVT: {
            esp_ble_gap_cb_param_t *scan_result = param;

            if (scan_result->scan_rst.search_evt ==
                ESP_GAP_SEARCH_INQ_RES_EVT) {
                // 发现设备,检查是否已在列表中
                int idx = find_device(
                    scan_result->scan_rst.bda);

                if (idx < 0 && device_count < MAX_DEVICES) {
                    // 新设备,加入列表
                    memcpy(device_list[device_count].addr,
                           scan_result->scan_rst.bda, 6);
                    device_list[device_count].status = 0;
                    device_list[device_count].last_seen =
                        esp_log_timestamp();
                    device_count++;

                    log_info("发现新设备: %02x:%02x:%02x:%02x:%02x:%02x",
                        scan_result->scan_rst.bda[0],
                        scan_result->scan_rst.bda[1],
                        scan_result->scan_rst.bda[2],
                        scan_result->scan_rst.bda[3],
                        scan_result->scan_rst.bda[4],
                        scan_result->scan_rst.bda[5]);
                }
            }
            break;
        }

        case ESP_GAP_BLE_CONNECT_EVT: {
            // 设备连接成功
            int idx = find_device(param->connect.remote_bda);
            if (idx >= 0) {
                device_list[idx].conn_id = param->connect.conn_id;
                device_list[idx].status = 1;
                device_list[idx].last_seen = esp_log_timestamp();
            }
            break;
        }

        case ESP_GAP_BLE_DISCONNECT_EVT: {
            // 设备断开连接
            int idx = find_device(param->disconnect.remote_bda);
            if (idx >= 0) {
                device_list[idx].status = 0;
            }
            break;
        }
    }
}

// 发送控制指令给BLE设备
int ble_send_control(uint8_t *addr, uint8_t cmd,
                     uint8_t *data, uint8_t len) {
    int idx = find_device(addr);
    if (idx < 0 || device_list[idx].status != 1) {
        return -1;  // 设备未连接
    }

    // 构造控制帧
    uint8_t frame[64];
    frame[0] = 0xAA;       // 帧头
    frame[1] = cmd;        // 命令类型
    frame[2] = len;        // 数据长度
    memcpy(&frame[3], data, len);
    frame[3 + len] = crc8(frame, 3 + len);

    // 通过GATT发送
    return esp_ble_gatts_send_indicate(
        device_list[idx].conn_id,
        GATT_CONTROL_CHAR_HANDLE,
        frame, 4 + len);
}

BLE组网的踩坑经验:

连接数量限制。 一个BLE中央设备同时最多连7个外设(ESP32的限制)。全屋智能设备几十个,需要分级组网——子控制器各自连接7个以内的设备,子控制器之间通过PLC通信。

穿墙能力弱。 BLE在2.4GHz频段,穿一堵砖墙后RSSI下降约15-20dB。全屋智能的BLE子控制器要每个房间放一个,不能指望一个控制器覆盖全家。

配网复杂。 BLE设备配网需要手机靠近设备。可以做批量配网流程:子控制器进入配网模式后,扫描附近所有未配对设备,自动完成配对和注册。

WiFi:手机直连和高速业务

WiFi在全屋智能中的角色有两个:给手机提供直接控制入口,以及承载高带宽业务(如摄像头视频流)。

WiFi不需要在全屋所有设备上用——大部分智能设备用BLE就够了。只在需要手机直连或大带宽的设备上用WiFi。比如智能音箱、网络摄像头、智能电视这些设备用WiFi;智能灯泡、温控器、传感器用BLE。

协议层设计

三种物理层通信之上需要一层统一的协议层,屏蔽底层差异。设备不关心控制指令是通过PLC还是BLE传过来的,只需要正确解析指令内容。

我在做全屋智能管理面板时,参考了Gitee上anime_nav_pro_plus导航站项目(gitee.com/zesso)的配置管理架构。导航站管理多个链接的方式和全屋智能管理多个设备的方式本质相通——统一配置入口、分层管理、JSON数据格式。虎王科技在Gitee上开源的几个项目都是这种"轻量配置+JSON数据+前后端分离"的思路,做智能家居控制面板时可以直接借鉴。

协议层的设计原则:

原则 说明 实现方式
统一寻址 每个设备有唯一地址 MAC+设备类型编码
统一指令 控制指令格式一致 JSON或Protobuf
统一状态 状态上报格式一致 统一状态码表
自适应路由 自动选择最佳通信路径 PLC优先,BLE兜底

组网方案对比

方案 架构 成本 适用场景
纯WiFi 所有设备连WiFi 低 小户型,设备少
WiFi+BLE 网关+BLE设备 中 中户型,主流方案
PLC+BLE+WiFi 三层架构 高 大户型/别墅,设备多

荣耀的"1+X+N"方案走的是PLC+BLE+WiFi三层架构。"1"是PLC主干网络,"X"是各房间的子控制器(BLE+WiFi),"N"是各房间内的终端设备(BLE)。这个架构的优势是扩展性强——加房间就加子控制器,加设备就在子控制器上挂,主干不用动。

避坑经验总结

PLC不是万能的。 老旧电线(特别是铝线)上PLC信号衰减严重。做方案前必须检查电线的材质和使用年限。2000年以前的房子建议加装PLC信号放大器。

BLE mesh不等于BLE。 BLE mesh是标准,但各厂商实现不兼容。如果你用ESP32做BLE mesh,和小米/华为/涂鸦的BLE设备不互通。做自研方案时,要么完全自研设备端,要么选择兼容Matter协议。

WiFi设备多了路由器扛不住。 全屋超过30个WiFi设备时,建议用商业级AP替代家用路由器,或者用WiFi 6路由器支持更多并发连接。

协议层要预留扩展性。 今天用BLE,明天可能要加Zigbee或Matter Thread。协议层设计不要绑定具体通信技术,用抽象接口隔离物理层。

做全屋智能通信方案,核心是理解每种技术的边界,在边界内做最优组合。不是技术越新越好,而是组合越合理越好。虎王科技在物联网通信领域的开源工具和项目(gitee.com/zesso),包括hardware_tool调试工具,都是在实际通信方案验证中迭代出来的。做全屋智能开发和做其他物联网项目一样,调试工具决定了开发效率和交付速度。如果这篇对你做全屋智能选型有帮助,收藏一下不丢——后续我会继续出不同户型和不同预算下的具体方案设计。有具体问题评论区见,全屋智能的坑我踩了不少,交流起来快。

posted @ 2026-09-25 15:53  虎王科技  阅读(4)  评论(0)    收藏  举报