内容介绍
内容介绍
任务:
利用NANO-33 BLE的传感器, 搭建一个小型环境监测站用于监测户外环境。待监测的参数包括:
-
周边环境温度(精度:±0.1°C, ±0.1°F)
-
周边环境湿度(精度:±1%)
-
大气压强(精度:±0.1kPa, ±0.1psi)
-
日照强度(用于判断白天/夜晚)
-
周边平均噪声(精度:±1dB)
传感器列表:
-
APDS9960 距离颜色手势传感器,获取光强用来判断白天/夜晚
-
LSM9DS1 九轴加速度重力传感器
-
HTS221 温湿度传感器 用来测量环境温湿度
-
LPS22HB 压力传感器 用来测量大气压强
-
MP334DT05 PDM麦克风 用来于判断环境噪音
代码实现:
#include <U8g2lib.h>// u8g2库头文件,用于驱动OLED显示字符及图形
#include <Arduino_LPS22HB.h>// 气压传感器头文件
#include <Arduino_HTS221.h>// 温湿度传感器头文件
#include <Arduino_APDS9960.h>// RGB和手势传感器头文件
#include <PDM.h>// 数字麦克风头文件
#include <math.h>// 数学函数头文件
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0,/* reset=*/ U8X8_PIN_NONE);
// 这里我使用的是无rest引脚的SH1106 OLED屏幕,请根据实际硬件从u8g2官方示例里选择
//定义全局变量用于计算环境声音分贝
static const char channels = 1;// 默认输出通道数,不可更改
static const int frequency = 16000;// 默认PCM输出频率,不可更改
short sampleBuffer[512];// 读取样本的缓冲区,每个样本为16位
volatile int samplesRead;// 读取的音频样本数
void onPDMdata()
{
int bytesAvailable = PDM.available();// 查询可用字节数
PDM.read(sampleBuffer, bytesAvailable);// 读入样本缓冲区
samplesRead = bytesAvailable / 2;// 16位,每个样本2字节
}
double SPL_cal()
{
double amp = 0, sum = 0; //amp为所求分贝
int cnt = 0;
while (cnt < 1020) //1024
{
if (samplesRead)
{ for (int i = 0; i < samplesRead; i++)
{
sum += double(sampleBuffer[i]) * sampleBuffer[i];
}
cnt += samplesRead;
samplesRead = 0; //Clear the read count
}
}
amp = 17 * log10(10 * sqrt(sum / cnt));// 通过声音幅值来近似计算分贝
return amp;// 返还结果
}
void setup() {
Serial.begin(9600);// 设置串口传输波特率
//初始化OLED
u8g2.begin();// 选择U8G2模式
u8g2.enableUTF8Print();// 设置启用UTF-8支持,虽然没有使用中文字体,为了兼容温度“°”这个符号而启用
u8g2.setContrast(255);// OLED屏亮度,可用范围0~255
//初始化LPS22HB气压传感器
if (!BARO.begin()) {
Serial.println("Failed to initialize LPS22HB sensor!");
digitalWrite(LEDR, HIGH);//失败会亮起红灯提示
while (1);// 阻止继续程序运行
}
//初始化HTS221温湿度传感器
if (!HTS.begin()) {
Serial.println("Failed to initialize HTS221 sensor!");
digitalWrite(LEDR, HIGH);
while (1);
}
//初始化APDS9960环境光传感器
if (!APDS.begin()) {
Serial.println("Failed to initialize APDS9960 sensor.");
digitalWrite(LEDR, HIGH);
while (1);
}
// 初始化PDM麦克风
PDM.onReceive(onPDMdata);
PDM.setGain(10);//麦克风增益
if (!PDM.begin(channels, frequency))
{
Serial.println("Failed to start PDM!");
digitalWrite(LEDR, HIGH);
while (1);
}
}
void loop() {
// 定义所需变量并从传感器获取数值
float pressure = BARO.readPressure(); //Unit:kPa
float temperature = HTS.readTemperature(); //℃
float humidity = HTS.readHumidity(); //%
int r, g, b, a; //max4097
// 检查颜色光强传感器数据是否可读,否则等待5毫秒
while (! APDS.colorAvailable())
{
delay(5);
}
APDS.readColor(r, g, b, a);// 读取颜色光强数据
u8g2.clearBuffer();// 清空Buffer缓冲区的数据
u8g2.setFont(u8g2_font_helvB12_tf);// 设置字体
u8g2.setCursor(0, 12);// 设置打印坐标,由y轴向上绘制
u8g2.print("T:");
u8g2.setCursor(18, 12);
u8g2.print(String("") + temperature + " °C");
u8g2.setCursor(0, 28);
u8g2.print("H:");
u8g2.setCursor(18, 28); //humidity
u8g2.print(String("") + humidity + " %");
u8g2.setFont(u8g2_font_open_iconic_weather_2x_t);// 设置字符字体
u8g2.setCursor(90, 60);
// 判断光强,光强范围0~4097
if (a > 1500) {
u8g2.drawGlyph(100, 25, 69);// 绘制特殊文本图标(需联合特殊字体)
}
else if (a > 700) {
u8g2.drawGlyph(100, 25, 65);
}
else {
u8g2.drawGlyph(100, 25, 66);
}
u8g2.setFont(u8g2_font_helvB12_tf);
u8g2.setCursor(0, 44);
u8g2.print("P:");
u8g2.setCursor(18, 44); //pressure
u8g2.print (String("") + pressure + " kPa");
double noise = SPL_cal();
u8g2.setCursor(0, 60);
u8g2.print("N:");
u8g2.setCursor(18, 60);
u8g2.print(String("") + noise + " dB");
u8g2.sendBuffer();// 将Buffer帧缓冲区的内容发送到显示器,发送刷新消息
digitalWrite(LEDB, HIGH);// 指示运行状态
delay(1000);
digitalWrite(LEDB, LOW);
}
功能说明:
通过nano 33 ble sense自带的传感器读取:当前环境的温度、湿度、大气压强、环境噪音以及日照强度,再通过OLED屏幕显示,数据信息每秒刷新一次。
效果展示:
活动感想:
通过本次Funpack活动,我学会了arduino的基本编程方法。得益于它开发的便捷性,只需要非常简短的代码就可以实现复杂的功能,非常适合用于电子兴趣入门。感谢硬禾学堂提供的学习平台,也感谢得杰电子的硬件支持。希望今后能持续举办这样的活动吸引更多电子爱好者入门学习,壮大电子DIYer的队伍。
团队介绍
评论
0 / 100
查看更多
猜你喜欢
Funpack第八期 Arduino Nano 33 BLE Sense 环境检测站本期完成基于Arduino Nano 33 BLE Sense 环境检测站
安先生
1089
Funpack第八期 — Arduino Nano 33 BLE Sense 环境监测站利用 Arduino Nano 33 BLE Sense 的板载传感器,搭建一个小型环境监测站用于监测户外环境,待监测的参数包括温湿度、大气压强、日照强度、周边平均噪声等信息。
枫雪天
1148
Funpack 第八期 Arduino Nano 33 BLE Sense 环境监测站使用Arduino Nano 33 BLE Sense检测环境参数,并通过OLED显示屏显示
tinysheeep
1181