☰
BC26 NB-IoT智能插座量产实战:从样机到稳定交付
2026/10/14 4:35:44 网站建设 项目流程

最近终于把手上这个BC26 NB室温采集插座的项目推到了量产阶段,说实话,那种感觉就像熬了一个大夜,终于在清晨看到了光。项目本身不复杂,一句话就能说清:做一个可以远程控制通断的智能插座,里面集成室温采集功能,通过BC26这款NB-IoT模组把温度和插座状态上报到云端。但这东西从“样机跑通”到“能批量交付”,中间隔着一整条河。

在动手写代码之前,我先把产品形态理顺了。插座本身是220V市电供电,内部一颗继电器做负载通断控制,主控MCU负责温度采集、按键处理、状态灯控制和与BC26模组通信。为什么要把温度采集放到插座里?因为很多场景下你并不需要在每个房间都单独放一个温度计,插座本身就是散布在房间各个位置的现成载体,客厅、卧室、厨房各一个,天然就能组成一张室温分布网。

这个项目适合正在做NB-IoT类产品、或者准备把实验室Demo往产品化推的人参考。后面内容偏工程实战,我会直接给出代码结构、AT指令调用顺序、低功耗参数配置,以及量产测试时遇到的那些坑。

1. 项目整体方案:为什么插座要选NB-IoT

1.1 产品定义与需求拆解

产品定义阶段先明确了三件事:采集什么、控制什么、上报什么。

采集端是一颗数字温度传感器,放在插座内部靠近上盖的位置,避免贴着继电器发热体。控制端是一路10A继电器,负责负载通断。上报端是BC26模组,通过运营商NB-IoT网络连接云平台,把设备唯一ID、实时温度、插座开关状态、信号强度和固件版本一起发出去。

这里有个容易被忽略的点:温度传感器不能离继电器太近。一开始为了让结构紧凑,我把传感器放在继电器旁边,样机阶段没注意,实际烧机两小时后温度读数比室温高了将近1.5度,完全是继电器线圈和触点发热串扰进来的。后面改板把传感器挪到插座上沿,中间加了一道隔热槽,问题才解决。做这类产品,结构布局对采集数据的影响,往往比代码细节更致命。

需求拆解最后落到几个关键词:远程通断、温度上报、断网告警、固件可升级。前两个是核心功能,后两个是产品化之后补的。很多项目死在只做核心功能、不考虑交付和运维,这个后面量产章节会详细说。

1.2 为什么是NB-IoT而不是WiFi或蓝牙

选通信方案的时候,团队内部其实纠结过一轮。WiFi方案成本低、带宽大,开发资料也多,但有两个问题绕不过去:插座安装在墙角、电视柜后面、弱电箱这种位置,WiFi信号普遍差;用户家里路由器品牌杂、频段混乱,售后咨询量会非常大。蓝牙方案更不用提,没法直接上云,必须配网关,成本全转移到用户那边了。

NB-IoT的优势恰好压在痛点上:覆盖深、穿透强,专门为室内弱信号、地下场景设计的。插座装在弱电箱里,WiFi手机都搜不到的角落,NB-IoT照样能注册入网。代价是带宽窄、时延高,单次有效载荷有限,但室温采集和开关状态这种低频小数据量场景,完全够用。

BC26这颗模组我多说两句:它支持多个NB-IoT频段,内部集成了网络协议栈,可以通过AT指令直接操作入网和MQTT连接,不需要外挂协议芯片。功耗控制也在合理范围,配合PSM模式能把休眠电流压到非常低。对于这种插座类产品,虽然平时插着电不愁供电,但低功耗意味着发热少、器件寿命长,对整机稳定性有帮助。

1.3 硬件架构与模块分工

整机硬件链路大致是:220V输入经过开关电源降压,输出3.3V给MCU和BC26供电;MCU通过I2C读取温度传感器;通过GPIO控制继电器驱动电路;通过UART与BC26交换AT指令。状态灯和按键也都是MCU直接管。

