跳转到主要内容

使用英特尔 Edison探索空气质量监测

空气质量监测是一个关注度较高的主题,其研究领域主要包括污染增长、过敏、健康与健身意识 ,以及技术创新。 消费市场显示,市场上推出的创新性产品提高了人们监测家庭空气质量的意识。 其中有一类产品为智能表。 这类智能表可监测各种与健康相关的参数,以及空气质量。 空气质量数据发送至云系统,应用为您提示空气质量的变化,以便您了解哪 个区域需要通风。 具备空气质量意识有助于改善生活质量。 本文将探讨如何通过使用 Arduino* 生态系统测量二氧化碳、挥发性有机化合物和灰尘的浓度,并将数据发送至云服务提供商来进行空气质量监测。

英特尔Edison 平台配备了快速处理器、大容量内存,以及面向 WiFi 和蓝牙的集成连接性,非常适合启动新原型,或迁移现有原型。 Arduino 生态系统可提供一系列硬件和固件库, 支持使用英特尔 Edison 计算模块和英特尔®Edison Arduino Breakout 开发板进行试验。

<strong>硬件组件:</strong>

该项目的空气质量监测系统主要使用下列硬件组:

英特尔 Edison 计算模块
英特尔 Edison Arduino Breakout 开发板
共阴极 RGB LED + 3 个 1kΩ 电阻器
GP2Y1010AU0F 光学灰尘传感器 + 150Ω 电阻器 + 220 µF 电解质电容器
MQ-135 气体传感器
K-30 CO2 传感器
PIR 运动传感器

<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001322-1621-airqua…; alt=""><center></center> 图 1 - 硬件连接图</center>

<strong>工作原理:</strong>

图 1 所示为硬件组件与英特尔 Edison Arduino Breakout 开发板的连接。 该系统将 RGB LED 用作简单的目测指示系统来显示空气质量。

为确定某区域的整体空气质量,该系统使用三个传感器:

1. 光学灰尘传感器:用于测量某区域的灰尘。

2. 气体传感器:用于测量烟雾等挥发性有机化合物。

3. CO2 传感器:借助 I2C 接口测量二氧化碳浓度。

此外, 该系统还配备运动传感器,通过过滤掉由运动引起的暂时性灰尘浓度上升以及由于人们靠近传感器呼吸所引起的暂时性 CO2 浓度上升,以最大程度地真实反映某区域的整体空气质量。

如果未检测到运动,固件将读取空气质量传感器、分析传感器数据、更新目测指示系统,并将空气质量数据发送至云。 有关该系统的详细内容将会在“固件”部分做进一步介绍。

如欲了解有关传感器的更多内容,请点击下列链接查看数据表:

http://www.kosmodrom.com.ua/pdf/MQ135.pdf

https://www.sparkfun.com/datasheets/Sensors/gp2y1010au_e.pdf

http://www.co2meter.com/collections/co2- sensors/products/k-30-co2-sensor-module

http://www.ladyada.net/media/sensors/PIRSensor- V1.2.pdf

配置 I2C 时钟频率:

需注意 的一点是,在撰写本文时,英特尔 Edison 的默认 I2C 时钟频率高于 100kHZ,超过了 K-30 CO2 传感器的规格。 K-30 CO2 传感器所支持的最高 I2C 时钟频率 (SCL) 为 100kHz。 英特尔® Edison I2C 时钟频率可通过下列几个步骤更改为 100kHZ:

- 确保安装了最新的英特尔 Edison Yocto 固件映像:

http://www.intel.com/support/edison/sb/CS- 035180.htm

- 打开 Edison Linux 终端,并以根用户身份登录:

https://software.intel.com/zh-cn/articles/getting-started-with-the-inte…- windows

-cd /sys/devices/pci0000:00/0000:00:09.1/i2c_dw_sysnode

-echo std > mode

-cat mode

如欲了解有关英特尔 Edison 计算模块和 I2C 外设的更多信息,请访问下列链接:

http://www.intel.com/support/edison/sb/CS-035274.htm?wapkw=intel +edison+compute+module+hardware+guide

<strong>固件:</strong>

下列代码显示了空气质量系统包含的组件、宏和函数。 下面将介绍针对初始化、主循环 、读取运动传感器、读取空气质量传感器、分析整体空气质量、更新目测指示 LED,以及将数据发送至云服务提供商的函数。

