Arduino开发实例-DIY空气粉尘密度检测仪

DIY空气粉尘密度检测仪

1、应用介绍

空气污染是许多城市的主要问题,空气质量指数每天都在恶化。 根据世界卫生组织的报告,由于空气中存在的有害颗粒的影响而过早死亡的人比死于车祸的人多。 根据环境保护署 (EPA) 的说法,室内空气的毒性可能是室外空气的 2 到 5 倍。

在本次DIY实例中,将实现一个空气粉尘密度检测仪,用于检测空气中的粉尘颗粒密度,从而达到空气质量检测目的。

在实例中,我们将夏普的GP2Y1014AU0F 传感器与 Arduino Nano 连接,以测量空气中的灰尘密度。 然后通过OLED 显示屏也用于显示测量值。

夏普的 GP2Y1014AU0F 灰尘传感器在检测香烟烟雾等非常细小的颗粒方面非常有效。 它设计用于空气净化器和空调。

本次DIY实例将使用到如下配件:

  • Arduino Nano
  • 夏普GP2Y1014AU0F传感器
  • 0.96寸 SPI OLED显示模块
  • 连接线
  • 220 µf 电容
  • 150 Ω 电阻
  • 面包板

关于OLED的驱动,前面的文章做过详细介绍,请参考:

关于GP2Y1014AU0F,前面文章有做过详细介绍,请参考:

2、GP2Y1014AU0F传感器介绍

GP2Y1014AU0F 是一款微型六针模拟输出光学空气质量/光学灰尘传感器,旨在感应空气中的灰尘颗粒。 它的工作原理是激光散射。 在传感器模块内部,一个红外发光二极管和一个光电传感器在进气孔附近对角排列,如下图所示:

在这里插入图片描述

当含有灰尘颗粒的空气进入传感器室时,灰尘颗粒将 IR LED 光散射到光电探测器。 散射光的强度取决于尘埃颗粒。 空气中的尘埃颗粒越多,光的强度就越大。 传感器 VOUT 引脚的输出电压根据散射光的强度而变化。

GP2Y1014AU0F的引脚说明如下:

在这里插入图片描述

序号 引脚名称 引脚描述
1 V-LED LED 电源引脚,通过 150Ω 电阻连接到 5V
2 LED-GND LED接地引脚
3 LED 用于切换 LED 开/关。
4 S-GND 传感器接地引脚
5 VOUT 传感器模拟信号输出引脚
6 VCC 传感器电源引脚

本次实例将使用SPI接口OLED,其引脚说明如下:

在这里插入图片描述

引脚名称 别名 描述
Gnd Ground 接地引脚
Vdd Vcc, 5V 电源引脚 (3-5V)
SCK D0,SCL,CLK 时钟引脚. 可用于 I2C和SPI
SDA D1,MOSI 数据引脚. 可用于IIC和SPI
RES RST, RESET 重置引脚,只对SPI有效
DC A0 数据、命令控制引脚,用于SPI
CS Chip Select 片选引脚,用于SPI

3、应用硬件接线图

在这里插入图片描述

电路非常简单,因为我们只是将 GP2Y10 传感器和 OLED 显示模块与 Arduino Nano 连接起来。 GP2Y10 传感器和 OLED 显示模块均采用 +5V 和 GND 供电。 V0 引脚与 Arduino Nano 的 A5 引脚相连。 传感器的 LED 引脚连接到 Arduino 的数字引脚 12。 由于 OLED Display 模块使用 SPI 通信,我们在 OLED 模块和 Arduino Nano 之间建立了 SPI 通信。 连接如下表所示:

序号 OLED模块引脚 Arduino引脚
1 GND Ground
2 VCC 5V
3 D0 10
4 D1 9
5 RES 13
6 DC 11
7 CS 12
序号 传感器引脚 Arduino 引脚
1 Vcc 5V
2 VO A5
3 S-GND GND
4 LED 7
5 LED-GND GND
6 V-LED 5V Through 150Ω Resistor

