- 实现的功能
使用Arduino nano 33 ble sense开发板上集成的LPS22HB气压传感器、HTS221温湿度传感器、APDS9960姿态距离颜色传感器、MP34DT05数字麦克风采集环境温湿度、气压、环境噪音、环境光亮度。
外接SH1106 128*64单色OLED显示器,将以上传感器采集的数据处理后显示,由于屏幕大小有限,内容需要轮换显示,每一屏幕的内容显示2s。
开机后显示大气压强与根据大气压强与当前温度使用hypsometric 公式计算的理论海拔高度,每50ms刷新一次数据
float altitude=(pow((101.325/pressure),0.1902)-1)*(temperature+273.15)/0.0065;
u8g2.print(String("")+altitude+" m");
等待两秒后显示相对湿度与环境温度,每50ms刷新一次数据
等待两秒后显示环境光亮度,并根据阈值判断当前是白天还是黑夜,每50ms刷新一次数据,最初考虑人眼对不同颜色的光的敏感度的不同,使用了一个将RGB亮度转换为灰度的心理学公式:
float gray=(float(r)/16*30 + float(g)/16*59 + float(b)/16*11 + 50) / 100;//彩色转灰色心理学公式
但是实际测试效果并不好……可能不同传感器的颜色标准不同吧……最后还是用了最简单的方式:
float gray=float(r+g+b)/122.91;
等待两秒后显示环境噪声响度,根据1024次采样的均方根计算环境噪声的声压级,并将单位转换为分贝,每秒刷新约15.625次数据,量程为20~106dB
double SPL_cal(){
double amp=0,sum=0;//amp:amplitude of sound
int cnt=0;//max=1023,15.625Hz
while(cnt<1020)
{
if(samplesRead)
{
for(int i=0;i<samplesRead;i++)
{
sum+=double(sampleBuffer[i])*sampleBuffer[i];
}
cnt+=samplesRead;
samplesRead=0;// Clear the read count
}
}
//Serial.println(String("samples count:")+cnt);//debug only
amp=20*log10(10*sqrt(sum/cnt));
//可以通过对数的运算规则改为amp=20*log10(sqrt(sum/cnt))+20;提高性能
//不过这样就不太容易理解了,反正性能足够,就不用这么抠啦
return amp;
}
等待两秒后对runTime重新赋值,再次开始第一屏内容的显示。
- 功能演示
以下界面按开机后显示顺序排列,每个界面显示2s,每个界面中数值都会以一定的速度刷新,文字不变。
1.大气压强显示:
2.温度与湿度显示界面:
3.环境光亮度界面(拍摄时在室内,因此亮度较低,显示的是夜晚,视频显示的是白天):
4.环境噪声声压级显示界面:
- 心得体会
很荣幸能参加本次活动,第一次用到了性能这么强的Arduino说实话颠覆了我对Arduino的认识,并且第一次尝试拍摄与剪辑视频,说实话还是有点紧张的,不过为了白嫖开发板完成这次挑战还是完成了作品的提交(其实也没那么难)。
在交流群中也见到了很多的大佬,得到了大佬们的帮助(十分感谢大佬们,诚惶诚恐),驱动oled的u8g2库就是大佬推荐的,分贝的计算也参考了大佬们发的文章。总的来说学到了不少,非常感谢电子森林和Digikey举办的此次活动,也很感谢Arduino能提供如此简单易用的平台方便我这样的非专业人士使用、开发MCU。