包含:
1 #include <Wire.h>

宏:
01 //Pin Defines #define gasSensorPin A1 #define
02
03 dustSensorPin A0 #define dustSensorLEDPin 2 #define redRGBLEDPin 3 #define
04
05 greenRGBLEDPin 4 #define blueRGBLEDPin 5 #define motionSensorPin 6 //Air
06
07 Quality Defines #define AIR_QUALITY_OPTIMAL 2 #define
08
09 AIR_QUALITY_GOOD 1 #define
10
11 AIR_QUALITY_BAD 0 #define AIR_QUALITY_UNKNOWN -1
12
13 #define MAX_SENSOR_READINGS 10
14
15 #define SENSOR_READING_DELAY 1000 //Motion Sensor Defines
16 #define MOTION_NOT_DETECTED 0 #define MOTION_DETECTED
17
18 1 #define MOTION_DELAY_TIME 1000 //Dust Sensor Timing Parameters
19
20 (from p.5 of datasheet) #define
21
22 SAMPLE_DELAY 280 //Sampling
23
24 #define PULSEWIDTH_DELAY 40 //Pw #define
25
26 PERIOD_DELAY 9680 //T //Gas Sensor
27
28 Thresholds #define GAS_SENSOR_OPTIMAL 140 #define
29
30 GAS_SENSOR_GOOD 200 //Dust Sensor Thresholds #define
31
32 DUST_SENSOR_OPTIMAL 125 #define DUST_SENSOR_GOOD 250 //CO2
33
34 Sensor Thresholds #define CO2_SENSOR_OPTIMAL 800 #define
35
36 CO2_SENSOR_GOOD 2000

<strong>函数:</strong>

<strong>初始化:</strong> 该函数可初始化串行调试接口、I/O 针脚和 I2C 接口。

01 void setup() {
02 Serial.begin(9600);
03 pinMode(gasSensorPin, INPUT);
04 pinMode(dustSensorPin, INPUT);
05 pinMode(dustSensorLEDPin, OUTPUT);
06 pinMode(redRGBLEDPin, OUTPUT);
07 pinMode(greenRGBLEDPin, OUTPUT);
08 pinMode(blueRGBLEDPin, OUTPUT);
09 pinMode(motionSensorPin, INPUT);
10 Wire.begin(); }

主循环: 主循环可初始化系统、检查运动、读取空气质量传感器、分析整体空气质量、更新指示 LED,并将数据发送至云服务。

01 void loop() {
02 // -- Init
03 int airQuality = 0;
04 int motion = 0;
05 int sensorAirQuality[3] = {0,0,0}; //0-Gas Sensor, 1-CO2 Sensor, 2-
06
07 DustSensor
08 Serial.println("");
09 // -- Check for motion
10 motion = readMotionSensor();
11 if (motion == MOTION_NOT_DETECTED) {
12 // -- Read Air Quality Sensors
13 readAirQualitySensors(sensorAirQuality);
14 // -- Analyze Total Air Quality
15 airQuality = analyzeTotalAirQuality(sensorAirQuality
16
17 [0],sensorAirQuality[1],sensorAirQuality[2]);
18 // -- Update Indication LED
19 updateIndicationLED(airQuality);
20 // -- Update Air Quality Value for Cloud
21
22 Datastream
23 updateCloudDatastreamValue(CHANNEL_AIR_QUALITY_ID,
24
25 airQuality);
26 // -- Send Data To Cloud Service
27 sendToCloudService();
28 } }

读取运动传感器: 通过取样传感器的数字输出针脚可读取运动传感器。 如果检测到运动,传感器输出针脚将跳变至“高电平”。 该函数尝试过滤故障,并反馈是否检测到运动。

01 int readMotionSensor() {
02 // -- Init
03 int motionSensorValue = MOTION_NOT_DETECTED;
04 int motion = MOTION_NOT_DETECTED;
05 Serial.println("-Read Motion Sensor");
06 // -- Read Sensor
07 motionSensorValue = digitalRead(motionSensorPin);
08 // -- Analyze Value
09 if (motionSensorValue == MOTION_DETECTED) {
10 delay(MOTION_DELAY_TIME);
11
12 motionSensorValue = digitalRead(motionSensorPin);
13 if (motionSensorValue ==
14
15 MOTION_DETECTED) {
16 motion = MOTION_DETECTED;
17 Serial.println("--Motion Detected");
18 updateIndicationLED(AIR_QUALITY_UNKNOWN);
19 }
20 }
21 return motion; }

