驴友花雕 发表于 2021-9-7 16:40:02

IRQ:PSM休眠唤醒管脚,当模块处于PSM低功耗模式下,将该管脚拉高以唤醒模块。连接示意图如下:




驴友花雕 发表于 2021-9-7 16:42:57

中断唤醒实验实际接线图





驴友花雕 发表于 2021-9-7 19:14:24

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十二:串口监视器上可以看到NB模块被PSM周期性唤醒进入

实验开源代码

/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十二:串口监视器上可以看到NB模块被PSM周期性唤醒进入
实验接线:
BC20       UNO
VIN      5V
GND      GND
SCL      A5
SDA      A4
ISR      D2
*/

#include "DFRobot_BC20_Gravity.h"

//RGB有7种颜色可供选择
#defineRED 0
#defineBLUE 1
#defineGREEN 2
#defineYELLOW 3
#definePURPLE 4
#defineCYAN 5
#defineWHITE 6

//IIC通讯
#define USE_IIC

//硬件串口通讯
//#define USE_HSERIAL

//软件串口通讯
//#define USE_SSERIAL

DFRobot_BC20_IIC myBC20(0x33);

/*
   唤醒UNO,
   模块上的 IRQ 引脚应连接到 WAKEUP_PIN
*/
#define WAKEUP_PIN 2

void setup() {
Serial.begin(115200);
myBC20.LED_OFF();

//初始化 BC20
Serial.print("正在启动BC20,请稍等...... ");
myBC20.changeColor(RED);
while (!myBC20.powerOn()) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("BC20 启动成功!");

//检查 SIM 卡是否插入
Serial.println("正在检查SIM卡……");
myBC20.changeColor(GREEN);
while (!myBC20.checkNBCard()) {
    Serial.println("请插入NB SIM卡!");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("SIM 卡检查OK!");

//打印 IMEI、ICCID 和 IMSI
myBC20.getGSN(IMEI);
Serial.print("BC20 IMEI: ");
Serial.println(sGSN.imei);
Serial.print("SIM card ICCID:");
Serial.print(myBC20.getQCCID());
Serial.print("SIM card IMSI: ");
Serial.println((char *)myBC20.getIMI());

/*
   模块将自动尝试连接到网络(移动站)。
   检查它是否已连接到网络。
*/
Serial.println("正在连接网络...");
myBC20.changeColor(BLUE);
while (myBC20.getGATT() == 0) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("网络已连接!");

//开启 PSM 模式(PSM 默认开启)
myBC20.setPSMMode(ePSM_ON);


   /*
      深度/轻度睡眠模式。(CPU)
      处于深度睡眠模式时,BC20 不会响应来自主控面板的任何 AT 命令
      直到被STM32唤醒(再次BC20退出PSM)
      当进入 Light Sleep Mode 时,BC20 仍然可以接收来自 ESP32 的 AT 命令。
      但是,它的功耗比前者要大。
*/
myBC20.configSleepMode(eSleepMode_DeepSleep);
}

void loop() {

/*
    控制器和 BC20 由 UNO(在模块上)桥接。
    要将模块置于低功耗模式,
    将 UNO 置于深度睡眠模式。
    BC20 将自动进入最低功耗(PSM + 深度睡眠模式)。
    要唤醒模块,
    先唤醒UNO,再唤醒BC20。
*/

// 使UNO进入睡眠模式。
if (!myBC20.stmLowpower()) {
    Serial.println("UNO进入睡眠模式!");
}

delay(30000);

//唤醒UNO
Serial.println("唤醒UNO!");
//IRQ 的上升沿唤醒 UNO
myBC20.stmWakeup(WAKEUP_PIN);

//从 PSM 和深度睡眠模式唤醒 BC20
Serial.print("BC20正在醒来......");
while (!myBC20.BC20Wakeup()) {
    Serial.print(".");
    delay(1000);
}
Serial.println("OK");
delay(10000);
}

驴友花雕 发表于 2021-9-7 19:16:07

实验串口返回情况


驴友花雕 发表于 2021-9-7 20:12:19

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十三:在串行监视器上循环低功耗唤醒,然后将消息上传到云端

实验开源代码

/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十三:在串行监视器上循环低功耗唤醒,然后将消息上传到云端
实验接线:
BC20       UNO
VIN      5V
GND      GND
SCL      A5
SDA      A4
ISR      D2
*/

#include "DFRobot_BC20_Gravity.h"

//RGB有7种颜色可供选择
#defineRED 0
#defineBLUE 1
#defineGREEN 2
#defineYELLOW 3
#definePURPLE 4
#defineCYAN 5
#defineWHITE 6

//配置设备证书信息
char* Iot_id = "wGkCJkIng";
char* Client_ID= "BC20 NB-IoT";
char* Iot_pwd    = "QMkC1kInRz";

//配置域名和端口号
char* EasyIot_SERVER = "182.254.130.180";
char* PORT = "1883";

//设置需要发布的设备编号
char* pubTopic = "hJmOvRIng";

//IIC通讯
#define USE_IIC

//硬件串口通讯
//#define USE_HSERIAL

//软件串口通讯
//#define USE_SSERIAL

DFRobot_BC20_IIC myBC20(0x33);

//连接IRQ唤醒模块
#define WAKEUP_PIN 2

void ConnectCloud() {
Serial.print("尝试MQTT连接... ");
myBC20.changeColor(YELLOW);
while (!myBC20.connected()) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);

    if (myBC20.connect(Client_ID, Iot_id, Iot_pwd)) {
      Serial.println("服务器可用");
    } else {

      //用于检测设备与服务器的连接
      if (myBC20.getQMTCONN())
      break;
    }
}
}

