【Funpack第八期】+任务二:环境监测站
此次参加的活动是由硬禾学堂联合Digi-Key发起的funpack第八期活动,本次活动任务主要是利用arduino nano 33 ble开发板所带的5个传感器,温湿度,气压,光线,声音,9轴加速传感器,实现环境数据监测
标签
嵌入式系统
测试
显示
leo121
更新2021-05-19
661

内容介绍

【项目简介】

     科技的不断进步,促进物联网蓬勃发展,做为物联网的关键部分就是传感器,好像我们的五官可以感知外部的环境,又通过网络把采集的相关数据反馈给最终用户。我本次选择的是Funpack第八期活动的主题任务之二环境监测站,顺便回顾以下任务要求

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

任务二 传感器

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

HTS221datasheet
· 周边环境湿度(精度:±1%)  
· 大气压强(精度:±0.1kPa, ±0.1psi) LPS22HB
· 日照强度(用于判断白天/夜晚) APDS9960
· 周边平均噪声(精度:±1dB) MP34DT05
-通过tftlcd展示上边的数据 st7789v 240x240
   

 

【软件】

  1. os ubuntu20.04
  2. arduino ide 1.8.13
  3. 若干库文件

【硬件】

  1. Arduino Nano 33 BLE Sense x1
  2. 240x240 st7789 1.44" x1
  3. 杜邦线若干

关于开发板的介绍请参考官方的文档,非常详细也包括库的介绍

【步骤】

  1. 驱动tftLCD,型号st7789v,接口标准4线SPI,

FiZvLUTM365U8U0XPSu1elffdLay

开发板 st7789
gnd gnd
vcc3.3v vcc
D13 TFT_SCK
D11 TFT_MOSI
D10 TFT_CS
D9 TFT_DC
D8 TFT_RESET
   

      查找st7789v的库文件,非常多,但是能用的很少,运气不错,找到一个直接可以用的,代码如下所示

FhvvQc6EjFFC8Z34tcMwYq-AlhWG

 

2.在上一步的基础上,驱动传感器并采集数据显示到LCD上 ,推荐使用官方的库,代码如下

Fv5aoMmGVbLkhgNQwu-VqxdtEo5l

  • 首先是温湿度传感器HTS221

主要特征:

0至100%相对湿度范围
电源电压:1.7至3.6 V
低功耗:ODR为1 Hz时为2μA
从1 Hz到12.5 Hz的可选ODR
高rH灵敏度:0.004%rH / LSB
湿度精度:±3.5%rH,20至+ 80%rH
温度精度:±0.5°C,15至+40°C
嵌入式16位ADC
16位湿度和温度输出数据
SPI和I²C接口

示例代码

#include <Arduino_HTS221.h>

void setup() {
    Serial.begin(9600);
    while (!Serial);
    if (!HTS.begin()) {
        Serial.println("Failed to initialize humidity temperature sensor!");
        while (1);
    }
}

void loop() {
    // read all the sensor values
    float temperature = HTS.readTemperature();
    float humidity    = HTS.readHumidity();
    // print each of the sensor values
    Serial.print("Temperature = ");
    Serial.print(temperature);
    Serial.println(" °C");
    Serial.print("Humidity    = ");
    Serial.print(humidity);
    Serial.println(" %");
    // print an empty line
    Serial.println();
    // wait 1 second to print again
    delay(1000);
}

 输出显示

Temperature = 36.76 °C

Temperature = 36.85 °C

Temperature = 36.83 °C

Detected RIGHT gesture
2
Humidity    = 64.82 %

Humidity    = 64.76 %

Humidity    = 64.65 %

  • LPS22HB-MEMS纳米压力传感器:260-1260 hPa绝对数字输出气压计

主要特征:

260至1260 hPa绝对压力范围
电流消耗低至3μA
高超压能力:20倍满量程
嵌入式温度补偿
24位压力数据输出
16位温度数据输出
ODR从1 Hz到75 Hz
SPI和I²C接口
嵌入式FIFO
中断功能:数据就绪,FIFO标志,压力阈值
电源电压:1.7至3.6 V
高冲击寿命:22,000 g

示例代码

#include <Arduino_LPS22HB.h>

void setup() {
    Serial.begin(9600);
    while (!Serial);
    if (!BARO.begin()) {
        Serial.println("Failed to initialize pressure sensor!");
        while (1);
    }
}
void loop() {
    // read the sensor value
    float pressure = BARO.readPressure();
    // print the sensor value
    Serial.print("Pressure = ");
    Serial.print(pressure);
    Serial.println(" kPa");
    // print an empty line
    Serial.println();
    // wait 1 second to print again
    delay(1000);
}