读取空气质量传感器: 该函数调用单独的气体、co2 和灰尘传感器函数。 函数将指针带入整数数组,以保存各传感器的空气质量结果。

1 void readAirQualitySensors(int* sensorAirQuality) {
2 Serial.println("-Read Air Quality Sensors");
3 sensorAirQuality[0] = readGasSensor();
4 sensorAirQuality[1] = readCO2Sensor();
5 sensorAirQuality[2] = readDustSensor(); }

读取气体传感器: 气体传感器可检测 NH3、NOx、乙醇、 苯,烟雾等气体。 气体传感器包含一个模拟电压输出,该输出与空气中的气体浓度成正比。 执行 A/D 换算可读取该传感器。 该函数可读取传感器、求取读数的平均值、分析传感器数据,并返回该传感器的空气质量。

01 int readGasSensor() {
02 // -- Init
03 int airQuality = 0;
04 int gasSensorValue = 0;
05 // -- Read Sensor
06 for (int i=0; i < MAX_SENSOR_READINGS; i++) {
07 gasSensorValue += analogRead(gasSensorPin);
08 delay(SENSOR_READING_DELAY);
09 }
10 gasSensorValue /= MAX_SENSOR_READINGS; //Average the sensor readings
11 // -- Update Cloud Datastream
12 Serial.print("--gasSensorValue = ");
13 Serial.println(gasSensorValue);
14 updateCloudDatastreamValue(CHANNEL_GAS_SENSOR_ID, gasSensorValue);
15 // -- Analyze Value
16 if (gasSensorValue < GAS_SENSOR_OPTIMAL) {
17 airQuality = AIR_QUALITY_OPTIMAL;
18 }
19 else if (gasSensorValue < GAS_SENSOR_GOOD) {
20 airQuality = AIR_QUALITY_GOOD;
21 }
22 else {
23 airQuality = AIR_QUALITY_BAD;
24 }
25
26 return airQuality; }

读取灰尘传感器: 灰尘传感器包含光学传感系统,该系统借助数字输出针脚通电。 通电后执行 A/D 换算可对传感器的模拟电压输出(与空气中的 灰尘成正比)进行取样。 该函数可读取传感器、求取读数的平均值、分析传感器数据, 并返回该传感器的空气质量。

01 int readDustSensor() {
02 // -- Init
03 int airQuality = 0;
04 int dustSensorValue = 0;
05 // -- Read Sensor
06 for (int i=0; i < MAX_SENSOR_READINGS; i++) {
07 digitalWrite(dustSensorLEDPin,LOW); //Enable LED
08 delayMicroseconds(SAMPLE_DELAY);
09 dustSensorValue += analogRead(dustSensorPin);
10 delayMicroseconds(PULSEWIDTH_DELAY);
11 digitalWrite(dustSensorLEDPin,HIGH); //Disable LED
12 delayMicroseconds(PERIOD_DELAY);
13 delay(SENSOR_READING_DELAY);
14 }
15 dustSensorValue /= MAX_SENSOR_READINGS; //Average the sensor readings
16 // -- Update Cloud Datastream
17 Serial.print("--dustSensorValue = ");
18 Serial.println(dustSensorValue);
19 updateCloudDatastreamValue(CHANNEL_DUST_SENSOR_ID, dustSensorValue);
20 // -- Analyze Value
21 if (dustSensorValue < DUST_SENSOR_OPTIMAL) {
22 airQuality = AIR_QUALITY_OPTIMAL;
23 }
24 else if (dustSensorValue < DUST_SENSOR_GOOD) {
25 airQuality = AIR_QUALITY_GOOD;
26 }
27 else {
28 airQuality = AIR_QUALITY_BAD;
29 } return airQuality; }

读取 CO2 传感器: CO2 传感器返回 CO2 浓度值(单位:ppm)。 CO2 传感器通过 I2C 接口读取。 该函数可读取传感器、求取读数的平均值、分析传感器数据,并返回该传感器的空气质量。

