任务:环境监测站
利用NANO-33 BLE的传感器, 搭建一个小型环境监测站用于监测户外环境。待监测的参数包括:
-
周边环境温度(精度:±0.1°C, ±0.1°F)
-
周边环境湿度(精度:±1%)
-
大气压强(精度:±0.1kPa, ±0.1psi)
-
日照强度(用于判断白天/夜晚)
-
周边平均噪声(精度:±1dB)
将采集到的参数通过外接显示屏显示
设计思路
程序中传感器数据的采集直接参考例程即可,OLED显示屏有十分好用的U8g2库来进行驱动。设计中唯一的难点在于如何使用板载PDM麦克风测算得到环境噪音dB值。查找了一些资料后得知nRF52系列控制器内部集成了一个PDM模块,板载PDM麦克风的输出就是由这个PDM模块处理的。
可以看到经过PDM模块转换处理,PDM的输入信号转换为了PCM数据。同样如果去查看Arduino论坛中的PDM库也能发现库中对数据的处理同样是基于PCM的。
那么如何将读取到的PCM数据换算成为dB值呢,首先要了解一下声音dB的计算方式。dB本身是一个单位,用来衡量两个数量的比值大小,计算方式是
由于人耳对音量大小的感知和对数关系比较相近,因此通常用dB来衡量音量大小比较贴近人的真实感受。dB通过两个变量的比值大小进行计算,那么衡量一个音量的大小就需要用到一个标准量作为分母。对声音最直接的衡量就是声波的能量大小,能量的难以直接测算,就通过声压来换算得到能量大小,能量的大小与声压大小成平方关系,通过对数性质我们可以得到利用声压计算dB的公式就是
通过声压计算得到的dB值也叫dBSPL,用于参考的标准声压大小为20微帕斯卡。在程序里得到的数字PCM数据又要如何转换到dBSPL呢,对于数字麦克风,有一个用于衡量音量大小的单位叫dBFS,FS代表full scale,其计算方式是
我们得到的PCM数据是16位的,将麦克风采样值除以它的最大幅度就是除以65536。但在这之前要知道,PDM麦克风所采样的数据是压强的瞬时变化,是在不断变化的。而声压级则不同,可以理解为将声音瞬时压强等效为一个平均作用的压强。二者的转换可以对声压级求均方根实现。
麦克风采样的数据大小很明显是与自身参数有关的,不同麦克风一般有不同的参数,同样音量所得到的采样值也不一定相同。因此数字麦克风有一个参数会出现在数据手册中,那就是灵敏度。灵敏度所代表的含义是标准声学输入所产生的麦克风输出,其单位就是dBFS,所谓标准声学输入是94dBSPL。板载的MP34DT05麦克风灵敏度为-26dBFS,换算关系就是
至此知道了如何计算dBFS和如何将dBFS换算到dBSPL,那么就可以利用PDM麦克风测量噪音大小了。计算环境噪音音量的代码如下:
float getNoise() {
float dB;
float data_rms = 0;
float dBSPL;
for(int i = 0; i < 10 ; i++) {
int j=0;
while(j<512) {
while(samplesRead==0);
data_rms += sampleBuffer[j]*sampleBuffer[j];
samplesRead--;
j++;
}
data_rms = sqrt(data_rms/500)+1;
dBSPL = 20*log10(data_rms)+24;
dB += dBSPL;
data_rms = 0;
samplesRead = 0;
}
dB = dB/10;
return dB;
}
心得体会
Arduino的开发真的真的十分方便,几乎完全不需要接触底层的细节,只要调用库库库函数就可以了,到现在为止我是第一次有这么轻松的开发体验。有点不足的地方就是Arduino没有一些方便的功能像自动补全等等,官网对于开发板、例程的说明有点不足,也可能是我找错了地方,总之造成了一些困扰。不过总体上还是比较轻松的在Arduino这个平台上实现了整个项目。