模块分工上,我坚持一个原则:通信协议栈尽量让模组干,MCU只做业务逻辑。BC26本身支持MQTT,那就不需要在MCU上再跑一套TCP/IP和MQTT客户端。MCU只是把JSON数据拼好,通过串口丢给BC26,由模组负责建链、发布消息。这样MCU选型门槛大幅降低,代码量也少很多,调试起来只面对AT指令一个接口。

MCU选的是低功耗单片机,主频不用高,Flash和RAM够用就行。因为业务逻辑不复杂,主要成本在电源、继电器和通信模组上。这里要提醒一点:继电器驱动必须加续流二极管和RC吸收,否则每次开关动作产生的尖峰脉冲,轻则干扰温度采样,重则打坏MCU引脚。第一批样板就有人省了这两个元件,结果一吸合就死机复位,排查了很久。

2. 源码拆解:从AT指令握手到数据上报

2.1 BC26模组驱动的初始化细节

BC26这类NB-IoT模组,MCU和它之间本质就是串口对话,所有操作都是AT指令。初始化顺序一旦搞错,后面全乱。我先贴一段核心初始化流程:

static void bc26_power_on(void) { /* 拉低PWRKEY指定时间触发开机,BC26一般需要保持拉低500ms以上 */ gpio_write(PWRKEY_PIN, 0); delay_ms(600); gpio_write(PWRKEY_PIN, 1); /* 模组启动后会上报URC消息,典型的是 APP RDY 或 RDY */ wait_urc("RDY", 3000); } static int bc26_init(void) { /* 第一步:AT握手,确认串口通路上模组已经响应 */ if (at_execute("AT", "OK", 500) != 0) { return -1; } /* 第二步:关闭回显,避免MCU解析时混入多余字符 */ at_execute("ATE0", "OK", 500); /* 第三步:检查SIM卡状态,SIM卡没就绪后面全部白做 */ if (at_execute("AT+CPIN?", "+CPIN: READY", 1000) != 0) { return -2; } /* 第四步:配置PDP上下文,设置APN */ /* 注意:APN由运营商网络决定,不同物联网卡可能不一样,做成可配置项 */ at_execute("AT+CGDCONT=1,\"IP\",\"\"", "OK", 500); /* 第五步:等待网络注册,CEREG返回1或5才是注册成功 */ int wait_cnt = 0; while (wait_cnt < 30) { if (at_execute("AT+CEREG?", "+CEREG: 1", 1000) == 0) { break; } delay_ms(1000); wait_cnt++; } /* 第六步:激活PDP上下文 */ at_execute("AT+CGACT=1,1", "OK", 1000); return 0; }

整个初始化里,最容易翻车的是等待模组启动的URC超时。BC26上电后如果网络附着慢,第一次AT握手可能没响应。我刚开始写的是“上电后延时2秒直接发AT”,结果在弱信号区域经常失败。后来改成循环重发AT,直到返回OK或者超时,握手就稳多了。

另外,AT指令的返回值解析一定要做“包含匹配”,不要做“精确匹配”。因为AT返回可能是\r\nOK\r\n,也可能是\r\n+CEREG: 1\r\n\r\nOK\r\n这种混合,用字符串包含判断最省事,不容易漏判。

2.2 MQTT上云:数据上报协议设计

数据上报我选的是MQTT,而不是UDP或者COAP。原因很简单:云平台接入方便,设备侧消息可以直接按topic路由,后续做远程指令下发也顺手。BC26模组自带MQTT扩展指令集,不需要在MCU端移植客户端,省了一堆事。

MQTT连接和发布的AT指令序列大概是这样的:

static int mqtt_publish_temp(float temp, uint8_t switch_state) { char topic[] = "dev/room/temp"; char payload[96]; snprintf(payload, sizeof(payload), "{\"id\":\"%s\",\"t\":%.1f,\"s\":%d,\"csq\":%d,\"fw\":\"%s\"}", device_id, temp, switch_state, get_csq(), FIRMWARE_VERSION); /* 如果不在线,先重连 */ if (mqtt_is_connected() != 1) { mqtt_connect(); } /* 发布QoS1消息,确保丢包重传 */ at_execute("AT+QMTPUB=0,0,1,0,\"" topic "\"", ">", 1000); uart_send_payload(payload, strlen(payload)); at_execute("", "OK", 2000); return 0; }