01 int readCO2Sensor() {
02 // -- Init
03 int airQuality = 0;
04 int co2SensorValue = 0;
05 int tempValue=0;
06 int invalidCount=0;
07 // -- Read Sensor
08 for (int i=0; i < MAX_SENSOR_READINGS; i++) {
09 tempValue = readCO2(); // see
10 http://cdn.shopify.com/s/files/1/0019/5952/files/Senseair-Arduino.pdf?
11
12 1264294173 for this function
13 (tempValue == 0) ? invalidCount++ : co2SensorValue +=
14
15 tempValue;
16 delay(SENSOR_READING_DELAY);
17 }
18 if (invalidCount != MAX_SENSOR_READINGS) {
19 co2SensorValue /= (MAX_SENSOR_READINGS - invalidCount);
20
21 //Average the sensor readings
22 }
23 // -- Update Cloud Datastream
24 Serial.print("--co2SensorValue = ");
25 Serial.println(co2SensorValue);
26 updateCloudDatastreamValue(CHANNEL_CO2_SENSOR_ID, co2SensorValue);
27 // -- Analyze Value
28 if (co2SensorValue < CO2_SENSOR_OPTIMAL) {
29 airQuality = AIR_QUALITY_OPTIMAL;
30 }
31 else if (co2SensorValue < CO2_SENSOR_GOOD) {
32 airQuality = AIR_QUALITY_GOOD;
33 }
34 else {
35 airQuality = AIR_QUALITY_BAD;
36 } return airQuality; }

分析整体空气质量: 该函数可通过分析传来的气体、co2 和灰尘等空气质量值确定该地区的整体空气质量。 该函数可返回该地区的整体空气质量水平。

