Funpack第八期-云端环境监测站
利用 Arduino Nano 33 BLE 板卡 做了一个环境监测站,nano33ble 读出板载传感器的数据,并通过 BLE 连接到网关,网关将数据送入了阿里云物联网平台。这样可以在云端检测环境监测站的数据。
标签
Arduino Nano 33 BLE Sense
Funpack第八期
Jackistang
更新2021-05-17
799

Funpack 第八期

1 成果介绍

我本次利用 nano33ble 做了一个环境监测站,nano33ble 读出板载传感器的数据,并通过 BLE 连接到网关,网关将数据送入了阿里云物联网平台。这样可以在云端检测环境监测站的数据。

2 Arduino Nano 33 BLE Sense

芯片介绍:

传感器介绍:

  • 手势传感器:能感应手势、颜色、亮度、接近度
  • 数字麦克风
  • 气压传感器
  • 温湿度传感器
  • 9 轴加速度重力传感器
  • TinyML

3 代码介绍

由于此板卡是 Arduino 官方提供的,因此有非常完整的 SDK,直接调用接口即可读出传感器数据,下面依次介绍。

3.1 温湿度

读取温湿度用的是 `<Arduino_HTS221.h>` 库文件,因此需要导入

#include <Arduino_HTS221.h>

利用 `HTS.begin()` 即可初始化传感器,然后调用接口 `HTS.readTemperature()` 即可读出温度,调用`HTS.readHumidity()` 即可读出湿度。如下所示:

if (!BLE.begin()) {
Serial.println("starting BLE failed!");
while (1);
}

...

float temperature = HTS.readTemperature();
float humidity = HTS.readHumidity();

// print each of the sensor values
Serial.print("Temperature = ");
Serial.print(temperature);
Serial.println(" °C");

Serial.print("Humidity = ");
Serial.print(humidity);
Serial.println(" %");

3.2 大气压强

读取大气压强用的是 `<Arduino_LPS22HB.h>` 这个库,因此需要导入

#include <Arduino_LPS22HB.h>

然后利用 `BARO.begin()` 初始化传感器,再利用 `BARO.readPressure(PSI)` 即可读出压强值了,代码如下:

if (!BARO.begin()) {
Serial.println("Failed to initialize pressure sensor!");
while (1);
}

...

// Passing PSI to readPressure(...)
// allows you to read the sensor values in imperial units
float pressure = BARO.readPressure(PSI);

// print the sensor value
Serial.print("Pressure = ");
Serial.print(pressure);
Serial.println(" psi");

3.3 光照强度

读取光照强度用的是 `<Arduino_APDS9960.h>` 这个库文件,因此需要导入:

#include <Arduino_APDS9960.h>

然后利用 `APDS.readColor()` 即可读出光照强度,注意此处读出来的分别是 r, g, b 三种颜色的光照强度,范围为 0 - 255,我们可以用 `map()` 函数将其范围缩放到 0 -100,切换成百分比的单位。代码如下:

if (!APDS.begin()) {
Serial.println("Error initializing APDS9960 sensor.");
while (1);
}

...

// check if a color reading is available
while (! APDS.colorAvailable()) {
delay(5);
}
int r, g, b;
// read the color
APDS.readColor(r, g, b);
uint8_t luminance = map(r, 0, 255, 0, 100);

// print the values
Serial.print("r = ");
Serial.println(r);
Serial.print("g = ");
Serial.println(g);
Serial.print("b = ");
Serial.println(b);
Serial.println();

3.4 噪音分贝

读取噪音分贝用的是 `<PDM.h>` 这个库,因此需要导入:

#include <PDM.h>

我对音频这一块不太熟悉,因此参考了一下其他同学完成的代码。先用 `PDM.onReceive()` 绑定回调函数,在回调函数里进行声音采集,并将数据读入缓冲区。然后利用 `PDM.begin()` 初始化传感器,并设置采样率为 16000,之后就涉及到采样数据与分贝的转换了,使用 

FjLZ1upDXzjSwXAf7LECZg-w1v-i

公式转化。

代码如下:

short sampleBuffer[512];
volatile int samplesRead;

...

//初始化声音传感器
PDM.onReceive(onPDMdata);
PDM.begin(1, 16000);

...

//计算分贝
while (!samplesRead);
uint32_t sample_max = 0;
for (int i = 0; i < samplesRead; i++) {
if(sampleBuffer[i] < 0)
sampleBuffer[i] = -sampleBuffer[i];
if(sampleBuffer[i] > sample_max)
sample_max= sampleBuffer[i];
}
uint8_t sample = 24*log10(sample_max*5); //转换分贝
samplesRead = 0;

...

//声音采集中断
void onPDMdata() {
int bytesAvailable = PDM.available(); //查询可用字节数
PDM.read(sampleBuffer, bytesAvailable); //读入缓冲区
samplesRead = bytesAvailable / 2;
}

3.5 BLE

蓝牙部分相对复杂一些,我自定义了一个 Service 和 Characterisic,

BLEService environmentService("5AA0");
BLECharacteristic environmentalMonitorCharacteristic("5AA1", BLERead | BLENotify, ENVIRONMENT_MONITOR_LEN);

并且将所有的传感器数据都存储在一个 Characteristic Value 里,字节流格式如下:

// len(1byte) + type(1byte) + data(len byte, little endian)
// 2 + temperature(0) + 0x15,0x19(25.21 °C)
// 2 + humidity(1) + 0x57,0x45(69.87 %)
// 2 + pressure(2) + 0x40,0x0E(14.64 psi)
// 1 + luminance(3) + 0x50(80 % [100%])
// 1 + noise(4) + 0x3C(60 dB)

是一串 len + type + data 的数据流,参考了 BLE 广播包的结构。

实际数据流可参考:

此处使用的是官方提供的 `<ArduinoBLE.h>` 库,因此需导入:

#include <ArduinoBLE.h>

官方提供了很多关于 BLE 的例程,Central 的例程也有很多,我这里套用了其中的一个,在建立完连接后,每隔一秒读取一遍传感器数据,并将其通知给网关。代码如下:

#define ENVIRONMENT_MONITOR_LEN 18
uint8_t buf[ENVIRONMENT_MONITOR_LEN];

buf[0] = 2; buf[1] = 0; buf[2] = (int)(temperature*100)%100; buf[3] = ((int)temperature%100);
buf[4] = 2; buf[5] = 1; buf[6] = (int)(humidity*100)%100; buf[7] = ((int)humidity%100);
buf[8] = 2; buf[9] = 2; buf[10] = (int)(pressure*100)%100; buf[11] = ((int)pressure%100);
buf[12] = 1; buf[13] = 3; buf[14] = luminance;
buf[15] = 1; buf[16] = 4; buf[17] = sample;

environmentalMonitorCharacteristic.writeValue(buf, ENVIRONMENT_MONITOR_LEN);

4 心得体会

第一次接触 Arduino 官方提供的板卡,感觉各方面都支持的挺完美的,开发原型十分便捷。非常感谢本期 Funpack 活动,让我接触到了这块如此优秀的板卡,Nano33ble 可玩性极高,其关于 TinyML 相关的部分我还未接触,以后会尝试一下。通过完成本期任务,我收获了许多,非常感谢。

附件下载
nano33ble.ino
团队介绍
团队成员
Jackistang
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号