选型避坑:ESP32 vs STM32+模组 vs NB-IoT,不同场景怎么选

选型避坑:ESP32 vs STM32+模组 vs NB-IoT,不同场景怎么选

专栏第 3 篇|这是一篇能帮你在立项阶段省掉两个月返工时间的文章。选错了主控方案,后期改起来牵一发而动全身------PCB 要重画,固件框架要重写,有时候连产品定义都得跟着调整。


一个选错芯片的真实代价

2021 年,我们接了一个户外停车场地磁传感器的项目。甲方要求 3 年免维护,电池供电,覆盖范围包括地下车库和城市各处停车位。

当时团队有人提议用 ESP32,理由是「开发快、资料多」。我拦下来了。

为什么?ESP32 深睡眠电流约 10µA,听起来不错。但它每次上报数据都需要重新连 Wi-Fi------扫描、关联、DHCP、TLS 握手,一次唤醒周期大约 1~3 秒,电流峰值 200mA+。按照每 5 分钟上报一次、每次唤醒 2 秒的算法,平均电流大约是 2.2mA。一节 3000mAh 的锂亚电池,理论续航不到 60 天。

更致命的是,地下车库根本没有 Wi-Fi 信号。

最终方案是 STM32L431 + BC660K(NB-IoT 模组),NB-IoT 的 PSM 模式下待机电流 3µA,每次唤醒通信约 300ms,平均电流 0.015mA,同样电池的理论续航超过 20 年。

选型阶段的 3 天决策,决定了产品能不能活下去。


三种方案的本质差异

在对比具体参数之前,先理解三种方案的「基因」各是什么。

ESP32 的基因是「集成」。Wi-Fi + BLE + 双核 Xtensa + 4MB Flash,全塞在一颗芯片里,开箱即用。它的设计哲学是让你最快速度跑起来一个原型,牺牲的是极致的功耗和灵活性。Arduino 生态、ESP-IDF 文档、乐鑫官方社区------新手 3 天能让设备联网,这是它最大的优势。

STM32 + 模组的基因是「分离与专业化」。MCU 只跑业务逻辑,通信交给专门的模组。这个架构的好处是每个部分都可以独立选型优化:MCU 选 STM32L4 超低功耗系列,通信模组根据场景换 4G/以太网/LoRa/NB-IoT,两者通过 AT 命令或 SPI 接口通信。代价是开发复杂度上升,需要写 AT 命令解析、处理模组的各种异常状态、自己做 EMC 测试。

NB-IoT 的基因是「极限优化」。它是专门为「低频上报、超长续航、广域部署」场景设计的蜂窝标准。PSM(省电模式)和 eDRX(扩展不连续接收)两个机制,让模组在不通信时进入接近断电的睡眠状态。运营商网络覆盖,你不需要部署网关,设备插上 SIM 卡就能接入。代价是带宽极窄,单次上行包通常不超过 512 字节,不适合任何需要大数据量或低延迟的场景。


深入方案一:ESP32

真正适合 ESP32 的场景

ESP32 在以下场景几乎没有竞争对手:

  • 室内 Wi-Fi 覆盖良好,设备靠近 AP
  • 常电供电,或电池允许每周充电
  • 需要 BLE 和 Wi-Fi 并存(比如蓝牙配网 + Wi-Fi 上报)
  • 团队嵌入式经验有限,需要快速验证产品逻辑
  • 原型阶段,不确定方向,需要快速迭代

智能家居设备(插座、灯控、传感器集线器)、桌面 IoT 设备、工厂内网环境的边缘节点------这些都是 ESP32 的主场。

ESP32 的功耗真相

很多人看到 ESP32 规格书上「Deep Sleep: 10µA」就以为功耗没问题,这是一个非常危险的误读。

10µA 只是 MCU 核心在深睡眠时的电流。实际系统还有:

  • RTC 域保活:约 6µA(如果用 RTC 定时唤醒)
  • Flash 保持:部分 Flash 在 Deep Sleep 时仍有静态电流,约 50~100µA,取决于 Flash 型号
  • 外围电路:传感器、电平转换芯片、LED 状态灯(如果没关掉),都在耗电

一个没有仔细优化的 ESP32 系统,Deep Sleep 实测电流经常在 200~500µA,而不是规格书上的 10µA。我见过一个团队,他们测完觉得「10µA 没问题」,但实际部署后电池 1 个月就没电了,查了一周才发现是 SD 卡模块的上拉电阻在睡眠期间一直拉电流。

