前言
由于之前自己接触 NB-IOT 模块,当时用的是 BC26,看到这块开发板也带着 NB IOT 的字样,于是也就有了这篇评测~
开发板概况打开快递后,映入眼帘的是一个黑色的包装盒子,如下所示: 我们打开盒子可以看到有如下几件东西: 通过包装就可以看到这个板子支持WiFi、BT(蓝牙)、NB-IOT(窄带物联网通信)、GNSS(全球导航卫星系统),光是这四个就足以看出这块板子的强大,接下来看啊可能板子的实际图片,如下所示: 可以看到元器件排布的很紧密,整块板子很小,给人看起来就很精致的感觉,除了正面有元器件以外,背面也有元器件,如下图所示: 同样整个背面的元器件排布的也很紧凑,有 SIM 卡插槽,也有引出的 IO 口,设计的非常的精致,下面是正面和背面元器件的概况图: 要使得模块能够正常工作,需要连接上天线和 SIM 卡,连接示意图如下所示: 组装图到此,基本就对板子的一个大体概况有了一个基本的认识,那接下来要把当前这个板子用起来,自然就需要当前板子的相关资料,目前有的资料有视频资料和文档资料,下面给出两处资料的链接: 有了资料了那就可以进行实操了,接下来看我们如何一步一步将这块板子玩起来。 开发工具的安装再进行安装 IDE 之前,需要安装一个驱动,驱动安装包在教程中可以找到,下面是安装的示意图: image-20201130214413048首先,要能够驱动当前的板子,那么就需要添加开发板驱动的 URL,添加步骤文件 -> 首选项,然后就打开了如下所示的界面: 添加了网址之后,就需要更新板子信息,按照如下步骤进行更新:工具 -> 开发板 -> 开发板管理器,更新完成后的界面如下图所示: 然后再搜索框搜索 TinkerNode,选择 TinkerNode ,选择版本后进行安装。 到此为止,准备工作就做完了,下面进入代码实验阶段。 代码实验点个灯作为嵌入式开发者来说,在拿到一块板子的时候,第一件想到的事就是点个灯吧,流水灯,呼吸灯,等等等等,这块板子也一样,我们可以看到板子有一颗小灯是留给开发者操作的,如下图所示: 那么如何点亮这颗小灯呢,我们打开 Arduino 的一个示例程序,打开方式如下所示: 打开之后的代码如下所示:
- void setup() {
- // initialize digital pin LED_BUILTIN as an output.
- pinMode(LED_BUILTIN, OUTPUT);
- }
-
- // the loop function runs over and over again forever
- void loop() {
- digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
- delay(1000); // wait for a second
- digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
- delay(1000); // wait for a second
- }
复制代码
如果是接触过 Arduino 的朋友,那么在看到上述这样的代码比较熟悉,但是如果之前没有接触过 Arduino 的朋友在看到这样的代码之后,就会有点懵了,main函数呢?在整个文件中看不到 main函数的存在,其实,这是 Arduino 为了降低开发的门槛,省略掉了一些比较底层的东西,使得更多爱好者能够上手 Arduino 编程。但实际上,main函数是存在的,我们使用搜索工具在软件的安装目录搜索 main函数,可以得到如下的结果: 文件的代码内容如下所示: - #include <Arduino.h>
-
- // Declared weak in Arduino.h to allow user redefinitions.
- int atexit(void (* /*func*/ )()) { return 0; }
-
- // Weak empty variant initialization function.
- // May be redefined by variant files.
- void initVariant() __attribute__((weak));
- void initVariant() { }
-
- void setupUSB() __attribute__((weak));
- void setupUSB() { }
-
- int main(void)
- {
- init();
-
- initVariant();
-
- #if defined(USBCON)
- USBDevice.attach();
- #endif
-
- setup();
-
- for (;;) {
- loop();
- if (serialEventRun) serialEventRun();
- }
-
- return 0;
- }
复制代码
这个时候再来看 setup 和 loop函数,就比较清晰明了了,这也就是为什么要把初始化的内容放到 setup里面去,为什么要把执行的操作放到 loop里面去。紧接着,我们在来看点灯的代码,我们在使用单片机的时候,如果要操做一个 IO 口,那么就需要知道这个 IO 口的端口以及引脚,但是我们在看这段代码的时候,只看到了一个LED_BUILTIN,并没有端口号和引脚号什么的,那是如何做到的呢?其实这也是 Arduino 为了降低门槛做的操作,它将这些引脚的定义都写到了库里面,各个开发板的引脚定义都对应各个开发板的pins_arduino.h文件,下面是在软件的安装目录找到的 pins_arduino.h文件。 下面是文件里的内容: 可以看到LED_BUILTIN的定义在不同的开发板引脚序号也是不相同的,知道了这些底层一些的东西之后,我们回过头来再来看点灯的代码,大体意思就是设置 IO 口的输出模式,然后设置 IO 的电平,最终达到闪烁的效果,将代码按照下述顺序编译并上传之后,就可以在板子上看到小灯闪烁的现象了。 到此,点灯操作到此结束。 连个网设备向云端传输数据在点了个灯之后,这是任何一款嵌入式开发板都具有的基本功能,那作为一款物联网开发板来说,它的特点自然是能够联网并传输数据了,接下来展示的就是开发板联网之后向云端发送数据的示例。首先,我们的云端采用的是 Easy IOT: 点击工作间,进到如下所示的一个界面: 上述图片所示的,我们需要记录如下三个信息,才能让我们的板子连接至云端。 - user:Nkoy_LAMR
- password:HkTslY0Mgz
- Topic:Gm9l_Y0Gg
下面是上传数据的代码: - #include <WiFi.h>
- #include <PubSubClient.h>
- #include "DFRobot_Iot.h"
-
- /* 配置WiFi名和密码 */
- const char * WIFI_SSID = "TP-LINK_C104";
- const char * WIFI_PASSWORD = "ee104109";
-
- /*配置设备认证信息*/
- String Iot_id = "Nkoy_LAMR";
- String Client_ID = "12345";
- String Iot_pwd = "HkTslY0Mgz";
-
- /* 配置 IOT 云平台的IP地址和端口号 */
- String EasyIot_SERVER = "182.254.130.180";
- uint16_t PORT = 1883;
-
- /* 配置要推送或者订阅的 topic */
- const char * pubTopic = "Gm9l_Y0Gg";
-
- DFRobot_Iot myEasyIoT;
- WiFiClient espClient;
- PubSubClient client(espClient);
-
- void connectWiFi()
- {
- WiFi.disconnect();
- delay(100);
- Serial.print("Connecting to");
- Serial.println(WIFI_SSID);
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi connected");
- Serial.print("IP Adderss: ");
- Serial.println(WiFi.localIP());
- }
-
- /*连接到IoT云服务器*/
- void ConnectCloud() {
- while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
- if (client.connect(myEasyIoT._clientId, myEasyIoT._username, myEasyIoT._password)) {
- Serial.println("Connect Server OK");
- } else {
- Serial.print("failed, rc=");
- Serial.print(client.state());
- Serial.println(" Try again in 5 seconds");
- delay(5000);
- }
- }
- }
-
- void setup() {
- // put your setup code here, to run once:
- /*初始化串口,波特率115200*/
- Serial.begin(115200);
-
- /*连接WIFI*/
- connectWiFi();
-
- /*配置需要连接的IoT云服务器(Easy-IoT)*/
- myEasyIoT.init(EasyIot_SERVER, Iot_id, Client_ID, Iot_pwd);
- client.setServer(myEasyIoT._mqttServer, PORT);
-
- /*连接到Easy-IoT*/
- ConnectCloud();
-
- }
-
- void loop() {
- // put your main code here, to run repeatedly:
- /*IoT云服务器断线重连*/
- if (!client.connected()) {
- ConnectCloud();
- }
- client.loop();
-
- /*每隔一段时间向Easy-IoT*/
- Serial.println("Sending message to cloud...");
- client.publish(pubTopic, "Hello");
- Serial.println("Message is sent.");
- delay(10000);
- }
复制代码
上述的代码也很好理解,就是每隔一段时间向云端发送 Hello,我们打开云端可以看到云端也确实接受到了设备给它发送的数据,如下所示: 到这,设备端向云端发送数据的操作就完成了,那么云端是如何向设备端发送数据的呢?那来看接下来的叙述。 云端向设备端发送数据云端向设备端发送数据,同样的,先贴出代码: - #include <WiFi.h>
- #include <PubSubClient.h>
- #include "DFRobot_Iot.h"
-
- /*配置WIFI名和密码*/
- const char * WIFI_SSID = "TP-LINK_C104";
- const char * WIFI_PASSWORD = "ee104109";
-
- /*配置设备的认证信息*/
- String Iot_id = "Nkoy_LAMR";
- String Client_ID = "12345";
- String Iot_pwd = "HkTslY0Mgz";
-
- /*配置IoT云平台的IP地址和端口号*/
- String EasyIot_SERVER = "182.254.130.180";
- uint16_t PORT = 1883;
-
- /*配置要推送(Publish)或订阅(Subscribe)的topic*/
- const char * subTopic = "Gm9l_Y0Gg";
-
- DFRobot_Iot myEasyIoT;
- WiFiClient espClient;
- PubSubClient client(espClient);
-
- /*连接WiFi*/
- void connectWiFi() {
- WiFi.disconnect();
- delay(100);
- Serial.print("Connecting to ");
- Serial.println(WIFI_SSID);
- WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
- while (WiFi.status() != WL_CONNECTED) {
- delay(500);
- Serial.print(".");
- }
- Serial.println();
- Serial.println("WiFi connected");
- Serial.print("IP Adderss: ");
- Serial.println(WiFi.localIP());
- }
-
- /*连接到IoT云服务器*/
- void ConnectCloud() {
- while (!client.connected()) {
- Serial.print("Attempting MQTT connection...");
- if (client.connect(myEasyIoT._clientId, myEasyIoT._username, myEasyIoT._password)) {
- Serial.println("Connect Server OK");
- } else {
- Serial.print("failed, rc=");
- Serial.print(client.state());
- Serial.println(" Try again in 5 seconds");
- delay(5000);
- }
- }
- }
-
- /*回调函数。当从订阅的topic收到消息时,该函数被调用。*/
- void callback(char * topic, uint8_t * payload, unsigned int len) {
-
- /*显示收到的topic名称和消息内容*/
- Serial.print("Recevice [Topic:");
- Serial.print(topic);
- Serial.print("] ");
- for (int i = 0; i < len; i++) {
- Serial.print((char)payload);
- }
- Serial.println();
- }
-
- void setup() {
- /*初始化串口,波特率115200*/
- Serial.begin(115200);
-
- /*连接WIFI*/
- connectWiFi();
-
- /*配置需要连接的IoT云服务器(Easy-IoT)*/
- myEasyIoT.init(EasyIot_SERVER, Iot_id, Client_ID, Iot_pwd);
- client.setServer(myEasyIoT._mqttServer, PORT);
-
- /*配置回调函数*/
- client.setCallback(callback);
-
- /*连接到Easy-IoT*/
- ConnectCloud();
-
- /*订阅(Subscribe)指定topic*/
- client.subscribe(subTopic);
- Serial.print("Topic:");
- Serial.print(subTopic);
- Serial.println(" subscribed!");
- }
-
- void loop() {
- /*IoT云服务器断线重连*/
- if (!client.connected()) {
- ConnectCloud();
- }
- client.loop();
- }
复制代码
代码阅读起来逻辑很清晰,就不再这里赘述了,我们通过运算向设备端发送123456,发送窗口如下如图所示: 发送了之后,我们将接受到的数据用串口打印出来,可以看到如下所示的消息: 说明数据发送是没有问题的。到此,就基本完成了,但是实际上这整个过程对于一个嵌入式开发者是存在很多疑问的,就拿设备端向云端发送数据这一段来讲,下面的这三个头文件在哪里,当前所使用的 IDE 并不能够直接打开这三个头文件,应该如何查看? - #include <WiFi.h>
- #include <PubSubClient.h>
- #include "DFRobot_Iot.h"
复制代码
要查看头文件的原因也很简单,如果不能查看头文件,那么也就不知道如何调用 API 接口,连接 WiFi 的接口,连接云端的接口,这些都是未知的,这要如何写呢?所以,查看头文件是很有必要的,接下来,就介绍如何打开我们所包含的头文件,首先,我们得知道路径,按照如下方式打开图示的选项。 打开这两个之后,我们在编译的时候,就可以看到相关信息,如下图所示: 我们按照这个信息进行查找一下,并用 VSCODE 打开,打开界面如下图所示: 可以找到.h文件以及对应的 .cpp 文件,也就知道了对应的实现,对应的也就知道了相应的接口。 结论上述就是一个基本的介绍了,当然这个板子的功能那么强大,还有很多待探索的功能,此次的开箱评测就到这里啦~
|