这里有三个设计细节值得展开。

第一,JSON里带了信号强度CSQ。这个字段看起来不起眼,但它在量产和售后阶段极其有用。云平台只要统计每台设备的CSQ分布,就能提前发现哪些设备装在了信号死角,哪些批次天线一致性不行,等用户投诉再排查就晚了。

第二,QoS选择1。室温数据丢一包无所谓,但开关状态指令如果丢了,用户会以为开成功了实际没开。所以状态上报和指令回执我用QoS1,纯温度数据用QoS0,节省网络资源。

第三,消息里带固件版本号。每次发布都带上,平台侧可以自动筛查哪些设备还在跑旧固件,为OTA升级提供数据依据。这个字段一开始没有,后来做了OTA需求才补上,属于返工教训。

2.3 温度采样与软件滤波

温度传感器是数字I2C接口,读取本身很简单,难点在数据可信度。插座的工况远比想象中复杂:继电器吸合瞬间电流波动、开关电源纹波、甚至附近用户用大功率电器,都可能让传感器读数跳变。

我加了三级处理:软硬件滤波电容、采样时机控制、滑窗均值。

static float temp_read_filtered(void) { const int N = 5; static float history[N]; static uint8_t idx = 0; static uint8_t filled = 0; float sum = 0.0f; float raw = sht30_read_temperature(); /* 明显异常值直接丢弃,比如超出-40~80度范围或突变超过3度 */ if (raw < -40.0f || raw > 80.0f || fabs(raw - history[(idx + N - 1) % N]) > 3.0f) { return history[(idx + N - 1) % N]; } history[idx] = raw; idx = (idx + 1) % N; if (filled < N) filled++; for (int i = 0; i < N; i++) { sum += history[i]; } return sum / filled; }

必须避开继电器动作的瞬间采样。我在代码里做了一个互斥逻辑:如果需要上报温度,但继电器刚刚切换,就延迟200ms再采样。200ms这个值是实测出来的,继电器电弧和线圈续流造成的干扰大约持续100~150ms,留一点余量。

还有个更容易被忽视的坑:温度传感器芯片本身有自热效应。I2C通信电流虽然小,但如果连续采集不间隔,芯片自热会让读数偏高0.1~0.3度。所以我把采集周期限制在每10秒最多一次,并且上报前只有最近一次采样结果有效,不额外频繁触发。

2.4 断网重连与状态补偿

NB-IoT网络质量不如家庭WiFi稳定,地下室、电梯井旁边、金属货架内部,都可能出现暂时失联。设备端必须有一套“状态补偿”逻辑,不能数据丢了就丢了。

我的实现思路是:离线期间本地缓存最新一次温度,入网后立即补报。缓存不需要大,一个扇区就够,因为室温变化本来就慢,只需要保证平台拿到的不是陈旧数据。

typedef struct { float temperature; uint8_t switch_state; uint32_t timestamp; } report_cache_t; static report_cache_t last_report; void on_periodic_report(void) { if (network_is_ready()) { float temp = temp_read_filtered(); last_report.temperature = temp; last_report.switch_state = relay_get_state(); last_report.timestamp = now(); mqtt_publish_temp(temp, relay_get_state()); } else { /* 网络不可用,先标记需要补报 */ pending_report = 1; } } void on_network_restored(void) { if (pending_report) { mqtt_publish_temp(last_report.temperature, last_report.switch_state); pending_report = 0; } }

重连逻辑上,BC26如果长时间驻网失败,不能一直死等,需要周期性复位模组。我设置的是连续6次入网失败后,冷复位BC26重新走初始化流程。这种看门狗式的处理不是最优解,但在批量部署场景里,简单粗暴往往比优雅聪明更可靠。