ESP32 功耗优化的核心原则:Deep Sleep 前,把所有外设的电源轨关掉,用 GPIO 控制 MOS 管切断供电,而不是依赖软件 disable。

ESP32 开发中最常见的 3 个坑

坑 1:Wi-Fi 重连时间不稳定。ESP32 连 Wi-Fi 有时候 500ms 搞定,有时候要 5 秒,取决于信道扫描情况和 AP 响应速度。如果你的业务逻辑假设「连网最多 2 秒」,弱信号环境下会频繁超时。解决方案:固化信道号和 BSSID,跳过扫描阶段,连接时间可以缩短到 200ms 以内。

c 复制代码
wifi_config_t cfg = {
    .sta = {
        .ssid = "your_ssid",
        .password = "your_pass",
        .channel = 6,          // 固化信道,跳过扫描
        .bssid_set = true,     // 固化 BSSID
        .bssid = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF},
    }
};

坑 2:NVS 写入次数限制。ESP32 的 NVS(非易失性存储)底层是 Flash,Flash 的写入次数有限(通常 10 万次)。如果你每次上报数据都顺手更新一个「上报计数器」到 NVS,10 万次很快就耗尽了,设备开始出现奇怪的存储错误。解决方案:不需要掉电保持的数据放 RAM,只把真正需要持久化的配置写 NVS。

坑 3:TLS 握手内存峰值 。ESP-IDF 的 mbedTLS 默认配置下,TLS 握手期间内存峰值可达 60~90KB。ESP32 只有 320KB DRAM,如果你的应用本身内存用量大,TLS 握手时会 OOM 崩溃。解决方案:在 menuconfig 里开启 CONFIG_MBEDTLS_DYNAMIC_BUFFER,握手完成后释放缓冲区,可以把内存峰值降到 40KB 左右。


深入方案二:STM32 + 通信模组

这个方案的适用场景

STM32 + 模组适合以下情况:

  • 工业现场,需要接 RS485/CAN/4-20mA 等工业接口,ESP32 支持不好
  • 可靠性要求高,需要硬件看门狗、工业级温度范围(-40℃ ~ 85℃)
  • 需要深度定制低功耗,MCU 和模组分开管理睡眠状态
  • 未来需要换通信方式(比如从 4G 换 5G,只换模组不动 MCU)
  • 大规模量产,需要自建 PCB 控制 BOM,ESP32 模组形态成本偏高

选 STM32 系列的学问

STM32 系列型号繁多,选错了功耗差距可以有 10 倍以上。一个快速决策框架:

场景 推荐系列 典型型号 典型 Stop 模式电流
普通工业 MCU STM32F4 STM32F407 ~1mA(Stop 1)
低功耗工业 STM32L4 STM32L432 / L451 ~400nA(Stop 2)
超低功耗传感器 STM32L0 STM32L031 ~210nA(Stop 模式)
高性能 + 低功耗 STM32U5 STM32U575 ~200nA(Stop 2)

对于 IoT 场景,STM32L4 或 STM32L0 是首选,F4 系列功耗太高,除非需要大量浮点运算。

模组选型的关键参数

通信模组的选型比 MCU 还要复杂,因为直接决定了网络覆盖、功耗和流量成本。以下是常见模组的选型参考:

4G 模组(SIM7600、EC21、ML307):适合需要较大带宽、实时性要求高的场景。代价是待机功耗 2~5mA 量级,电池场景慎用。

NB-IoT 模组(BC660K、BC26、M5311):适合低频上报、超长续航。BC660K 是目前主流,PSM 模式下 3µA,价格约 ¥20~30。

以太网模块(W5500、ENC28J60):工厂内网场景,有线连接最可靠,没有无线的信号问题,但需要布线。

LoRa 模组(SX1276、LLCC68):私有网络,需要自建网关,适合园区内部大量传感器节点的低成本部署。

AT 命令交互的工程规范

STM32 和通信模组通过 UART 发 AT 命令通信。这里有一套工程规范,不遵守的话调试起来会很痛苦:

c 复制代码
// 规范的 AT 命令发送与响应解析框架
typedef enum {
    AT_OK = 0,
    AT_ERROR,
    AT_TIMEOUT,
} AT_Result;

AT_Result at_send_cmd(const char *cmd, const char *expected_resp, uint32_t timeout_ms) {
    // 1. 清空 RX 缓冲区(重要:防止上一条命令的残留响应干扰)
    uart_flush_rx();
    
    // 2. 发送命令(带 \r\n 结尾)
    uart_write(cmd, strlen(cmd));
    uart_write("\r\n", 2);
    
    // 3. 等待响应,超时处理
    uint32_t start = systick_ms();
    while (systick_ms() - start < timeout_ms) {
        if (uart_recv_contains(expected_resp)) return AT_OK;
        if (uart_recv_contains("ERROR")) return AT_ERROR;
        delay_ms(10);
    }
    return AT_TIMEOUT;
}