输出

Pressure = 100.42 kPa

Pressure = 100.42 kPa

Pressure = 100.42 kPa

Pressure = 100.42 kPa

Pressure = 100.41 kPa

Pressure = 100.41 kPa
  • APDS-9960-数字接近,环境光,RGB和手势传感器

主要特征:

微型封装尺寸:长3.94 x宽2.36 x高1.35毫米
与专用中断引脚兼容的I2C接口
深色玻璃后面的高灵敏度支持操作
集成UV-IR块滤光片的RGBC光感测
几何排列的RGBC光电二极管提供均匀的角响应
校准至100mm的检测距离,消除了客户终端产品的校准
四个独立的光电二极管,对不同的方向敏感
集成可见块滤波器的接近度和手势感测
获得专利的屏蔽设计,最大限度地减少了串扰
集成光学透镜,可准直IR LED光束并提高光电二极管灵敏度。
低功耗:睡眠模式下典型值为1.0 µA

示例代码

include <Arduino_APDS9960.h>

void setup() {
    Serial.begin(9600);
    while (!Serial); // Wait for serial monitor to open

    if (!APDS.begin()) {
        Serial.println("Error initializing APDS9960 sensor.");
        while (true); // Stop forever
    }
}

int proximity = 0;
int r = 0, g = 0, b = 0;
unsigned long lastUpdate = 0;

void loop() {

    // Check if a proximity reading is available.
    if (APDS.proximityAvailable()) {
        proximity = APDS.readProximity();
    }

    // check if a gesture reading is available
    if (APDS.gestureAvailable()) {
        int gesture = APDS.readGesture();
        switch (gesture) {
            case GESTURE_UP:
                Serial.println("Detected UP gesture");
                break;

            case GESTURE_DOWN:
                Serial.println("Detected DOWN gesture");
                break;

            case GESTURE_LEFT:
                Serial.println("Detected LEFT gesture");
                break;

            case GESTURE_RIGHT:
                Serial.println("Detected RIGHT gesture");
                break;

            default:
                // ignore
                break;
        }
    }

    // check if a color reading is available
    if (APDS.colorAvailable()) {
        APDS.readColor(r, g, b);
    }

    // Print updates every 100ms
    if (millis() - lastUpdate > 100) {
        lastUpdate = millis();
        Serial.print("PR=");
        Serial.print(proximity);
        Serial.print(" rgb=");
        Serial.print(r);
        Serial.print(",");
        Serial.print(g);
        Serial.print(",");
        Serial.println(b);
    }
}

 我这里使用了手势来切换不同的菜单显示传感器的数据。

if (APDS.gestureAvailable()) {
    // a gesture was detected, read and print to serial monitor
    int gesture = APDS.readGesture();

    switch (gesture) {
      case GESTURE_UP:
        Serial.println("Detected UP gesture");

        menu++;
        if(menu>5)
        menu=1;
         Serial.println(menu);
        break;

      case GESTURE_DOWN:
        Serial.println("Detected DOWN gesture");
        menu--;
        if(menu==0||menu>6)
        menu=5;
        Serial.println(menu);
         
        break;

      case GESTURE_LEFT:
        
        Serial.println("Detected LEFT gesture");
         menu--;
        if(menu==0||menu>6)
        menu=5;
        Serial.println(menu);
        break;

      case GESTURE_RIGHT:
        Serial.println("Detected RIGHT gesture");
        menu++;
        if(menu>5)
        menu=1;
         Serial.println(menu);
        break;

      default:
        // ignore
        break;
    }

输出仅仅使用了光强检测部分

Night!
ALS:16
ALS:16
ALS:16
ALS:16
ALS:12
ALS:12
ALS:13
ALS:13
ALS:14
ALS:14
Day!
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
ALS:138
  • MP34DT05-A-MEMS音频传感器全向数字麦克风

主要特征:

单电源电压
低功耗
AOP = 122.5 dBSPL
64 dB信噪比
全向灵敏度
–26 dBFS±3 dB灵敏度
PDM输出

示例代码

#include <PDM.h>

// buffer to read samples into, each sample is 16-bits
short sampleBuffer[256];

// number of samples read
volatile int samplesRead;

void setup() {
    Serial.begin(9600);
    while (!Serial);

    // configure the data receive callback
    PDM.onReceive(onPDMdata);

    // optionally set the gain, defaults to 20
    // PDM.setGain(30);

    // initialize PDM with:
    // - one channel (mono mode)
    // - a 16 kHz sample rate
    if (!PDM.begin(1, 16000)) {
        Serial.println("Failed to start PDM!");
        while (1);
    }
}

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++) {
            Serial.println(sampleBuffer[i]);
        }

        // clear the read count
        samplesRead = 0;
    }
}

