物联网 NB-IoT 模块 BC26 实战:低功耗远程数据采集系统
引言
如果你要做远程数据采集,WiFi 和蓝牙覆盖不了,LoRa 又得自己搭网关,那 NB-IoT 可能就是最省事的方案了。运营商基站直接覆盖,插张 SIM 卡就能上网,待机功耗低到离谱。
今天我们就用 Quectel BC26 模块,从零搭一个低功耗远程数据采集节点。文章会涵盖硬件选型、接线、AT 指令调试、功耗优化,以及把数据推送到云平台的完整流程。
一、NB-IoT 是什么?为什么选 BC26?
NB-IoT 技术特点
NB-IoT(窄带物联网)是 3GPP 标准定义的 LPWA(低功耗广域网)技术,工作在授权频段上。它有这几个核心优势:
- 覆盖广:直接复用运营商 4G 基站,不需要自建网关
- 功耗低:PSM 模式下待机电流只有几微安(μA)
- 成本低:模组价格在 30-50 元,SIM 卡套餐每月几块钱
- 连接多:单基站可承载 10 万+设备
为什么选 Quectel BC26?
BC26 是 Quectel(移远通信)推出的 NB-IoT 模组,市面上最主流的型号之一:
| 参数 | BC26 |
|---|---|
| 频段 | B1/B3/B5/B8/B28/B34/B38/B39/B40/B41 |
| 通信接口 | UART(AT 指令) |
| 工作电压 | 3.3V |
| 待机电流(PSM) | ~3.5 μA |
| 发射电流 | ~200 mA(峰值) |
| 封装 | LCC |
| 价格 | 约 35 元 |
BC26 还有升级版 BC260Y(引脚兼容,支持更多频段),但 BC26 已经够用了。如果你在国内用,确认运营商频段匹配——中国电信 B5/B8、中国移动 B3/B5/B8、中国联通 B1/B3/B8。
二、硬件清单
| 部件 | 型号/规格 | 数量 | 参考价格 |
|---|---|---|---|
| NB-IoT 模组 | Quectel BC26 | 1 | ¥35 |
| 主控板 | Arduino Nano / ESP32 开发板 | 1 | ¥15-30 |
| NB-IoT 底板 | BC26 breakout 板(含天线座) | 1 | ¥20 |
| NB-IoT 天线 | PCB 天线或外置天线 | 1 | ¥10 |
| SIM 卡 | 电信/移动/联通 NB-IoT 专用卡 | 1 | ¥5/月 |
| 温湿度传感器 | DHT22 / SHT30 | 1 | ¥10-25 |
| 电压传感器 | INA219 | 1 | ¥8 |
| 杜邦线 | 母对母、公对母 | 若干 | ¥5 |
| 面包板 | 830 孔 | 1 | ¥5 |
| 锂电池(可选) | 18650 + TP4056 | 1 | ¥15 |
总成本约 110-160 元,比 4G 方案便宜一半以上。
三、硬件接线
BC26 模组通过 UART 与 Arduino 通信,接线很简单:
Arduino Nano BC26 Breakout
============ =============
3.3V ---------> VCC(注意!必须 3.3V)
GND ---------> GND
D2 (RX) ---------> TX
D3 (TX) ---------> RX
(电源地和信号地共地)
⚠️ 关键注意:BC26 工作电压是 3.3V,绝对不能接 5V!Arduino Nano 的 UART TX 输出是 5V 电平,需要通过电平转换芯片(如 TXB0104)或者串联 1kΩ 电阻降压。更推荐的做法是用 ESP32(原生 3.3V GPIO)。
传感器接法:
- DHT22:VCC→3.3V,GND→GND,DATA→D4
- INA219:VCC→3.3V,GND→GND,SDA→A4,SCL→A5
四、AT 指令调试
BC26 通过 AT 指令控制。先把模块上电,用串口调试工具(波特率 115200)连接,逐条测试。
4.1 基础连通性测试
// 测试模块是否正常响应
AT
OK
// 查询模块型号
ATI
Quectel
BC26
Revision: BC26JAR02A07
OK
// 查询 SIM 卡状态
AT+CPIN?
+CPIN: READY
OK
// 查询运营商注册状态
AT+CEREG?
+CEREG: 0,1 // 1 = 已注册到本地网络
OK
// 查询信号强度
AT+CSQ
+CSQ: 15,99 // 15 = RSSI 约 -85dBm,信号良好
OK
如果 CEREG 返回 0,2 表示正在搜索网络,0,3 表示注册被拒绝。需要检查:
- SIM 卡是否开通 NB-IoT 功能
- 当地是否有 NB-IoT 覆盖
- 天线是否接好
4.2 数据连接与发送
BC26 支持多种数据传输方式,我们用最简单的 UDP Socket:
// 设置 APN(根据运营商填写)
AT+CGDCONT=1,"IP","ctnet" // 电信
// 或
AT+CGDCONT=1,"IP","cmnbiot" // 移动
// 激活 PDP 上下文
AT+CGACT=1,1
OK
// 查询 IP 地址
AT+CGPADDR=1
+CGPADDR: 1,"10.174.xx.xx"
OK
// 创建 UDP Socket
AT+NSOCR=DGRAM,17,0,1
0 // Socket 编号 = 0
OK
// 发送数据到服务器(IP + 端口)
AT+NSOST=0,"120.78.xxx.xxx",5683,10,0102030405060708090A
+NSOST: 0,10,10 // Socket 0, 请求 10 字节, 发送 10 字节
OK
实际项目中,数据格式推荐用 CoAP + LwM2M 协议,这是 NB-IoT 最常用的物联网协议,专为低带宽场景设计。
五、Arduino 代码实现
我们用 SoftwareSerial 库与 BC26 通信,采集传感器数据后通过 UDP 发送到服务器。
#include <SoftwareSerial.h>
#include <SimpleDHT.h>
#include <Wire.h>
#include <Adafruit_INA219.h>
// BC26 串口
SoftwareSerial bc26Serial(2, 3); // RX, TX
// 传感器
SimpleDHT22 dht22(4);
Adafruit_INA219 ina219;
// 服务器配置(换成你自己的)
const char* SERVER_IP = "120.78.xxx.xxx";
const int SERVER_PORT = 5683;
// Socket 编号
int socketId = -1;
void setup() {
Serial.begin(115200);
bc26Serial.begin(115200);
// 初始化传感器
ina219.begin();
ina219.setCalibration_32V_2A();
delay(3000); // 等待 BC26 上电
Serial.println("=== BC26 NB-IoT 数据采集节点 ===");
// 1. 检查模块
sendAT("AT", 1000);
// 2. 检查 SIM
sendAT("AT+CPIN?", 1000);
// 3. 检查网络注册
sendAT("AT+CEREG?", 1000);
// 4. 检查信号
sendAT("AT+CSQ", 1000);
// 5. 设置 APN
sendAT("AT+CGDCONT=1,\"IP\",\"ctnet\"", 2000);
// 6. 激活 PDP
sendAT("AT+CGACT=1,1", 5000);
// 7. 创建 UDP Socket
String resp = sendAT("AT+NSOCR=DGRAM,17,0,1", 2000);
// 解析返回的 socket ID
socketId = 0; // 通常返回 0
Serial.println("初始化完成,开始采集...");
}
void loop() {
// 读取传感器数据
float temperature, humidity;
int err = dht22.read2(&temperature, &humidity, NULL);
if (err != SimpleDHTErrSuccess) {
Serial.println("DHT22 读取失败");
}
float busVoltage = ina219.getBusVoltage_V();
float current_mA = ina219.getCurrent_mA();
float power_mW = ina219.getPower_mW();
// 构建数据包(简化 JSON)
String data = String("{") +
"\"t\":" + String(temperature, 1) + "," +
"\"h\":" + String(humidity, 1) + "," +
"\"v\":" + String(busVoltage, 2) + "," +
"\"i\":" + String(current_mA, 0) +
"}";
Serial.println("数据: " + data);
// 通过 NB-IoT 发送
sendNBIoTData(data);
// 低功耗:每 15 分钟采集一次
delay(15 * 60 * 1000);
}
// 发送 AT 指令并返回响应
String sendAT(String cmd, int timeout) {
Serial.println(">> " + cmd);
bc26Serial.println(cmd);
String response = "";
unsigned long start = millis();
while (millis() - start < timeout) {
while (bc26Serial.available()) {
char c = bc26Serial.read();
response += c;
}
}
Serial.println("<< " + response);
return response;
}
// 通过 BC26 发送数据
void sendNBIoTData(String data) {
String hexData = stringToHex(data);
String cmd = String("AT+NSOST=") +
String(socketId) + "," +
"\"" + SERVER_IP + "\"," +
String(SERVER_PORT) + "," +
String(data.length()) + "," +
hexData;
String resp = sendAT(cmd, 5000);
if (resp.indexOf("+NSOST") >= 0) {
Serial.println("数据发送成功");
} else {
Serial.println("发送失败,重连...");
reconnect();
}
}
// 字符串转十六进制
String stringToHex(String str) {
String hex = "";
for (int i = 0; i < str.length(); i++) {
hex += String(str.charAt(i), HEX);
}
hex.toUpperCase();
return hex;
}
// 重连逻辑
void reconnect() {
Serial.println("尝试重新连接...");
sendAT("AT+CGACT=0,1", 2000);
delay(1000);
sendAT("AT+CGACT=1,1", 5000);
}
六、功耗优化
NB-IoT 的最大优势就是低功耗。BC26 支持两种省电模式:
6.1 PSM(Power Saving Mode)
PSM 模式下,模块进入深度睡眠,待机电流仅 ~3.5 μA。唤醒后需要重新附着网络。
// 启用 PSM,Active Time=0(发送完立即睡眠),
// T3324=300 秒周期唤醒
AT+CPSMS=1,,,"00000000","01000101"
OK
功耗对比:
| 模式 | 电流 | 说明 |
|---|---|---|
| 连接态 | ~200 mA | 发送数据时 |
| Idle 模式 | ~5 mA | 保持网络附着 |
| PSM 模式 | ~3.5 μA | 深度睡眠 |
用 2000 mAh 锂电池,如果每小时唤醒发送一次数据(每次 5 秒连接态),理论续航 超过 6 个月。
6.2 eDRX(扩展非连续接收)
eDRX 模式下设备保持网络附着,但周期性地关闭接收。适合需要快速响应的场景:
// 启用 eDRX,周期 20.48 秒
AT+CEDRXS=1,5,"0101"
OK
6.3 实测功耗优化建议
- 数据采集频率降低:从每分钟一次改为每 15 分钟一次,功耗降 15 倍
- 关闭不必要的 AT 查询:每次上电只查一次信号和注册状态
- 使用 PSM + 定时唤醒:传感器 + 主控用定时器中断唤醒 BC26
- 缩短发送窗口:数据打包尽量小,一次发送完成立即回到 PSM
- 主控板也休眠:Arduino 用
LowPower库进入 Power Down 模式(~10 μA)
七、云平台对接
数据发到服务器后,推荐用以下方案做存储和可视化:
方案一:CoAP + LwM2M 服务器
Leshan 是开源的 LwM2M 服务器,BC26 原生支持:
// 连接到 Leshan 服务器
AT+QLWUL="coap://leshan.eclipseprojects.io:5683"
方案二:MQTT(通过 BC26 TCP)
// 创建 TCP Socket
AT+NSOCR=STREAM,6,0,1
0
OK
// 连接 MQTT Broker
AT+NSOCO=0,"broker.hivemq.com",1883
OK
// 发送 MQTT 数据包(需手动组包或库支持)
方案三:自建 HTTP 后端
UDP 数据发到你的服务器,Node.js 接收后写入 InfluxDB,再用 Grafana 可视化。这个方案我们在第 060 篇文章会详细讲。
八、常见问题排查
问题 1:AT 指令无响应
- 检查接线:TX↔RX 交叉接,不要 TX 接 TX
- 确认波特率:BC26 默认 115200,用
AT+IPR?查询 - 检查供电:BC26 需要 3.3V,电流峰值 200mA,USB 供电可能不够,加电容
问题 2:CEREG 一直返回 0,2(搜索中)
- SIM 卡未开通 NB-IoT 功能 → 联系运营商开通
- 当地无 NB-IoT 覆盖 → 换运营商或换位置测试
- 天线未接或方向不对 → 接好天线,金属外壳内信号衰减严重
问题 3:数据发送失败(NSOST 报错)
- PDP 未激活 → 先执行
AT+CGACT=1,1 - 防火墙阻止 → 确认服务器端口开放,NB-IoT 部分运营商限制特定端口
- 信号太差 →
AT+CSQ查看信号,RSSI < -110dBm 基本无法通信
问题 4:功耗降不下来
- 确认 PSM 已启用:
AT+CPSMS? - 检查是否有后台数据保持连接活跃
- 主控板是否也在休眠
问题 5:收到数据但乱码
- 确认 Hex 编码正确:BC26 的 NSOST 要求十六进制格式
- 检查字节序和编码格式(UTF-8 vs ASCII)
九、项目扩展
基于这个数据采集节点,你可以继续做:
- 多传感器扩展:加土壤湿度、光照、PM2.5 等传感器
- 边缘告警:在 Arduino 端设置阈值,超标时才唤醒 BC26 发送告警
- 太阳能供电:加太阳能板和充电控制器,实现永久在线
- 多节点组网:多个采集点共享一个 BC26,降低单节点成本
- 对接智能家居:把采集数据推送到 Home Assistant
总结
NB-IoT BC26 方案的核心优势就三个字:省心。不用搭网关,插上 SIM 卡就能联网,功耗低到可以用电池跑半年。适合农田监测、水质监测、设备巡检这些分散部署、无人值守的场景。
如果你有大规模部署需求(成百上千个节点),建议搭配 LwM2M 协议做设备管理;如果是个人项目,简单的 UDP + 自建服务器就够了。
动手试试吧,有问题欢迎在评论区交流!