4、驱动实现

本次DIY实例将使用如下开源驱动库:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <SPI.h>
#include <Adafruit\_GFX.h>
#include <Adafruit\_SSD1306.h>

#define SCREEN\_WIDTH 128 // OLED display width, in pixels
#define SCREEN\_HEIGHT 64 // OLED display height, in pixels

// // SPI引脚定义
#define OLED\_MOSI 9
#define OLED\_CLK 10
#define OLED\_DC 11
#define OLED\_CS 12
#define OLED\_RESET 13

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

int measurePin = A5;
int ledPower = 7;

float voMeasured = 0;
float calcVoltage = 0;
float dustDensity = 0;

void setup(){
Serial.begin(9600);
pinMode(ledPower,OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay();
display.display();
}

void loop(){
digitalWrite(ledPower,LOW);
delayMicroseconds(280);

voMeasured = analogRead(measurePin);

delayMicroseconds(40);
digitalWrite(ledPower,HIGH);
delayMicroseconds(9680);

calcVoltage = voMeasured\*(5.0/1024);
dustDensity = 0.17\*calcVoltage-0.1;

if ( dustDensity < 0)
{
dustDensity = 0.00;
}

Serial.println("Raw Signal Value (0-1023):");
Serial.println(voMeasured);

Serial.println("Voltage:");
Serial.println(calcVoltage);

Serial.println("Dust Density:");
Serial.println(dustDensity);

display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(85,22);
display.println("Dust");
display.setCursor(85,38);
display.println("Density");
display.setTextSize(3);
display.setCursor(0,13);
display.println(dustDensity);
display.setCursor(6,43);
display.setTextSize(2);
display.println("ug/m3");
display.display();
display.clearDisplay();

delay(1000);
}

应用代码如何工作?

1)导入依赖头文件

1
2
3
4
#include <SPI.h>
#include <Adafruit\_GFX.h>
#include <Adafruit\_SSD1306.h>

2)定义OLED相关信息

1
2
3
4
5
6
7
8
9
10
#define SCREEN\_WIDTH 128
#define SCREEN\_HEIGHT 64

// SPI引脚定义
#define OLED\_MOSI 9
#define OLED\_CLK 10
#define OLED\_DC 11
#define OLED\_CS 12
#define OLED\_RESET 13

3)定义OLED实例

1
2
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);

4)定义传感器引脚

1
2
3
int sensePin = A5;
int ledPin = 7;

5)在setup函数中初始化设备

1
2
3
4
5
6
Serial.begin(9600);
pinMode(ledPower,OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay();
display.display();

6)在loop函数中采集传感器数据并显示

1
2
3
4
5
6
7
8
9
digitalWrite(ledPower,LOW);
delayMicroseconds(280);

voMeasured = analogRead(measurePin);

delayMicroseconds(40);
digitalWrite(ledPower,HIGH);
delayMicroseconds(9680);

在 loop() 函数中,从 Arduino Nano 的模拟引脚 5 读取电压值。 首先,打开 IR LED,然后等待 0.28 毫秒,然后再读取输出电压。 之后,从模拟引脚读取电压值。 此操作大约需要 40 到 50 微秒,因此在关闭灰尘传感器 LED 之前引入 40 微秒的延迟。 根据规范,LED 应每 10ms 脉冲一次,因此等待 10ms 周期的剩余时间 = 10000 - 280 - 40 = 9680 微秒。

然后,使用输出电压和信号值计算灰尘密度:

1
2
3
sigVolt = outVo\*(5/1024);
dustLevel = 0.17 \* sigVolt - 0.1;

接着,显示转换数据:

1
2
3
4
5
6
7
8
9
10
display.setTextSize(1);
display.setTextColor(WHITE);
display.println("Dust");
display.println("Density");
display.setTextSize(3);
display.println(dustLevel);

display.display();
display.clearDisplay();

文章来源: https://iotsmart.blog.csdn.net/article/details/128110312