37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的。鉴于本人手头积累了一些传感器和执行器模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里准备逐一动手试试多做实验,不管成功与否,都会记录下来——小小的进步或是搞不掂的问题,希望能够抛砖引玉。
【Arduino】168种传感器模块系列实验(资料代码+仿真编程+图形编程)
实验一百九十三:Gravity: I2C & UART BC20 NB-IoT & GNSS通信模块
NB-IoT广域低功耗无线通信 GPS/北斗精准定位 户外物联网必备
知识点:移远BC20
BC20 是一款高性能、低功耗、多频段、支持 GNSS 定位功能的 NB-IoT 无线通信模块。其尺寸仅为 18.7 mm × 16.0 mm× 2.1 mm,能最大限度地满足终端设备对小尺寸模块产品的需求,同时有效帮助客户减小产品尺寸并优化产品成本。
BC20 在设计上兼容移远通信 GSM/GPRS/GNSS 系列 MC20 模块,方便客户快速、灵活的进行产品设计和升级。BC20提供丰富的外部接口和协议栈,同时支持中国移动 OneNET、中国电信 IoT 以及阿里云 IoT 等物联网云平台,为客户的应用提供极大的便利。
基于先进的 GNSS 技术,BC20 可支持 BeiDou 和 GPS 双卫星导航系统解调算法,使其定位更加精准、抗多路径干扰能力更强,比传统的单 GPS 定位模块具有更多优势。另外,BC20 模块内置 LNA 和低功耗算法:前者保证更高的灵敏度,后者保证低功耗模式下更低的耗流。
相较传统的 NB-IoT + GNSS 方案,BC20 的一体化设计使其体积减少 40 %。凭借其紧凑尺寸、超低功耗和超宽工作温度范围,BC20 在各种应用中占具更大优势;其主要应用领域为:自行车和摩托车防盗、宠物追踪、金融财产追踪及行车记录仪等等。
【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种颜色可供选择
#define RED 0
#define BLUE 1
#define GREEN 2
#define YELLOW 3
#define PURPLE 4
#define CYAN 5
#define WHITE 6
//配置参数休眠模式
#define SLEEP_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[i]);
}
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模块进入睡眠模式!");
}
}
}
}
通过Easy-IOT平台发布消息(数字0或1),唤醒BC20模块
实验串口返回情况
DFRobot_BC20_Gravity库部分函数
/**
* @用于以布尔返回值打开BC20。
*/
bool powerOn(void);
/**
* @用于检查是否存在带有bool返回值的NB卡
*/
bool checkNBCard(void);
/**
* @对于网络连接,成功返回1,失败返回0
*/
uint8_t getGATT(void);
/**
* @用于配置bc20的休眠模式,参数为枚举类型
*/
typedef enum {
eSleepMode_Disable,
eSleepMode_DeepSleep
eSleepMode_Light
}eSleepMode_t;
bool configSleepMode(eSleepMode_t mode);
/**
* @获得扩展信号质量
*/
void getESQ(void);
/**
* @获取网络注册状态
*/
void getEREG(void);
/**
* @获取PDP地址
*/
void getGPADDR(void);
/**
* @对于bc20的远程固件升级,参数为升级的url
*/
bool setQFOTADL(String url);
/**
* @用于检测当前设备是否连接
*/
bool connected();
/***
* @用于将设备连接到服务器
*/
bool connect(char * clientID, char * username,char * password,char connectID ='0');
/**
* @用于检测设备和服务器之间的连接
*/
bool getQMTCONN(void);
/**
* @用于连接物联网站点
*/
bool setServer(char* IPAddress,char* port,char connectID = '0');
DFRobot_BC20_Gravity库部分函数之二
/**
* @用于向服务器发送消息,参数说明:第一个参数用于指定主题,
* @第二个参数是要发送的具体数据
*/
bool publish(char* topic,char* msg);
/**
* @这个函数用于在服务器发送给订阅者时接收数据
*/
void loop();
/**
* @订阅的第三个参数是指定主题
*/
bool subTopic(char connectID, char msgID, char* topic, char qos);
/**
* @用于模块电源控制。如果返回值为1,则模块处于供电状态;
* @如果返回值为0,模块处于掉电状态
*/
uint8_t getQGNSSC(void);
/**
* @用于获取指定的卫星信息,该参数用于指定要获取的信息类型。
* @参数选择如下:
*/
bool getQGNSSRD(char* sth);
/**
* @这两个函数用于控制led灯的亮灭
*/
void LED_ON();void LED_OFF();
/**
* @获取NB卡的序列号
*/
void getGSN(uint8_t cmd=0);
/**
* @获取SIM卡号
*/
String getQCCID(void);
/**
* @获取当前网络时间
*/
String getCLK(void);
/**
* @用于通过外部中断唤醒开发板,外部中断引脚输出信号
*/
bool stmWakeup(uint8_t Awake_Pin);
/**
* @用于获取当前网络信号的强度
*/
void getSQ(void);
/**
* @检查来自 BC20 的数据
*/
void available(void);
/**
* @发送单个字符到 bc20
*/
void sendATCMDBychar(void);
/**
* @Receive bc20 返回的数据
*/
void readData(void);
/**
* @用于处理接收数据的格式
*/
void setCallback(void (*call)(char*, uint8_t*, unsigned int));
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();