// 使用示例:初始化 NB-IoT 模组
void nb_init(void) {
    AT_Result r;
    
    r = at_send_cmd("AT", "OK", 1000);  // 基础通信测试
    if (r != AT_OK) { /* 模组未响应,检查硬件 */ return; }
    
    at_send_cmd("AT+CFUN=1", "OK", 5000);   // 开启全功能
    at_send_cmd("AT+CEREG=1", "OK", 1000);  // 开启网络注册上报
    
    // 等待入网,最多 60 秒
    uint32_t start = systick_ms();
    while (systick_ms() - start < 60000) {
        at_send_cmd("AT+CEREG?", "+CEREG: 1,1", 1000); // 1,1 表示已注册
        if (/* 解析结果已注册 */) break;
        delay_ms(2000);
    }
}

最重要的一条:每个 AT 命令都必须有超时处理和重试逻辑。模组有时候会因为信号弱、网络拥塞等原因不响应,没有超时处理的代码在生产环境会直接死在那里。


深入方案三:NB-IoT

真正理解 PSM 和 eDRX

NB-IoT 的低功耗秘密在两个机制,很多人只知道名字,不知道原理,导致配置错了还不知道。

PSM(Power Saving Mode,省电模式):设备向基站申请一个 TAU 周期(T3412 定时器,通常 1 小时~24 小时可配),在这个周期内设备大部分时间完全关闭射频,只在需要上报时唤醒,发完数据等一个 Active Time 窗口(T3324 定时器,通常 2~30 秒)接收下行消息,然后重新进入 PSM。

c 复制代码
// 配置 PSM:TAU = 1 小时,Active Time = 10 秒
// T3412 格式:5位单位 + 3位值,见 3GPP TS 24.008 Table 10.5.163a
// "00100001" = 单位1小时 × 1 = 1小时
// T3324 格式:同上
// "00000101" = 单位2秒 × 5 = 10秒
at_send_cmd("AT+CPSMS=1,,,\"00100001\",\"00000101\"", "OK", 1000);

eDRX(Extended Discontinuous Reception,扩展不连续接收):比 PSM 更灵活,设备在 eDRX 周期内定期醒来「听」一下有没有下行消息,周期可以设到 5 分钟~40 分钟。eDRX 比 PSM 功耗高,但下行延迟更低------如果你需要云端能相对及时地推消息给设备,eDRX 比 PSM 更合适。

PSM 的最大坑:下行延迟。设备进入 PSM 后,云端推下来的消息要等到设备下次主动唤醒才能收到,这个延迟可能是几小时。如果你的场景需要云端实时控制设备(比如开关阀门),PSM 完全不适合。NB-IoT 天然适合「设备主动上报、云端被动接收」的单向模型,双向实时控制不是它的强项。

NB-IoT 的 MQTT 特殊性

NB-IoT 上跑 MQTT 有几个和 Wi-Fi 环境不同的地方,必须特别处理:

心跳周期要配合 PSM。MQTT 的 keepalive 时间必须大于 PSM 的 TAU 周期,否则 Broker 会因为心跳超时把连接断掉。但 PSM 期间 TCP 连接本来就已经断了,所以每次唤醒后要重新建立 MQTT 连接。这意味着 NB-IoT 场景下,MQTT 重连频率高、每次重连的 TLS 握手开销需要纳入功耗预算。

包大小严格控制。NB-IoT 单帧最大传输单元约 1280 字节,MQTT payload 建议控制在 512 字节以内。数据格式推荐用 CBOR 替代 JSON------相同数据量,CBOR 编码通常比 JSON 小 30~50%,在低带宽场景意义显著。

c 复制代码
// JSON(37字节)
{"t":26.5,"h":58.2,"b":87}

// CBOR 等价(约 15 字节,节省 60%)
// 83 F9 43 90 F9 44 66 18 57
// 使用 TinyCBOR 库编码

入网时间纳入功耗预算。NB-IoT 首次入网(Attach)可能需要 10~60 秒,这段时间射频全开,是功耗最高的阶段。优化策略:每次 PSM 唤醒后不重新 Attach,而是利用之前保存的 eDRX/PSM 上下文直接恢复,入网时间可以缩短到 2~5 秒(部分运营商网络支持)。


选型决策树

