Funpack8:Arduino Nano 33 BLE Sense开发板(微型环境监测站)
利用Arduino nano 33 ble sense 及板载传感器开发出一个环境检测的项目 · 大气压强(精度:±0.1kPa, ±0.1psi) · 日照强度(用于判断白天/夜晚) · 周边平均噪声(精度:±1dB)
标签
嵌入式系统
Jacky
更新2021-05-19
1020

内容介绍

  • 开发板:Arudino NANO 33 BLE SENSE
  • IDE:arduino IDE
  • 传感器:HTS211(温湿度传感器)

            LPS22HB(压力传感器)

            MP34DT05-A(麦克风)

            APD29960(颜色、距离、姿态传感器)

            这些传感器都是通过I2C协议与处理器进行通信

  • 开发板引脚说明

FlduN6dv4wqz79TylTneWv6xI82A

  • 任务要求

利用NANO-33 BLE的传感器,搭建一个小型环境监测站用于监测户外环境。待监测的参数包括:

· 周边环境温度(精度:±0.1°C, ±0.1°F)

· 周边环境湿度(精度:±1%)

· 大气压强(精度:±0.1kPa, ±0.1psi)

· 日照强度(用于判断白天/夜晚)

· 周边平均噪声(精度:±1dB)

我这里采用外接oled显示屏显示参数

  • 工作流程设计

FjJrDnfBjIiKnd6mLC0w_AAIOCUQ

  • PDM与声压级

脉冲密度调制(Pulse Density Modulation),简称PDM,是一种使用二进制数0,1表示模拟信号的调制方式。在PDM信号中,模拟信号的幅值使用输出脉冲对应区域的密度表示。PWM波是PDM波转换频率固定的一种特例,对于一个使用8位长表示的电压信号而言,峰值的1/2处会高低电平各持续一半,即128个时钟周期。在PDM信号中,会在1,0之间每个时钟周期都切换。两种波形的平均值都是50%,但是PDM波切换的更加频繁。对于100%和0的电平信号,两种方式的输出相同。下面这幅图是在网上找到的方便于理解一下。

             FjTU3Csal7Tcqx-2fxrOyCls6IL6

 

在任务要求中需要测量平均噪声且单位是dB,在我看来是对其声压的计算。                          声压是定量描述声波的最基本物理量。通常讲的声压是有效声压,即在一定时间内将瞬时声压对时间求均方根值(Root Mean Square,RMS)而得,单位是帕斯卡Pa。计算公式为:FoGCxTmjbFVVvk0TVhEiZkAZBPG3

其中,N为时域采样点数,x(n)为时域采样点的值

声音的有效声压与基准参考声压之比,取以10为底的对数,再乘以20,即为声压级,单位dB。计算公式为:

FsGuc46TXNfWScLPCfJGKctTDf3R其中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, 
  };

FlOhrW0sHJWR5e0NtqHR9bEaGuXwFlcYH-u_K5_1ZsWyuT1EStekrRuS

  • 部分源码
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编写方便太多了,开发速度也比较快。

附件下载

environment.ino

团队介绍

团队成员
Jacky

评论

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