|
NB-IoT 模块 BC26 实战:低功耗远程数据采集系统

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 BC261¥35
主控板Arduino Nano / ESP32 开发板1¥15-30
NB-IoT 底板BC26 breakout 板(含天线座)1¥20
NB-IoT 天线PCB 天线或外置天线1¥10
SIM 卡电信/移动/联通 NB-IoT 专用卡1¥5/月
温湿度传感器DHT22 / SHT301¥10-25
电压传感器INA2191¥8
杜邦线母对母、公对母若干¥5
面包板830 孔1¥5
锂电池(可选)18650 + TP40561¥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 表示注册被拒绝。需要检查:

  1. SIM 卡是否开通 NB-IoT 功能
  2. 当地是否有 NB-IoT 覆盖
  3. 天线是否接好

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 实测功耗优化建议

  1. 数据采集频率降低:从每分钟一次改为每 15 分钟一次,功耗降 15 倍
  2. 关闭不必要的 AT 查询:每次上电只查一次信号和注册状态
  3. 使用 PSM + 定时唤醒:传感器 + 主控用定时器中断唤醒 BC26
  4. 缩短发送窗口:数据打包尽量小,一次发送完成立即回到 PSM
  5. 主控板也休眠: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)

九、项目扩展

基于这个数据采集节点,你可以继续做:

  1. 多传感器扩展:加土壤湿度、光照、PM2.5 等传感器
  2. 边缘告警:在 Arduino 端设置阈值,超标时才唤醒 BC26 发送告警
  3. 太阳能供电:加太阳能板和充电控制器,实现永久在线
  4. 多节点组网:多个采集点共享一个 BC26,降低单节点成本
  5. 对接智能家居:把采集数据推送到 Home Assistant

总结

NB-IoT BC26 方案的核心优势就三个字:省心。不用搭网关,插上 SIM 卡就能联网,功耗低到可以用电池跑半年。适合农田监测、水质监测、设备巡检这些分散部署、无人值守的场景。

如果你有大规模部署需求(成百上千个节点),建议搭配 LwM2M 协议做设备管理;如果是个人项目,简单的 UDP + 自建服务器就够了。

动手试试吧,有问题欢迎在评论区交流!