01 int analyzeTotalAirQuality(int gasAirQuality, int
02
03 co2AirQuality, int dustAirQuality) {
04 int airQuality = 0;
05 Serial.println("-Analyze Total Air Quality");
06 if (gasAirQuality==AIR_QUALITY_BAD \
07 || dustAirQuality==AIR_QUALITY_BAD
08
09 \
10 || co2AirQuality==AIR_QUALITY_BAD)
11
12 {
13 Serial.println("--Air Quality Is
14
15 BAD");
16 airQuality = AIR_QUALITY_BAD;
17 }
18 else if (gasAirQuality == AIR_QUALITY_OPTIMAL \
19
20
21 && dustAirQuality == AIR_QUALITY_OPTIMAL \
22
23
24 && co2AirQuality==AIR_QUALITY_OPTIMAL) {
25 Serial.println("--Air Quality Is
26
27 OPTIMAL");
28 airQuality = AIR_QUALITY_OPTIMAL;
29 }
30 else {
31 Serial.println("--Air Quality Is
32
33 Good");
34 airQuality = AIR_QUALITY_GOOD;
35 }
36 return airQuality; }

更新目测指示 LED: 该函数可将指示 LED 更新至与传来的空气质量值相对应的颜色。 LED 变成蓝色表示空气质量水平达到最佳、绿色表示空气质量良好、红色表示空气质量差。 如果检测到运动,LED 将变成品红色。

01 void updateIndicationLED(int airQuality) {
02 Serial.println("-Update Indication LED");
03 // --Turn off all colors
04 digitalWrite(redRGBLEDPin,LOW);
05 digitalWrite(greenRGBLEDPin,LOW);
06 digitalWrite(blueRGBLEDPin,LOW);
07 // --Update Indication LED
08 if (airQuality == AIR_QUALITY_UNKNOWN) {
09 digitalWrite(redRGBLEDPin,HIGH);
10 digitalWrite(greenRGBLEDPin,HIGH);
11 digitalWrite(blueRGBLEDPin,HIGH);
12 }
13 else if (airQuality == AIR_QUALITY_OPTIMAL) {
14 digitalWrite(blueRGBLEDPin, HIGH);
15 }
16 else if (airQuality == AIR_QUALITY_GOOD) {
17 digitalWrite(greenRGBLEDPin, HIGH);
18 }
19 else {
20 digitalWrite(redRGBLEDPin, HIGH);
21 } }

将数据发送至云服务提供商:

如欲将英特尔® Edison 连接至 WiFi 网络,请参考下列链接:

http://www.intel.com/support/edison/sb/CS- 035342.htm

<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001322-1622-xively…; alt=""></center>
图 2 - xively.com 馈送

在本示例中, xively.com 将用作接收空气质量数据的云服务提供商。 图 2 所示为由四条通道组成的示例馈送。 “函数” 部分将对这些通道做进一步介绍。 集成 xively.com 要求将 Http Client 和 Xively 库添加至 Arduino IDE。 请点击以下链接,查看关于 xively.com创建账户、Arduino 教程,以及将库集成于 Arduino IDE 的更多信息。

https://xively.com/dev/tutorials/arduino_wi- fi/

下列代码显示了可添加至空气质量系统的组件、宏和函数示例,可因此添加 xively.com 支持。

包含:
1 #include <WiFi.h>
2 #include <HttpClient.h>
3 #include <Xively.h>

宏:
01 //Xively.com Defines #define XIVELY_FEED <enter
02
03 your feed number here>
04 #define XIVELY_KEY <enter your key string here>
05 #define XIVELY_HTTP_SUCCESS 200 #define CHANNEL_AIR_QUALITY
06
07 "AIR_QUALITY" #define CHANNEL_AIR_QUALITY_ID 0
08
09 #define CHANNEL_GAS_SENSOR "GAS_SENSOR" #define
10
11 CHANNEL_GAS_SENSOR_ID 1 #define CHANNEL_CO2_SENSOR
12
13 "CO2_SENSOR" #define CHANNEL_CO2_SENSOR_ID 2
14
15 #define CHANNEL_DUST_SENSOR "DUST_SENSOR" #define
16
17 CHANNEL_DUST_SENSOR_ID 3 #define
18
19 MAX_CHANNELS
20
21 4

全局变量:

01 //Xively Datastream XivelyDatastream datastreams[] = {
02 XivelyDatastream(CHANNEL_AIR_QUALITY, strlen
03
04 (CHANNEL_AIR_QUALITY), DATASTREAM_FLOAT),
05 XivelyDatastream(CHANNEL_GAS_SENSOR, strlen
06
07 (CHANNEL_GAS_SENSOR), DATASTREAM_FLOAT),
08 XivelyDatastream(CHANNEL_CO2_SENSOR, strlen
09
10 (CHANNEL_CO2_SENSOR), DATASTREAM_FLOAT),
11 XivelyDatastream(CHANNEL_DUST_SENSOR, strlen
12
13 (CHANNEL_DUST_SENSOR), DATASTREAM_FLOAT)
14 }; //Xively Feed XivelyFeed feed(XIVELY_FEED, datastreams,
15
16 MAX_CHANNELS);
17
18 //Xively Client WiFiClient client; XivelyClient xivelyclient(client);

<strong>函数:</strong>

更新数据流: 调用该函数可更新 xively.com 通道数据流的值。 通道 ID 和数据流的值可传递至该函数。 如图 2 所示,该系统使用四条数据流。 数据流可更新为气体、co2 和灰尘传感器函数的原始传感器数据。 此外,主循环中的数据流 还可更新为整体空气质量值。

1 void updateCloudDatastreamValue(int channelID, int
2
3 value) {
4 // -- Update the Datastream Value
5 datastreams[channelID].setFloat(value); }

将数据流发送至 Xively: 该函数针对 xively.com 馈送执行 PUT 操作 。 函数返回成功或失败代码状态。 主循环调用该函数。

01 void sendToCloudService() {
02 int status=0;
03 Serial.println("-Send To Cloud Service”);
04
05 // -- Upload the Datastream to Xively
06 status = xivelyclient.put(feed, XIVELY_KEY);
07 // -- Verify Transaction
08 if (status == XIVELY_HTTP_SUCCESS) {
09 Serial.println("--HTTP OK");
10 }
11 else {
12 Serial.print("--ERROR: ");
13 Serial.println(status);
14 } }

<strong>总结:</strong>

欢迎大家使用英特尔 Edison 平台研究空气质量监测。 挑战自我,添加其他显示各传感器状态的指示,添加针对空气质量变化的警告触发器增强云服务体验,并寻找机会将空气质量监测与其他系统相集成。
<center><img src="http://intel.eetrend.com/files/2016-03/wen_zhang_/100001322-1623-system…; alt=""></center>

文章来源:<a href="https://software.intel.com/zh-cn/articles/exploring-air-quality-monitor…