void onPDMdata() {
    // query the number of bytes available
    int bytesAvailable = PDM.available();

    // read into the sample buffer
    PDM.read(sampleBuffer, bytesAvailable);

    // 16-bit, 2 bytes per sample
    samplesRead = bytesAvailable / 2;
}

输出

-22
-14
-22
-18
-15
-10
-25
-14
-9
-5

FiJd3-WsPtADAEZd4_rWwSR0XwPK

采集到的数据转换为分贝(db)代码

void pdm_computeRMSValue(void)
{
  for(int i = 0; i < samplesRead; i++){
  PDM_RMSValue+= sampleBuffer[i]*sampleBuffer[i];//平方和
  }
  PDM_RMSValue=PDM_RMSValue/samplesRead;
  PDM_RMSValue=sqrt(PDM_RMSValue);//均方根
  PDM_RMSValue=20*log10(PDM_RMSValue)+20;//根据升压公式转化为db,+20是修正值
  samplesRead=0;
}

 

3. 简单的菜单实现,主要用手势功能来实现几个传感器的切换

代码

uint8_t p =0 ; //局部刷新
uint8_t menu=0;//0-欢迎界面 1-温度 2-湿度 3-气压 4-环境光强判断黑夜/白天 5-环境噪音
Scheduler.startLoop(switch_sensor);//多菜单切换
  
//Scheduler.startLoop(tftPrintWelcome);//发现用多任务非常慢
//Scheduler.startLoop(tftPrintTemp);
//Scheduler.startLoop(tftPrintHum);
//Scheduler.startLoop(tftPrintPressure);
//Scheduler.startLoop(tftPrintPDM);
//Scheduler.startLoop(tftPrintALS);
void loop() {
 
 if (APDS.gestureAvailable()) {
    // a gesture was detected, read and print to serial monitor
    int gesture = APDS.readGesture();

    switch (gesture) { //通过检测手势切换菜单
      case GESTURE_UP:
        Serial.println("Detected UP gesture");

        menu++;
        if(menu>5)
        menu=1;
         Serial.println(menu);
        break;

      case GESTURE_DOWN:
        Serial.println("Detected DOWN gesture");
        menu--;
        if(menu==0||menu>6)
        menu=5;
        Serial.println(menu);
         
        break;

      case GESTURE_LEFT:
        
        Serial.println("Detected LEFT gesture");
         menu--;
        if(menu==0||menu>6)
        menu=5;
        Serial.println(menu);
        break;

      case GESTURE_RIGHT:
        Serial.println("Detected RIGHT gesture");
        menu++;
        if(menu>5)
        menu=1;
         Serial.println(menu);
        break;

      default:
        // ignore
        break;
    }
  }
  // Check if a proximity reading is available.
 
 // tftPrintTest();
  delay(500);

}

在程序里进行判断是否当前的菜单,仅举一个例子,其余类似

 if(menu==1){ //如果==1显示当前菜单
  
  // read all the sensor values
  float temperature = HTS.readTemperature();
 //float humidity    = HTS.readHumidity();

  // print each of the sensor values
  Serial.print("Temperature = ");
  Serial.print(temperature);
  Serial.println(" °C");


 
  if(p!=1)
  {p=1;//局部刷新
  tft.fillRect(0,80,240,100,BLACK);
    

【作品图片展示】

简单展示2张,有兴趣可以看视频

温度:

FkxV6KvfXQUMaG8DBNeSF9_ubA8k

湿度:

FlL4T_RlYQXBeCEqbEkDqTc64NQ-

【项目总结】

本项目依托两大开源组织(arduino,mbed)的支持,以及丰富的资源库,为我们快速高效的开发提供了可能,nano 33 ble这块小小的开发板集成了众多的传感器,令人惊讶和敬佩。本次活动主要在官方给定的例程的基础之上来完成众多的功能,最后致谢硬禾学堂和得捷提供参加本次活动的机会。

附件下载

funpack8.zip
源代码,没有st7789屏,可以通过串口打印获得相应的数据和信息

团队介绍

本人从事供配电设计方面的工作,主要方向照明,数据采集等方面的工作,对物联网非常感兴趣,利用业余时间学习和研究相关的资料,也会简单的开发一些好玩有趣的东西。
团队成员
leo121

评论

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