void setup() {
Serial.begin(115200);
myBC20.LED_OFF();

//初始化 BC20
Serial.print("正在启动BC20,请稍等...... ");
myBC20.changeColor(RED);
while (!myBC20.powerOn()) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("BC20 启动成功!");

//检查 SIM 卡是否插入
Serial.println("正在检查SIM卡……");
myBC20.changeColor(GREEN);
while (!myBC20.checkNBCard()) {
    Serial.println("请插入NB SIM卡!");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("SIM 卡检查OK!");

/*如果你使用的是大内存主控,你可以开启
    以下功能可查看SIM卡详情
    打印IMEI、ICCID和IMSI */
//myBC20.getGSN(IMEI);
//Serial.print("BC20 IMEI: ");
//Serial.println(sGSN.imei);
//Serial.print("SIM card ICCID:");
//Serial.print(myBC20.getQCCID());
//Serial.print("SIM card IMSI: ");
//Serial.println((char *)myBC20.getIMI());

/*
      模块将自动尝试连接到网络(移动站)。
      检查它是否已连接到网络。
*/
Serial.println("正在连接网络...");
myBC20.changeColor(BLUE);
while (myBC20.getGATT() == 0) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("网络已连接!");

Serial.println("连接到DFRobot Easy-IoT");

//配置物联网服务器
myBC20.setServer(EasyIot_SERVER, PORT);
Serial.println("服务器可用!");

//连接DFRobot Easy-IoT
ConnectCloud();
Serial.println("云连接成功!");

//启用 PSM(调制解调器)
myBC20.setPSMMode(ePSM_ON);

//启用深度睡眠模式(CPU)
myBC20.configSleepMode(eSleepMode_DeepSleep);
}

void loop() {
Serial.println("发送消息到云端... ");
myBC20.publish(pubTopic, "Hello");
Serial.println("消息已发送");

/*
    控制器和 BC20(NB-IoT 模块)由 UNO 桥接。
    要将模块置于低功耗模式,
    只需将 UNO 置于深度睡眠模式即可。
    BC20 将自动达到最低功耗(PSM + 深度睡眠模式)。
    要唤醒模块,
    先唤醒UNO,再唤醒BC20。
*/
if (!myBC20.stmLowpower()) {
    Serial.println("UNO进入睡眠模式!");
}

//唤醒间隔
delay(60000);

// IRQ 的上升沿唤醒 UNO
myBC20.stmWakeup(WAKEUP_PIN);
Serial.println("UNO退出睡眠模式!");
//唤醒 BC20
myBC20.changeColor(WHITE);
while (!myBC20.BC20Wakeup()) {
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("BC20 成功退出 PSM!");
}

驴友花雕 发表于 2021-9-7 20:17:35

在Easy-IOT平台工作间,可看到收到三条信息


驴友花雕 发表于 2021-9-7 20:21:06

UNO主板和BC20模块大概休眠50秒后发送一条信息,循环


驴友花雕 发表于 2021-9-7 20:22:56

实验串口返回情况


驴友花雕 发表于 2021-9-7 21:07:29

【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十四:通过Easy-IOT平台发布消息(数字0或1),唤醒BC20模块

实验开源代码

/*
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
项目二十四:通过Easy-IOT平台发布消息(数字0或1),唤醒BC20模块
实验接线:
BC20       UNO
VIN      5V
GND      GND
SCL      A5
SDA      A4
ISR      D2
*/

#include "DFRobot_BC20_Gravity.h"

//RGB有7种颜色可供选择
#defineRED 0
#defineBLUE 1
#defineGREEN 2
#defineYELLOW 3
#definePURPLE 4
#defineCYAN 5
#defineWHITE 6

//配置参数休眠模式
#defineSLEEP_INTERVAL 10000
static uint32_t timeStamp = 0;
bool sleepFlag = false;

//配置设备证书信息
char* Iot_id = "wGkCJkIng";
char* Client_ID= "BC20 NB-IoT";
char* Iot_pwd    = "QMkC1kInRz";

//配置域名和端口号
char* EasyIot_SERVER = "182.254.130.180";
char* PORT = "1883";

//设置需要发布的设备编号
char* pubTopic = "hJmOvRIng";

//IIC通讯
#define USE_IIC

//硬件串口通讯
//#define USE_HSERIAL

//软件串口通讯
//#define USE_SSERIAL

DFRobot_BC20_IIC myBC20(0x33);

/*
   每次模块收到消息时,都会调用此函数。
   它将打印消息和相应的主题。
*/
void callback(char * topic, uint8_t * payload, unsigned int len) {
Serial.print("接收[主题:");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < len; i++) {
    Serial.print((char)payload);
}
Serial.println();
timeStamp = millis();
sleepFlag = true;
}

void ConnectCloud() {
Serial.print("尝试MQTT连接...");
while (!myBC20.connected()) {
    Serial.print(".");
    if (myBC20.connect(Client_ID, Iot_id, Iot_pwd)) {
      Serial.println("连接服务器正常");
    } else {

      //用于检测设备与服务器的连接
      if (myBC20.getQMTCONN())
      break;
    }
}

while (!myBC20.subTopic('0', '1',pubTopic, '0')) {
    Serial.print(".");
}
Serial.print("主题:");
Serial.print(pubTopic);
Serial.println("已经订阅了!");
}

void setup() {
Serial.begin(115200);
myBC20.LED_OFF();

//启动BC20
Serial.print("正在启动BC20,请稍等...... ");
myBC20.changeColor(RED);
while (!myBC20.powerOn()) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("BC20 启动成功!");

//检查 SIM 卡是否插入
Serial.print("检查SIM卡...");
myBC20.changeColor(GREEN);
while (!myBC20.checkNBCard()) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("OK!");
/*如果你使用的是大内存主控,你可以开启
   *以下功能可查看SIM卡详情
   *打印IMEI、ICCID和IMSI */
//myBC20.getGSN(IMEI);
//Serial.print("BC20 IMEI: ");
//Serial.println(sGSN.imei);
//Serial.print("SIM card ICCID:");
//Serial.print(myBC20.getQCCID());
//Serial.print("SIM card IMSI: ");
//Serial.println((char *)myBC20.getIMI());

/*
   模块将自动尝试连接到网络(移动站)。
   检查它是否已连接到网络。
*/
Serial.print("正在连接网络......");
myBC20.changeColor(BLUE);
while (myBC20.getGATT() == 0) {
    Serial.print(".");
    myBC20.LED_ON();
    delay(500);
    myBC20.LED_OFF();
    delay(500);
}
Serial.println("已连接!");

//设置回调函数
myBC20.setCallback(callback);

Serial.println("连接到DFRobot Easy-IoT");

//配置物联网服务器
myBC20.setServer(EasyIot_SERVER, PORT);
Serial.println("服务器可用!");

//连接DFRobot Easy-IoT
ConnectCloud();
Serial.println("云连接成功!");

//启用深度睡眠模式
myBC20.configSleepMode(eSleepMode_DeepSleep);

//当进入 PSM 时,BC20 将不会收到任何从云端发出的消息。
//禁用 PSM
myBC20.setPSMMode(ePSM_OFF);

//使模块进入睡眠模式。
if (!myBC20.stmLowpower()) {
    Serial.println("BC20模块进入睡眠模式!");
}
}

void loop() {
myBC20.loop();

/*
   笔记:
   1.云端发送的第一条消息是唤醒模块。
   此消息将被丢弃。
   2.第二条消息和后面的消息将被接收并打印
   在模块进入睡眠模块之前。
   3.当模块再次进入睡眠模式时,又一次唤醒信息
   在发送有效消息之前需要。
   4.确定进入每个睡眠模式的时间间隔
   按 SLEEP_INTERVAL。
*/

if (sleepFlag == true) {
    if (millis() - timeStamp > SLEEP_INTERVAL) {
      sleepFlag = false;

      //使模块进入睡眠模式。
      if (!myBC20.stmLowpower()) {
      Serial.println("BC20模块进入睡眠模式!");
      }
    }
}
}

驴友花雕 发表于 2021-9-7 21:09:13

通过Easy-IOT平台发布消息(数字0或1),唤醒BC20模块



驴友花雕 发表于 2021-9-7 21:09:58

实验串口返回情况


驴友花雕 发表于 2021-9-8 07:51:27

本帖最后由 驴友花雕 于 2021-9-8 07:52 编辑

Arduino 系列传感器和执行器模块实验目录清单:
一块扩展板完成Arduino的10类37项实验(代码+图形+仿真)
https://mc.dfrobot.com.cn/thread-280845-1-1.html
连杆形式的腿机构十一种:盘点机器人行走背后的机械原理
https://mc.dfrobot.com.cn/thread-308097-1-1.html
【花雕动手做】超低成本,尝试五十元的麦克纳姆轮小车!
https://mc.dfrobot.com.cn/thread-307863-1-1.html
【花雕动手做】超迷你哦,用徽商香烟盒做个智能小车!
https://mc.dfrobot.com.cn/thread-307907-1-1.html
【花雕动手做】太搞笑啦,一支胶管制成二只蠕动机器人
https://mc.dfrobot.com.cn/thread-308046-1-1.html
【花雕动手做】快餐盒盖,极低成本搭建机器人实验平台
https://mc.dfrobot.com.cn/thread-308063-1-1.html
【花雕动手做】特别苗条,使用微波传感器控制的纤细小车
https://mc.dfrobot.com.cn/thread-308866-1-1.html
【花雕动手做】脑洞大开、五花八门的简易机器人66种
https://mc.dfrobot.com.cn/thread-307900-1-1.html

实验一百五十八:QMC5883L电子指南针罗盘模块 三轴磁场传感器GY-271
https://mc.dfrobot.com.cn/thread-308195-1-1.html
实验一百六十三:BMI160 6轴惯性运动传感器 16位3轴加速度+超低功耗3轴陀螺仪I2C/SPI 14LGA
https://mc.dfrobot.com.cn/thread-310371-1-1.html
实验一百六十五:2.4 英寸 TFT LCD 触摸屏模块 XPT2046 PCB ILI9341 240x320 像素 8 位 SPI 串口显示器
https://mc.dfrobot.com.cn/thread-309803-1-1.html
实验一百七十六:6mm大尺寸8x8LED方块方格点阵模块 可级联 红绿蓝白色 可选8级亮度
https://mc.dfrobot.com.cn/thread-309845-1-1.html
实验一百八十三:GY-530 VL53L0X 激光测距 ToF测距 飞行时间测距传感器模块 IIC通信协议
https://mc.dfrobot.com.cn/thread-310273-1-1.html
实验一百八十五:MAX4466声音传感器 驻极体话筒放大器 麦克风可调功放模块 microphone
https://mc.dfrobot.com.cn/thread-310193-1-1.html
实验一百八十九:TDA1308 硅麦克风 数字咪头放大模块 拾音器放大板 楼氏SUNLEPHANT
https://mc.dfrobot.com.cn/thread-310246-1-1.html
实验一百九十三:TCS34725颜色识别传感器 RGB IIC明光感应模块 ColorSensor
https://mc.dfrobot.com.cn/thread-310209-1-1.html
实验二百:RCWL-0515微波雷达感应开关 人体感应 智能感应探测传感器 12-15米远距离2.7G微波检测模块
https://mc.dfrobot.com.cn/thread-310313-1-1.html
实验二百零三:Air724UG合宙 Cat14G模块 DTU物联网UART串口通信数据TCP透传 核心板组合套餐
https://mc.dfrobot.com.cn/thread-310342-1-1.html
实验二百零九:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块 NB-IoT广域低功耗无线通信 GPS/北斗精准定位
https://mc.dfrobot.com.cn/thread-310433-1-1.html


驴友花雕 发表于 2021-9-8 09:02:52

DFRobot_BC20_Gravity库部分函数

/**
   * @用于以布尔返回值打开BC20。
   */
bool powerOn(void);

/**
   * @用于检查是否存在带有bool返回值的NB卡
   */
boolcheckNBCard(void);

/**
   * @对于网络连接,成功返回1,失败返回0
   */
uint8_tgetGATT(void);

/**
   * @用于配置bc20的休眠模式,参数为枚举类型
   */
typedef enum {
    eSleepMode_Disable,   
    eSleepMode_DeepSleep
    eSleepMode_Light   
}eSleepMode_t;

boolconfigSleepMode(eSleepMode_t mode);

/**
   * @获得扩展信号质量
   */
voidgetESQ(void);

/**
   * @获取网络注册状态   
   */
voidgetEREG(void);

/**
   * @获取PDP地址
   */
voidgetGPADDR(void);

/**
   * @对于bc20的远程固件升级,参数为升级的url
   */
boolsetQFOTADL(String url);

/**
   * @用于检测当前设备是否连接
   */
boolconnected();

/***
   * @用于将设备连接到服务器
   */
boolconnect(char * clientID, char * username,char * password,char connectID ='0');

/**
   * @用于检测设备和服务器之间的连接
   */
boolgetQMTCONN(void);

/**
   * @用于连接物联网站点
   */
boolsetServer(char* IPAddress,char* port,char connectID = '0');

驴友花雕 发表于 2021-9-8 09:04:43

DFRobot_BC20_Gravity库部分函数之二

/**
   * @用于向服务器发送消息,参数说明:第一个参数用于指定主题,
   * @第二个参数是要发送的具体数据
   */
boolpublish(char* topic,char* msg);

/**
   * @这个函数用于在服务器发送给订阅者时接收数据
   */
voidloop();

/**
   * @订阅的第三个参数是指定主题
   */
boolsubTopic(char connectID, char msgID, char* topic, char qos);

/**
   * @用于模块电源控制。如果返回值为1,则模块处于供电状态;
   * @如果返回值为0,模块处于掉电状态   
   */
uint8_tgetQGNSSC(void);

/**
   * @用于获取指定的卫星信息,该参数用于指定要获取的信息类型。
   * @参数选择如下:
   */
boolgetQGNSSRD(char* sth);

/**
   * @这两个函数用于控制led灯的亮灭
   */
voidLED_ON();void LED_OFF();

/**
   * @获取NB卡的序列号
   */
voidgetGSN(uint8_t cmd=0);

/**
   * @获取SIM卡号
   */
StringgetQCCID(void);

/**
   * @获取当前网络时间
   */
StringgetCLK(void);

/**
   * @用于通过外部中断唤醒开发板,外部中断引脚输出信号
   */
boolstmWakeup(uint8_t Awake_Pin);

/**
   * @用于获取当前网络信号的强度
   */
voidgetSQ(void);

/**
   * @检查来自 BC20 的数据
   */
voidavailable(void);

/**
   * @发送单个字符到 bc20
   */
voidsendATCMDBychar(void);

/**
   * @Receive bc20 返回的数据
   */
voidreadData(void);

/**
   * @用于处理接收数据的格式
   */
void setCallback(void (*call)(char*, uint8_t*, unsigned int));



驴友花雕 发表于 2021-9-8 09:06:13

DFRobot_BC20_Gravity库部分函数之三

/**
   * @用于控制LED灯的颜色
   * @它的参数是字符串
   * @"LED_R_ON";"LED_R_OFF";
   * @"LED_G_ON";"LED_G_OFF";
   * @"LED_B_ON";"LED_B_OFF";
   * @"LED_P_ON";"LED_P_OFF";
   * @"LED_C_ON";"LED_C_OFF";
   * @"LED_W_ON";"LED_W_OFF";
   * @"LED_B_ON";"LED_Y_OFF";
   */
void controlLED(String str);

void changeColor(uint8_t newColor);

/**
   * @设置低功耗模式
   */
bool setPSMMode(ePSM_t status);
typedef enum {
    ePSM_OFF,
    ePSM_ON,
    ePSM_OFF_ResetParam
} ePSM_t;

/**
    * @启用/禁用深度睡眠唤醒指示
    * @参数是宏观定义的
    * @开或关
   */
bool setQATWAKEUP(uint8_t enable);

/**
   * @进入低功耗模式
   */
void stmLowpower();

/**
   * @发送命令,参数可以是String/char/uint8_t
   * @这些参数由AT指令集决定
   */
void sendATCMD(char* str);

void LEDFlash(String Color);

/**
   * @发送命令,参数可以是String/char/uint8_t
   * @这些参数由AT指令集决定
   */
bool stmWakeup(uint8_t Awake_Pin);

bool BC20Wakeup();

页: 1 2 3 4 5 [6]
查看完整版本: 【Arduino】168种传感器系列实验(209)---移远 BC20 NB+GNSS模块