3. 低功耗设计:PSM和eDRX参数怎么调

3.1 NB-IoT功耗模型底子

做智能插座,很多人觉得反正有市电,功耗不重要。这个想法在量产之后就站不住脚了。功耗不只是省电问题,它直接影响整机发热、器件寿命、电源成本,甚至会反向影响温度采集的准确性——电源发热是室温传感器最大的干扰源。

BC26模组的功耗模型和普通蜂窝模组不一样,主要是因为它支持PSM(省电模式)和eDRX(扩展非连续接收)。理解这两个机制,就能明白NB-IoT的低功耗上限在哪。

PSM模式下,模组完成数据收发后进入深度睡眠,网络侧不再临时寻呼它,相当于手机熄屏后直接关机断网,等设备主动唤醒或者定时位置更新时再恢复连接。代价是下行数据不能随时随地到达。

eDRX则温和一些,模组不会完全断网,而是把监听寻呼的间隔拉长到几十秒甚至几分钟级别,让下行消息延迟可控,但功耗相比PSM还是偏高。

3.2 实际参数配置方法

这个插座项目的配置逻辑是:对下行实时性要求低,所以直接上PSM。远程开关指令本身是通过云平台下发的,用户按一下App按钮,平台向设备推送指令。如果设备处于PSM深睡,指令可能延迟到下次唤醒才收到,这个延迟对插座场景来说可以接受,毕竟不是开关灯这种瞬间操作。

BC26配置PSM的AT指令如下:

/* 开启PSM,设置TAU定时器和激活定时器 */ /* TAU定时器值要根据网络侧允许范围来,配太大可能被网络拒绝 */ at_execute("AT+CPSMS=1,,,\"00100100\",\"00000101\"", "OK", 500);

TAU定时器的数值不是随便填的,它决定了设备最长可以睡多久不主动唤醒。配置前我特意咨询了模组技术支持,确认了当前运营商网络允许的最大TAU范围,然后取了一个折中值。这个值必须和上云平台的设备保活机制配合,如果平台侧认为设备已经掉线而实际只是PSM睡着了,那就会出现平台显示离线、设备实际正常的乌龙。

eDRX我没有启用,因为它和PSM互斥性比较强,对室温采集这种定时上报业务,纯PSM方案最简洁。如果你的产品需要随时响应下行指令,再研究eDRX,那个参数和网络模板绑定,各家模组手册差异也比较大。

3.3 实测功耗数据与上报周期选择

功能稳定后,我专门用功耗仪测了一组数据。设备在市电供电下,重点看的是BC26模组的峰值电流和整机纹波,为电源选型留余量。

实测下来,整机休眠态电流在几十微安级别,主要是MCU和传感器。唤醒进入发送流程后,模组瞬时电流能到200mA左右,持续几百毫秒,整个上报窗口大约2~3秒。这个峰值对3.3V电源来说是不小的冲击,如果开关电源余量不足,会导致电压跌落,模组在弱信号下重传时更容易失败。

上报周期的选择,我最后定在15分钟一次。这个频率对室温监控足够,云平台显示曲线不稀疏,同时整机功耗和网络流量占用都在合理范围内。如果有设备装到信号很弱的区域,发送延时和重传次数会增加,平台侧要给它设置更长的“失联容忍时间”,不能一刀切。

我在代码里把上报周期做成可远程配置的参数,通过MQTT下行topic下发。这样运营阶段可以根据用户反馈动态调整,比如有人觉得反馈太慢,就把周期调短到5分钟;有人安装环境信号差,就调长到30分钟减少重传次数。这个设计对批量运营帮助很大。

4. 量产阶段:天线、校准、产测一个都不能少

4.1 生产测试流程怎么设计

从样机到量产,第一个要解决的是产测流程。没有产测,就不能保证每一台出厂的设备都能正常入网、正常上报。这一步如果依赖人工看串口日志,效率低且容易漏检。

我做的产测流程分三层:裸板测试、整机测试、云端联调。