把上面的内容浓缩成一棵决策树,供立项时快速参考:

复制代码
设备需要部署在室外,或没有 Wi-Fi?
├─ 是 → 需要双向实时控制(延迟 < 1 秒)?
│        ├─ 是 → STM32 + 4G 模组
│        └─ 否 → 上报频率高于每小时一次?
│                 ├─ 是 → STM32 + 4G 模组
│                 └─ 否 → NB-IoT(首选)
└─ 否 → 电池供电,且需要超过 1 年续航?
         ├─ 是 → NB-IoT(室内 NB-IoT 穿墙能力比 Wi-Fi 强)
         └─ 否 → 团队嵌入式经验少,或原型阶段?
                  ├─ 是 → ESP32
                  └─ 否 → 需要工业接口(RS485/CAN)或大规模量产?
                           ├─ 是 → STM32 + 模组
                           └─ 否 → ESP32(简单场景首选)

三种方案的切换成本

有一个问题很多工程师立项时没有想清楚:如果选错了,改方案有多贵?

从 ESP32 迁移到 STM32 + 模组:固件几乎全部重写(不同 SDK、不同 HAL),硬件 PCB 要重新设计,预计 1~2 个月工作量。

从 STM32 + Wi-Fi 模组换成 STM32 + NB-IoT 模组:硬件改动相对小(模组接口类似),固件的 AT 命令层和网络配置要重写,大约 2~4 周。

从 NB-IoT 换回 Wi-Fi(比如觉得带宽不够):硬件和固件都要重来,同时意味着产品定义变了(需要网络覆盖要求降低),可能连部署方案都要重设计。

结论:越早想清楚,越便宜。选型评审不是形式,是真实的技术决策。


一个被忽视的维度:运维成本

大多数选型讨论只看 BOM 成本,但运维成本往往是 BOM 的 10 倍以上。

NB-IoT 的 SIM 卡流量费,按照每台设备每月上报 1000 条数据、每条 200 字节计算,每月约 200KB 流量,现在运营商物联网卡大约 ¥2~5/台/年,10 万台设备就是 20~50 万/年。这个数字要在立项阶段就纳入商业模型,而不是产品出来了才发现流量费吃掉了利润。

Wi-Fi 方案的运维成本在于「设备是否能稳定连上路由器」。消费电子场景里,用户家里的路由器换密码、换设备,都会导致你的设备断连。如果没有好的重新配网流程,售后服务成本会很高。

STM32 + 4G 方案的运维成本主要是 SIM 卡管理------几万台设备的 SIM 卡如果分属不同运营商,管理平台的复杂度和费用都不低。


最后的建议

我在团队里推行一个原则:选型决策要写成一页纸的文档,列出候选方案、评估维度和最终决策理由,让 3 年后的人能看懂当时为什么这么选。

因为产品迭代的时候,新人接手不知道当时的约束条件,很容易做出「为什么不换成 ESP32 / 换成 NB-IoT」这类质疑。有文档,一切清晰;没文档,每次都要重新讨论一遍。

技术选型没有标准答案,只有适合当前约束条件的最优解。


下一篇:MQTT 协议精讲:QoS 0/1/2 背后的工程权衡,不是文档翻译

作者:15 年嵌入式软件工程师,专注物联网设备端开发

专栏:嵌入式物联网工程实战:从连接到上云

这篇文章对你有帮助?点赞收藏,下次选型的时候翻出来对照着用。

相关推荐
黎阳之光2 小时前
黎阳之光透明大楼:实景孪生重构智慧建筑全新范式
人工智能·物联网·算法·安全·数字孪生
拎得清n4 小时前
寄存器点灯
单片机·嵌入式硬件
MetrixAeroCore10 小时前
美国物联网设备出海通信适配指南|北美全域组网合规方案(MetrixAeroCore)
物联网
破晓单片机13 小时前
067、STM32项目分享:语音儿童学习书桌系统
stm32·单片机·嵌入式硬件
欢乐熊嵌入式编程13 小时前
嵌入式 + MQTT:数据上传到阿里云实战(从0到1完整教程)
stm32·单片机·mqtt·freertos·嵌入式架构·efr32
10WTW0113 小时前
微机原理 8259A 可编程中断控制器
单片机·嵌入式硬件
破晓单片机16 小时前
068、STM32项目分享:智能小区门禁系统
stm32·单片机·嵌入式硬件
AGIPlayer16 小时前
没有生态的大模型不算前沿
大数据·人工智能·物联网
H__Rick17 小时前
C51单片机学习-DAY3
单片机·学习·mongodb