备注1:本文翻译自 CNX Software 泰国站的原文。第一部分(本文)会介绍该套件,并展示了如何使用 Arduino 对其进行编程从而将传感器数据传输到 LoRAWAN 网关并将其显示在 Wio 终端上;之后再使用 Grafana 等开源工具在私有 LoRaWAN 网络中处理数据。下一次则会发布展示该套件 AI 功能的相关文章。
备注2:Seeed Studio,即深圳矽递科技股份有限公司,简称“矽递科技”。该公司成立于 2009年,经营范围包括半导体及电子产品、机电设备、计算机、光机电一体化设备的技术开发等。
备注3: Wio 终端即Wio Terminal,是由矽递科技推出的一种基于samd51的微控制器,它由Realtek RTL8720DN支持、可以兼容Arduino和MicroPython,目前只有Arduino支持无线连接。Wio终端本身配备了2.4LCD屏幕、机载IMU(LIS3DHTR)、麦克风、蜂鸣器、microSD卡槽,光传感器和红外发射器(IR 940nm)。除此之外,它还有两个用于Grove生态系统的多功能Grove端口,以及用于更多插件的40个兼容树莓派的引脚GPIO。
备注4:Microchip Technology Incorporated即美国微芯科技公司,简称“微芯半导体”是全球领先的单片机和模拟半导体供应商,为全球数以千计的消费类产品提供低风险的产品开发、更低的系统总成本和更快的产品上市时间。
如今的数字化时代,物联网和大数据的应用更加普遍了。在这些应用的过程中,都需要通过传感器去收集大量的数据。
为了实现数字化转型,矽递科技(Seeed Studio)推出了 SenseCAP K1100 套件。该套件配备了所有必要的传感器和设备,包括 Wio 终端、AI 视觉传感器、LoRaWAN 模块等等。通过这个即插即用的平台,用户就可以轻松地创建出一个传感器,并将其用于数据搜集,从而解决目前面对的各种难题和挑战。
在详细查看SenseCAP K1100 传感器套件之前,我们先一起了解一下相关的定义和专业术语:
IOT即“物联网”,是指连接到互联网的设备网络。它可以让我们通过互联网去控制和使用各种设备,例如:多种开关设备、电器、汽车、手机、通讯工具、农业设备、建筑物、房屋,以及我们日常使用的各种家电。
LoRaWAN是“Long Range Wide Area Network”的缩写,是一种基于 LoRa 协议的无线电技术,是专为低功耗远距离的通信而设计。它在物联网开发领域越来越流行,应用场景很多,例如:连接智能设备。
SenseCAP K1100:是由矽递科技设计的一款紧凑型传感器原型套件,应用了 LoRaWAN 和 AI 技术,其开发的主要目的是为了帮助开发人员和制造商们更简单的去创建物联网原型。通过该套件的 Grove LoRa-E5 模块用户还可以为 Wio 终端添加 LoRaWAN 连接,原本 Wio 终端(Wio Terminal)是只能支持 Wi-Fi 和蓝牙无线通信的。本篇文章中,我会重点介绍:如何通过私有 LoRaWAN 网络去收集传感器数据。
SenseCAP K1100 套件的内容
SenseCAP K1100 套件中包含有一个 Wio 终端(Wio Terminal),它是一个兼容 Arduino 的 HMI 控制器,该控制器带有 WiFi 和蓝牙。
Wio终端的规格:
- MCU – Microchip ATSAMD51P19 Arm Cortex-M4F,运行频率为 120 MHz
- Wi-Fi 和蓝牙 – 瑞昱RTL8720DN Arm Cortex-M4 微控制器,具有双频(2.4 GHz 和 5 GHz)WiFi
- GPIO – 40 针,与树莓派相同的针脚位置
- 板载传感器和功能
- 板载 3 轴数字加速度计 (LIS3DHTR)
- 光传感器
- 麦克风和蜂鸣器
- 红外线发射器
- 2.4英寸液晶屏
- 支持TinyML(人工智能和机器学习)
套件模块部分的规格:
- 基于STM32WLE5JC MCU的LoRa-E5 LoRaWAN模块;射频功率:+20.8 dBm,支持EU868/US915/AU915/AS923/KR920频段
- SHT40温湿度传感器模块
- SGP30 模块作为空气质量传感器(VOC 和 eCO2 气体传感器)
- 土壤水分模块
- 带摄像头的视觉 AI 模块
SenseCAP K1100 传感器的工作原理
SenseCAP K1100 光传感器使用光电作为传感元件,之后通过转换将“被测光”的变化转换为电信号。
SenseCAP K1100 的温度传感器依赖于热电偶方法。它由 2 根金属线组成,可以形成一个电接头。由于塞贝克效应,热电偶会产生与温度相关的电压,该电压也可以解释为测量温度。
SenseCAP K1100 的相对湿度传感器是通过聚胺膜或醋酸聚合物来测量湿度。当薄膜吸水或失水时,两个电极之间的介电常数会发生变化,电容会被记录下来并转换成电信号。
开始评测 SenseCAP K1100 套件
前期准备
准备阶段,需要注意我们接下来会用到以下内容来测量环境数据,并将其发送到私有的 LoRaWAN 网络:
- Wio终端
- USB Type-C 数据线
- LoRa-E5 模块
- SHT40模块
- 一台主机
- 一个 LoRaWAN 网关
- LoRaWAN 云平台
硬件连接
现在,我开始使用 SenseCAP K1100。通过将其连接 SHT40 传感器模块我们就可以测量空气温度和相对湿度,以及 Wio 终端内置传感器和麦克风的光和噪声情况。之后,通过Grove LoRa-E5 模块在开发板和 LoRaWAN 网关之间建立连接。
我们还将使用具有 4G LTE 互联网连接的Dragino LG308 -AS923-TH-EC25 多通道 LoRaWAN 网关。
软件安装及说明
以下是软件部分要遵循的步骤
1、安装 Arduino IDE
2、添加 Wio 终端所需的板文件。在 Arduino 顶部菜单中,转到 tp File -> Preferences并复制/粘贴https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json进入 Additional Boards Manager URLs 框:
3、单击工具 -> 板 -> 板管理器并搜索 Wio 终端。
4、现在转到工具 -> 板并选择板Seeeduino Wio 终端
5、为 SHT40 温湿度传感器添加 Arduino 库。下载文件 arduino-i2c-sht4x.zip,然后转到Sketch -> Include Library -> Add .ZIP Library并选择 arduino-i2c-sht4x
6、下载 Disk91_LoRaE5.zip 后以同样方式添加 LoRa-E5 Arduino 库
7、在 Seeed_Arduino_LCD.zip 中添加 Seeed Arduino LCD 库
8、然后我们修改了 LoRa-SHT40-TFT.ino 示例的代码以使其适应我们的环境,并在 Wio Terminal 显示屏上显示信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 |
// LoRaWAN + SHT40 + Light + Microphone + TFT LCD // by.. Ninephon kongangkab <ninephon9@gmail.com> #include <SoftwareSerial.h> #include <Arduino.h> #include <SensirionI2CSht4x.h> //SHT40 library #include <Wire.h> #include "TFT_eSPI.h" //TFT LCD library TFT_eSPI tft; //Initializing TFT LCD TFT_eSprite spr = TFT_eSprite(&tft); //Initializing buffer SoftwareSerial mySerial(A0, A1); // RX, TX SensirionI2CSht4x sht4x; static char recv_buf[512]; static bool is_exist = false; static bool is_join = false; static int at_send_check_response(char *p_ack, int timeout_ms, char *p_cmd, ...) { int ch; int num = 0; int index = 0; int startMillis = 0; va_list args; memset(recv_buf, 0, sizeof(recv_buf)); va_start(args, p_cmd); mySerial.printf(p_cmd, args); Serial.printf(p_cmd, args); va_end(args); delay(200); startMillis = millis(); if (p_ack == NULL) { return 0; } do { while (mySerial.available() > 0) { ch = mySerial.read(); recv_buf[index++] = ch; Serial.print((char)ch); delay(2); } if (strstr(recv_buf, p_ack) != NULL) { return 1; } } while (millis() - startMillis < timeout_ms); return 0; } static void recv_prase(char *p_msg) { if (p_msg == NULL) { return; } char *p_start = NULL; int data = 0; int rssi = 0; int snr = 0; p_start = strstr(p_msg, "RX"); if (p_start && (1 == sscanf(p_start, "RX: \"%d\"\r\n", &data))) { Serial.println(data); } p_start = strstr(p_msg, "RSSI"); if (p_start && (1 == sscanf(p_start, "RSSI %d,", &rssi))) { Serial.println(rssi); } p_start = strstr(p_msg, "SNR"); if (p_start && (1 == sscanf(p_start, "SNR %d", &snr))) { Serial.println(snr); } } void setup(void) { Serial.begin(115200); mySerial.begin(9600); Wire.begin(); tft.begin(); //Start TFT LCD tft.setRotation(3); //Set TFT LCD rotation spr.createSprite(TFT_HEIGHT, TFT_WIDTH); //Create buffer pinMode(WIO_LIGHT, INPUT); //Set light sensor pin as INPUT pinMode(WIO_MIC, INPUT); //Set Microphone sensor pin as INPUT uint16_t error; char errorMessage[256]; sht4x.begin(Wire); uint32_t serialNumber; error = sht4x.serialNumber(serialNumber); delay(5000); if (error) { Serial.print("Error trying to execute serialNumber(): "); errorToString(error, errorMessage, 256); Serial.println(errorMessage); } else { Serial.print("Serial Number: "); Serial.println(serialNumber); } Serial.print("E5 LORAWAN TEST\r\n"); if (at_send_check_response("+AT: OK", 100, "AT\r\n")) { is_exist = true; at_send_check_response("+ID: DevEui", 1000, "AT+ID=DevEui,\"xxxxxxxxxxxxxxxx\"\r\n"); at_send_check_response("+ID: AppEui", 1000, "AT+ID=AppEui,\"xxxxxxxxxxxxxxxx\"\r\n"); at_send_check_response("+MODE: LWOTAA", 1000, "AT+MODE=LWOTAA\r\n"); at_send_check_response("+DR: AS923", 1000, "AT+DR=AS923\r\n"); at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,0-2\r\n"); at_send_check_response("+KEY: APPKEY", 1000, "AT+KEY=APPKEY,\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"\r\n"); at_send_check_response("+CLASS: A", 1000, "AT+CLASS=A\r\n"); at_send_check_response("+PORT: 8", 1000, "AT+PORT=8\r\n"); delay(200); is_join = true; } else { is_exist = false; Serial.print("No E5 module found.\r\n"); } } void loop(void) { uint16_t error; float temperature, humidity; int int_temp, int_humi; error = sht4x.measureHighPrecision(temperature, humidity); int_temp = temperature * 100; int_humi = humidity * 100; int light = analogRead(WIO_LIGHT); //Assign variable to store light sensor values int mic = (analogRead(WIO_MIC))/10; //Assign variable to store microphone sensor values //Setting the title header spr.fillSprite(TFT_WHITE); //Fill background with white color spr.fillRect(0, 0, 320, 50, TFT_DARKGREEN); //Rectangle fill with dark green spr.setTextColor(TFT_WHITE); //Setting text color spr.setTextSize(3); //Setting text size spr.drawString("CNX Software", 50, 15); //Drawing a text string spr.drawFastVLine(150, 50, 190, TFT_DARKGREEN); //Drawing verticle line spr.drawFastHLine(0, 140, 320, TFT_DARKGREEN); //Drawing horizontal line //Setting Temperature spr.setTextColor(TFT_BLACK); spr.setTextSize(2); spr.drawString("Temperature", 10, 65); spr.setTextSize(3); spr.drawNumber(temperature, 50, 95); //Display Temperature values spr.drawString("C", 90, 95); //Setting Humidity spr.setTextSize(2); spr.drawString("Humidity", 25, 160); spr.setTextSize(3); spr.drawNumber(humidity, 30, 190); //Display Humidity values spr.drawString("%RH", 70, 190); //Setting Microphone spr.setTextSize(2); spr.drawString("Microphone", 180, 65); spr.setTextSize(3); spr.drawNumber(mic, 205, 95); //Display microphone values spr.drawString("dB", 245, 95); //Setting light spr.setTextSize(2); spr.drawString("Light", 200, 160); spr.setTextSize(3); light = map(light, 0, 1023, 0, 100); //Map sensor values spr.drawNumber(light, 205, 190); //Display sensor values as percentage spr.drawString("%", 245, 190); spr.pushSprite(0, 0); //Push to LCD if (is_exist) { int ret = 0; if (is_join) { ret = at_send_check_response("+JOIN: Network joined", 12000, "AT+JOIN\r\n"); if (ret) { is_join = false; } else { Serial.println(""); Serial.print("JOIN failed!\r\n\r\n"); delay(5000); } } else { char cmd[128]; sprintf(cmd, "AT+CMSGHEX=\"%04X %04X %04X %04X\"\r\n", int_temp, int_humi, light, mic); ret = at_send_check_response("Done", 10000, cmd); if (ret) { Serial.print("Temperature: "); Serial.print(temperature); Serial.println(); Serial.print("Humidity: "); Serial.println(humidity); Serial.print("Light: "); Serial.println(light); Serial.print("Microphone: "); Serial.println(mic); recv_prase(recv_buf); } else { Serial.print("Send failed!\r\n\r\n"); } delay(5000); } } else { delay(1000); } } |
9、完成上面的设置之后,我们还需要修改一些代码来设置该 LoRaWAN 板所需的信息,如下所示:
- DevEUI 编号(8 个字节)
- AppEUI 编号(8 字节)
- APPKEY 编号(16 字节)
- 设置 OTAA 连接
- 指定工作频段。比如在泰国是AS923
10、现在将程序上传到开发板 Wio 终端。该板的一个优点是它会自动进入 Bootloader 模式,这样我们就不需要按任何按钮了。
11、打开串行监视器以检查程序的输出。如果一切正常,它将显示 LoRaWAN 连接成功的位置和传感器的值,例如:温度 = 25.46 度,湿度 = 58.39%,光 = 7% 和噪声 = 55 dB。
12、进行到这一步,我们就可以查看 Wio 终端控制器上显示的传感器数了
Wio终端板从传感器读取数值后,就会以 AES-128(高级加密标准)格式重新编码,并通过LoRa-E5模块无线传输。如果它在 LoRaWAN 网关的范围内,则数据将被转发到 LoRaWAN 网络,等以下我们一起查看一下。与此同时,这里有一段简短的视频演示,上面展示了显示屏上正在刷新的数据。
相关视频连接,点击此处可查看。
编程 Wio 终端时遇到的一个小问题
我尝试通过 Arduino IDE 将程序代码上传到 Wio 终端时遇到了问题。在上传的时候卡住了,就一直不动。
因为计算机无法识别 Wio 终端,并显示错误“未知 USB 设备(设备描述符请求失败)”,如下图所示。
尽管我多次尝试手动重置板子并进入 Bootloader,但尝试下图中的方法时仍不成功。
所以我决定联系矽递科技帮助我解决这个问题,但他们的技术支持教给我的方法跟我使用的是一样。一番折腾之后,我发现原来解决问题的关键是“快速双击”,最初我按了两次按钮,比较快,但速度还不够。反复滑动开关多次尝试后,我终于能够再次使用 Wio 终端了。(我无法计算我尝试了多少次,总之次数很多!)。
这意味着计算机终于可以再次正确地读到 USB 端口了,我们可以在正常情况下继续评测了。先不要太开心,重点来了,如果进行到这一步板子再次卡住不动了,我们就需要手动进入 Bootloader 模式。
私有 LoRaWAN IoT 本地平台
现在我已经将 SenseCAP K1100 套件中的数据发送到网关中了,我会通过个人私有的 LoRaWAN IoT 平台对其进行处理。它基于各种开源组件,如下所述:
- ChirpStack开源 LoRaWAN 网络和应用服务器,注册 LoRaWAN IoT 设备号并通过充当发送者(发布)的 MQTT 代理(消息队列遥测传输)以 AES128 格式解密接收到的数据
- 用于编程、基于 Node-RED 流的开发工具。它是通过 MQTT 协议从 ChirpStack 接收(订阅)并从有效负载中获取数据并根据 BASE64 格式对其进行解码。它将传感器数据存储在 InfluxDB 数据库中,并在 LINE 通知应用程序中检查和配置通知设置
- InfluxDB是一个开源的时间序列数据库,存储传感器和 LoRaWAN 网关数据,并自动按时间序列排序,这让我们可以分析任何时间段的数据
- 我还使用了 Grafana实时仪表板来可视化来自 InfluxDB 数据库的数据
- LINE Notify:当传感器高于或低于指定值时,LINE 消息应用程序只会通过 LINE Notify API 通知我们一次,这就意味着不会有重复值的通知
写在最后:SenseCAP K1100 的受众群是谁?
我个人认为 SenseCAP K1100 传感器原型套件适用于希望使用 LoRaWAN 无线连接来创建具有各种传感器的原型、编写代码 (Arduino) 和测试概念验证 (PoC) 的学生、教学者、制造商的实验者等人群。但是,如果想要应用于实的应用中,工业级类的传感器还是更加适合和可靠。以上这些内容就是目前我从矽递科技及供应商处得知的。
十分感谢矽递科技给我寄送的 SenseCAP K1100 传感器原型套件。它目前的的售价是 99 美元,运费需要另外付。在下次的评测中,我将使用 Grove Vision AI 模块来测试 SenseCAP K1100 用于人脸检测时的具体情况。
文章翻译者:Nicholas,技术支持工程师、瑞科慧联(RAK)高级工程师,深耕嵌入式开发技术、物联网行业多年,拥有丰富的行业经验和新颖独到的眼光!