裸板阶段,通过测试治具的探针接触板子上的测试点,检查电源电压、MCU晶振、I2C总线、继电器驱动电路是否正常。这里能筛掉大部分虚焊、错料问题。

整机阶段,设备已经装进外壳,通过预留的测试串口连接电脑,跑一套自动化测试脚本。脚本烧进设备的测试固件,然后自动执行:读取传感器ID、触发继电器吸合释放、查询BC26信号和网络注册状态、尝试连接云平台并发布一条测试消息。

云端联调则是最后一关。设备上报一条带测试标记的消息,云平台收到后回调产测系统,自动比对设备SN和IMEI绑定关系,全部正确才判定通过。这一步很多人会省略,但恰恰是它拦住了最麻烦的一类问题:设备能联网、能上报,但后台看到的设备ID是错的。

4.2 天线一致性与射频调试

NB-IoT工作在低频段,天线尺寸偏大,插座外壳又小,天线设计是量产阶段最容易出偏差的环节。样机阶段用手工焊接的弹簧天线,性能跑得好好的,一到批量物料批次不同,信号强度参差不齐。

我们用网络分析仪逐批抽测天线座的S11参数,看谐振点是否落在目标频段。如果谐振点偏移,先查天线物料批次差异——有些供应商生产的弹簧天线批次一致性差,同一型号两批货阻抗能差出不少。其次是检查装配环节,天线贴近金属外壳或者被电源线压住,驻波比会明显恶化。

产线还发现了装配方向问题:天线周围有一侧是塑料外壳,另一侧挨着继电器模块,设备插到墙上不同朝向时信号会有几dBm波动。最后解决方案是给天线规划了专门的净空区,并在结构件上做定位卡槽,装配时保证天线位置固定。

4.3 温度传感器是否需要逐台校准

数字温度传感器出厂已经校准过,理论上不需要产线逐台校准。但量产阶段我还是加了两个检查项:一是传感器I2C地址读取是否稳定,防止虚焊导致地址漂移;二是在产线恒温室里抽检温漂。

为什么抽检而不是全检?因为数字传感器的一致性比NTC好太多,全检性价比低。但抽检不能省,我遇到过某个批次传感器在40度高温环境下读数整体偏高0.4度的案例,虽然没有超出精度规格,但云平台上所有设备横向对比时,这批设备的数据明显有系统偏差。抽检能把这类批次性问题提前暴露出来。

如果当初用NTC方案,那就必须逐台校准了,NTC的B值离散性大,批量一致性靠物料筛选和分点校准撑着,产线成本会高一大截。这也是我选数字传感器的一个隐性原因。

4.4 固件批量烧录与SN管理

量产固件管理比大部分人想的重要。产线上同一批板子可能要做多个地区的版本,或者中间改了天线匹配、改了上报逻辑,必须确保每台设备烧的是正确的固件。

我把固件版本号放到编译时注入的宏定义里,同时把设备SN烧录到MCU的独立Flash区,和固件分离。这样即使后续OTA升级刷了新固件,SN不会丢。SN又和产测时绑定的IMEI、证书信息放在一起,云端校验时缺一不可。

批量烧录用的是产线烧录器,配合Hex文件直接烧录,比Bootloader串口下载快得多。但Hex文件里如果带完整地址段,烧录时间会变长,所以我会让编译脚本裁剪出应用区段,只烧录必要部分。这个优化看着小,一天产几千台的时候能节约一个多小时烧录时间,效率提升很明显。

5. 开发过程踩过的三个坑

5.1 弱电箱里的“失踪”信号

项目测试阶段有一台样机装在客户现场弱电箱里,后台显示设备每隔几小时就离线一次。现场排查发现,弱电箱是金属外壳,设备装进去之后天线贴着金属底板,信号强度从正常值掉到临界值,一遇到干扰就脱网。

这个问题暴露了一个产品定位失误:我们默认用户会把插座装在开阔墙面上,根本没考虑弱电箱安装场景。后来在天线上做了两个改动:一是把内置天线改成可外接FPC天线,用IPEX座连接,安装空间受限时可以把天线拉出来贴在塑料面板内侧;二是固件里增加信号弱告警,平台连续N次收到低信号等级上报,就自动生成工单提醒检查安装位置。

