- 开发板:Arudino NANO 33 BLE SENSE
- IDE:arduino IDE
- 传感器:HTS211(温湿度传感器)
LPS22HB(压力传感器)
MP34DT05-A(麦克风)
APD29960(颜色、距离、姿态传感器)
这些传感器都是通过I2C协议与处理器进行通信
- 开发板引脚说明
- 任务要求
利用NANO-33 BLE的传感器,搭建一个小型环境监测站用于监测户外环境。待监测的参数包括:
· 周边环境温度(精度:±0.1°C, ±0.1°F)
· 周边环境湿度(精度:±1%)
· 大气压强(精度:±0.1kPa, ±0.1psi)
· 日照强度(用于判断白天/夜晚)
· 周边平均噪声(精度:±1dB)
我这里采用外接oled显示屏显示参数
- 工作流程设计
- PDM与声压级
脉冲密度调制(Pulse Density Modulation),简称PDM,是一种使用二进制数0,1表示模拟信号的调制方式。在PDM信号中,模拟信号的幅值使用输出脉冲对应区域的密度表示。PWM波是PDM波转换频率固定的一种特例,对于一个使用8位长表示的电压信号而言,峰值的1/2处会高低电平各持续一半,即128个时钟周期。在PDM信号中,会在1,0之间每个时钟周期都切换。两种波形的平均值都是50%,但是PDM波切换的更加频繁。对于100%和0的电平信号,两种方式的输出相同。下面这幅图是在网上找到的方便于理解一下。
在任务要求中需要测量平均噪声且单位是dB,在我看来是对其声压的计算。 声压是定量描述声波的最基本物理量。通常讲的声压是有效声压,即在一定时间内将瞬时声压对时间求均方根值(Root Mean Square,RMS)而得,单位是帕斯卡Pa。计算公式为:
其中,N为时域采样点数,x(n)为时域采样点的值
声音的有效声压与基准参考声压之比,取以10为底的对数,再乘以20,即为声压级,单位dB。计算公式为:
其中Pref为基准参考声压,空气中一般取2x10^-5 (Pa)。
再去到arduino关于PDM的例程看看
void loop() {
// Wait for samples to be read
if (samplesRead) {
// Print samples to the serial monitor or plotter
for (int i = 0; i < samplesRead; i++) {
if(channels == 2) {
Serial.print("L:");
Serial.print(sampleBuffer[i]);
Serial.print(" R:");
i++;
}
Serial.println(sampleBuffer[i]);
}
// Clear the read count
samplesRead = 0;
}
}
这个sampleBuffer[i]应该是存放的瞬时声压的值,将瞬时声压进行RMS(求均方根值)计算得出有效声压,这个有效声压与基准参考声压之比,取以10为底的对数,再乘以20就算出需要用到的分贝值了,下图是声压级计算函数
double getRms(int samples_Read) {
int sum = 0;
double P ;
if (samples_Read) {
// Print samples to the serial monitor or plotter
for (int i = 0; i < samples_Read; i++) {
sum = sum + pow(sampleBuffer[i], 2);
}
int Rms = sqrt (sum / samples_Read);
P = (20 * log10(Rms));
Serial.println(P);
// Clear the read count
sum = 0;
samplesRead = 0;
}
return P;
}
- oled显示白天黑夜
先在画图画出一个16x16的月亮或者太阳生成jpg文件在利用取模软件生成符号数组
static const uint8_t PROGMEM sun_16x16[]={
0x21,0x84,0x51,0x8A,0x29,0x94,0x10,0x08,0x07,0xE0,0x04,0x20,0x04,0x20,0xF4,0x2F,
0xF4,0x2F,0x04,0x20,0x07,0xE0,0x10,0x08,0x29,0x94,0x51,0x8A,0xA1,0x85,0x41,0x82,
};
static const uint8_t PROGMEM moon_16x16[]={
0x00,0x00,0x01,0xE0,0x01,0x20,0x07,0x40,0x0C,0xC0,0x08,0x80,0x08,0x80,0x08,0x80,
0x08,0x80,0x08,0xC0,0x08,0x40,0x0C,0x60,0x06,0x38,0x01,0xCC,0x00,0x44,0x00,0x78,
};
- 部分源码
void loop() {
temperature = HTS.readTemperature();
humidity = HTS.readHumidity();
pressure = BARO.readPressure();
Pe = getRms(samplesRead);
while (! APDS.colorAvailable()) {
delay(5);
}
APDS.readColor(r, g, b,a);
Serial.print ("Light = ");
Serial.println(a);
Serial.print("Temperature = ");
Serial.print(temperature);
Serial.println(" °C");
Serial.print("Humidity = ");
Serial.print(humidity);
Serial.println(" %");
Serial.print("Pressure = ");
Serial.print(pressure);
Serial.println(" kPa");
Serial.print("Sound=");
Serial.print(Pe);
Serial.println("dB");
oled_disp();
delay(1000);
}
- 心得体会
第一次在网络上发表自己的小项目,这个活动很好的锻炼了我的动手能力,文档编写能力。不断锻炼自己的能力,希望以后能做出更好的东西。arduino实在是太香了,比起常规的51和32编写方便太多了,开发速度也比较快。