这个插曲也让我养成了一个习惯:硬件设计阶段就找真实安装场景测试,不要只在自己办公桌上测。办公桌信号好,什么都测不出来。

5.2 批量生产时的AT握手偶发失败

产线测试架测试某批次板子时,大概有2%的设备第一次AT指令无响应,必须手动断电重启才好。这批板子用的MCU和之前样机一模一样,我一度怀疑是模组物料问题。

逐台排查后发现,问题出在MCU上电初始化和BC26上电初始化之间的时序。MCU跑得快,上电几百毫秒后就开始发AT,但BC26这时候还没完成内部初始化,串口根本没起来。样机阶段因为每次都是接调试器慢慢跑,问题被掩盖了;产线测试架通电后立刻跑测试脚本,时序冲突就暴露了。

修复方式很简单,把BC26的PWRKEY拉低时间加长到700ms,同时MCU侧增加“发送AT直到返回OK”的握手循环。之后这批板子复测,失败率降到零。

5.3 继电器闭合瞬间温度跳变

有用户反馈,每次插座的继电器吸合后,手机App上显示的室温会瞬间跳高0.5度左右,过一会又恢复。复现后发现,继电器吸合瞬间的电流冲击通过电源网络串扰到温度传感器的I2C总线上,导致读取到错误数据,时间上刚好和继电器动作重合。

这个问题的根治是硬件改了采样电路,加了滤波电容;软件上也做了三重保护:继电器动作后延迟200ms再采样、滑窗滤波剔除突变值、单次采样失败重试3次。三层下来,这个现象彻底消失。

这类问题给我最大的教训是:软硬件问题经常混在一起,只改软件不硬,只改硬件太慢。两者同时下手才最快。

6. NB-IoT插座常见问题速查表

现象可能原因排查方向
设备迟迟无法注册网络SIM卡未插好/卡未激活检查CPIN返回值,确认物联网卡资费状态
信号值极低但偶尔能上报天线贴金属、装配压线、安装位置在死角用网络分析仪测S11,调整天线净空区和安装方向
AT指令偶发超时模组启动未完成、串口配置不一致加长PWRKEY时间,改为AT握手重试循环
温度读数跳动继电器动作干扰、I2C毛刺、传感器自热采样避开继电器切换,软硬件滤波,延长采样间隔
MQTT频繁断连网络不稳定、PDP上下文被释放、心跳超时配置合理保活周期,断线后主动重连,必要时冷复位模组
平台显示在线但收不到响应设备处于PSM睡眠明确PSM期间下行延迟机制,必要时用eDRX
批量产测设备上报ID混乱SN和IMEI绑定关系不一致产测增加云端联调环节逐台校验

排查这类问题,我的通用顺序是:先查供电,再查信号,然后查串口日志,最后查云平台数据。不要在不确定供电和信号的情况下直接怀疑代码逻辑,物联网设备90%的“看起来像代码问题”其实都是物理链路问题。

还有一个细节:现场排查时,串口日志一定要带时间戳保存下来。NB-IoT设备的问题大多是偶发性的,没有日志根本没法定位。我在固件里加了一个环形日志区,把最近50条关键AT返回和事件记录在Flash里,远程排查时可以让设备把日志作为一条特殊消息上报。这个功能救了不止一次售后。


最后再分享一个量产阶段的心得:这个项目最花时间的反而不是写代码,而是让设备在“用户不会按照你的设想去安装”的情况下还能稳定工作。我的体会是,样品阶段跑通功能只算完成了三成,剩下七成都在处理信号、装配、产测和售后这些看起来“不硬核”的事情。但恰恰是这些部分,决定了一个项目能不能真正落地。如果你也正在推一个NB-IoT项目,提前把产测流程、SN管理、弱信号告警和远程日志纳入开发计划,后面会少熬很多个夜。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询