探索使用 Intel® Edison 进行空气质量监测
本文展示了一种通过使用 Arduino* 生态系统测量二氧化碳、挥发性有机化合物 (VOC) 和灰尘水平,并将数据发送到云服务提供商来探索空气质量监测的方法。
获取新的 Intel® IoT Developer Kit,这是一个完整的软硬件解决方案,使开发人员能够使用 Intel® Galileo 和 Intel® Edison 板创建令人兴奋的新解决方案。请访问 Intel® 物联网开发者中心。
随着污染、过敏敏感性、健康与健身意识以及技术创新的兴起,空气质量监测是一个有趣的研究课题。消费品市场已推出创新产品,提高了人们对家庭空气质量监测的认识。其中一种产品是智能秤。这些智能秤可监测各种与健康相关的参数以及空气质量。空气质量数据会发送到云端,应用程序可以向您发出空气质量变化的警报,以便您知道何时需要通风。了解空气质量可以提高生活质量。本文展示了一种通过使用 Arduino* 生态系统测量二氧化碳、挥发性有机化合物 (VOC) 和灰尘水平,并将数据发送到云服务提供商来探索空气质量监测的方法。
Intel® Edison 平台凭借其快速的处理器、大内存容量以及集成的 WiFi 和蓝牙连接功能,非常适合启动新原型或迁移现有原型。Arduino 生态系统提供了一套功能强大的硬件和固件库,可用于使用 Intel® Edison 计算模块和 Intel® Edison Arduino 扩展板进行实验。
如需了解有关 Intel Edison 平台的更多信息,请参阅以下链接
http://www.intel.com/content/www/us/en/do-it-yourself/edison.html
硬件组件
该项目使用以下硬件组件构建空气质量监测系统
- Intel® Edison 计算模块
- Intel® Edison Arduino 扩展板
- 共阴极 RGB LED + 3 个 1kΩ 电阻
- GP2Y1010AU0F 光学灰尘传感器 + 150Ω 电阻 + 220 µF 电解电容
- MQ-135 气体传感器
- K-30 CO2 传感器
- PIR 运动传感器
工作原理
图 1 显示了硬件组件与 Intel® Edison Arduino 扩展板的连接。该系统使用 RGB LED 作为简单的视觉指示系统来显示空气质量。
为了确定一个区域的总空气质量,使用了三个传感器
- 使用光学灰尘传感器测量该区域的灰尘。
- 使用气体传感器测量挥发性有机化合物 (VOC),例如烟雾。
- 使用带 I2C 接口的 CO2 传感器测量二氧化碳水平。
此外,还使用运动传感器来帮助系统更好地代表区域内的总空气质量,方法是过滤掉由运动引起的灰尘浓度暂时增加,以及由靠近传感器呼吸的人引起的 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 时钟频率
需要注意的是,在撰写本文时,Intel® Edison 的默认 I2C 时钟频率高于 100kHz,这超出了 K-30 CO2 传感器的规格。K-30 CO2 传感器支持的最大 I2C 时钟频率 (SCL) 为 100kHz。可以通过以下几个步骤将 Intel® Edison 的 I2C 时钟频率更改为 100kHz
-确保安装了最新的 Intel® Edison Yocto 固件映像
http://www.intel.com/support/edison/sb/CS-035180.htm
-打开 Edison Linux 终端并以 root 用户登录
https://software.intel.com/en-us/articles/getting-started-with-the-intel-edison-board-on-windows
-cd /sys/devices/pci0000:00/0000:00:09.1/i2c_dw_sysnode
-echo std > mode
-cat mode
如需了解有关 Intel® Edison 计算模块和 I2C 外设的更多信息,请参阅以下链接
固件
以下代码显示了空气质量系统的包含文件、宏和函数。将讨论初始化、主循环、读取运动传感器、读取空气质量传感器、分析总空气质量、更新视觉指示 LED 和将数据发送到云服务提供商的函数。
包含
#include <Wire.h>
宏
//Pin Defines
#define gasSensorPin A1
#define dustSensorPin A0
#define dustSensorLEDPin 2
#define redRGBLEDPin 3
#define greenRGBLEDPin 4
#define blueRGBLEDPin 5
#define motionSensorPin 6
//Air Quality Defines
#define AIR_QUALITY_OPTIMAL 2
#define AIR_QUALITY_GOOD 1
#define AIR_QUALITY_BAD 0
#define AIR_QUALITY_UNKNOWN -1
#define MAX_SENSOR_READINGS 10
#define SENSOR_READING_DELAY 1000
//Motion Sensor Defines
#define MOTION_NOT_DETECTED 0
#define MOTION_DETECTED 1
#define MOTION_DELAY_TIME 1000
//Dust Sensor Timing Parameters (from p.5 of datasheet)
#define SAMPLE_DELAY 280 //Sampling
#define PULSEWIDTH_DELAY 40 //Pw
#define PERIOD_DELAY 9680 //T
//Gas Sensor Thresholds
#define GAS_SENSOR_OPTIMAL 140
#define GAS_SENSOR_GOOD 200
//Dust Sensor Thresholds
#define DUST_SENSOR_OPTIMAL 125
#define DUST_SENSOR_GOOD 250
//CO2 Sensor Thresholds
#define CO2_SENSOR_OPTIMAL 800
#define CO2_SENSOR_GOOD 2000
函数
初始化:此函数初始化串行调试接口、I/O 引脚和 I2C 接口。
void setup() {
Serial.begin(9600);
pinMode(gasSensorPin, INPUT);
pinMode(dustSensorPin, INPUT);
pinMode(dustSensorLEDPin, OUTPUT);
pinMode(redRGBLEDPin, OUTPUT);
pinMode(greenRGBLEDPin, OUTPUT);
pinMode(blueRGBLEDPin, OUTPUT);
pinMode(motionSensorPin, INPUT);
Wire.begin();
}
主循环:主循环初始化系统,检查运动,读取空气质量传感器,分析总空气质量,更新指示 LED,并将数据发送到云服务。
void loop() {
// -- Init
int airQuality = 0;
int motion = 0;
int sensorAirQuality[3] = {0,0,0}; //0-Gas Sensor, 1-CO2 Sensor, 2-DustSensor
Serial.println("");
// -- Check for motion
motion = readMotionSensor();
if (motion == MOTION_NOT_DETECTED) {
// -- Read Air Quality Sensors
readAirQualitySensors(sensorAirQuality);
// -- Analyze Total Air Quality
airQuality = analyzeTotalAirQuality(sensorAirQuality[0],sensorAirQuality[1],sensorAirQuality[2]);
// -- Update Indication LED
updateIndicationLED(airQuality);
// -- Update Air Quality Value for Cloud Datastream
updateCloudDatastreamValue(CHANNEL_AIR_QUALITY_ID, airQuality);
// -- Send Data To Cloud Service
sendToCloudService();
}
}
读取运动传感器:通过对传感器数字输出引脚进行采样来读取运动传感器。如果检测到运动,传感器输出引脚将变为高电平。该函数尝试过滤毛刺并返回是否检测到运动。
int readMotionSensor() {
// -- Init
int motionSensorValue = MOTION_NOT_DETECTED;
int motion = MOTION_NOT_DETECTED;
Serial.println("-Read Motion Sensor");
// -- Read Sensor
motionSensorValue = digitalRead(motionSensorPin);
// -- Analyze Value
if (motionSensorValue == MOTION_DETECTED) {
delay(MOTION_DELAY_TIME);
motionSensorValue = digitalRead(motionSensorPin);
if (motionSensorValue == MOTION_DETECTED) {
motion = MOTION_DETECTED;
Serial.println("--Motion Detected");
updateIndicationLED(AIR_QUALITY_UNKNOWN);
}
}
return motion;
}
读取空气质量传感器:此函数调用单独的气体、co2 和灰尘传感器函数。该函数接受指向整数数组的指针,用于存储每个传感器的空气质量结果。
void readAirQualitySensors(int* sensorAirQuality)
{
Serial.println("-Read Air Quality Sensors");
sensorAirQuality[0] = readGasSensor();
sensorAirQuality[1] = readCO2Sensor();
sensorAirQuality[2] = readDustSensor();
}
读取气体传感器:气体传感器可以检测氨气、氮氧化物、酒精、苯和烟雾等气体。气体传感器有一个模拟电压输出,与空气中的气体水平成正比。执行 A/D 转换来读取此传感器。该函数读取传感器,对读数进行平均,分析传感器数据,并返回该传感器的空气质量。
int readGasSensor() {
// -- Init
int airQuality = 0;
int gasSensorValue = 0;
// -- Read Sensor
for (int i=0; i < MAX_SENSOR_READINGS; i++) {
gasSensorValue += analogRead(gasSensorPin);
delay(SENSOR_READING_DELAY);
}
gasSensorValue /= MAX_SENSOR_READINGS; //Average the sensor readings
// -- Update Cloud Datastream
Serial.print("--gasSensorValue = ");
Serial.println(gasSensorValue);
updateCloudDatastreamValue(CHANNEL_GAS_SENSOR_ID, gasSensorValue);
// -- Analyze Value
if (gasSensorValue < GAS_SENSOR_OPTIMAL) {
airQuality = AIR_QUALITY_OPTIMAL;
}
else if (gasSensorValue < GAS_SENSOR_GOOD) {
airQuality = AIR_QUALITY_GOOD;
}
else {
airQuality = AIR_QUALITY_BAD;
}
return airQuality;
}
读取灰尘传感器:灰尘传感器包含一个光学传感系统,该系统通过数字输出引脚通电。然后执行 A/D 转换来采样传感器的模拟电压输出,该输出与空气中的灰尘成正比。此函数读取传感器,对读数进行平均,分析传感器数据,并返回该传感器的空气质量。
int readDustSensor() {
// -- Init
int airQuality = 0;
int dustSensorValue = 0;
// -- Read Sensor
for (int i=0; i < MAX_SENSOR_READINGS; i++) {
digitalWrite(dustSensorLEDPin,LOW); //Enable LED
delayMicroseconds(SAMPLE_DELAY);
dustSensorValue += analogRead(dustSensorPin);
delayMicroseconds(PULSEWIDTH_DELAY);
digitalWrite(dustSensorLEDPin,HIGH); //Disable LED
delayMicroseconds(PERIOD_DELAY);
delay(SENSOR_READING_DELAY);
}
dustSensorValue /= MAX_SENSOR_READINGS; //Average the sensor readings
// -- Update Cloud Datastream
Serial.print("--dustSensorValue = ");
Serial.println(dustSensorValue);
updateCloudDatastreamValue(CHANNEL_DUST_SENSOR_ID, dustSensorValue);
// -- Analyze Value
if (dustSensorValue < DUST_SENSOR_OPTIMAL) {
airQuality = AIR_QUALITY_OPTIMAL;
}
else if (dustSensorValue < DUST_SENSOR_GOOD) {
airQuality = AIR_QUALITY_GOOD;
}
else {
airQuality = AIR_QUALITY_BAD;
}
return airQuality;
}
读取 CO2 传感器:CO2 传感器返回百万分率 (ppm) 的 CO2 浓度水平。CO2 传感器通过 I2C 接口读取。此函数读取传感器,对读数进行平均,分析传感器数据,并返回该传感器的空气质量。
int readCO2Sensor() {
// -- Init
int airQuality = 0;
int co2SensorValue = 0;
int tempValue=0;
int invalidCount=0;
// -- Read Sensor
for (int i=0; i < MAX_SENSOR_READINGS; i++) {
tempValue = readCO2(); // see http://cdn.shopify.com/s/files/1/0019/5952/files/Senseair-Arduino.pdf?1264294173 for this function
(tempValue == 0) ? invalidCount++ : co2SensorValue += tempValue;
delay(SENSOR_READING_DELAY);
}
if (invalidCount != MAX_SENSOR_READINGS) {
co2SensorValue /= (MAX_SENSOR_READINGS - invalidCount); //Average the sensor readings
}
// -- Update Cloud Datastream
Serial.print("--co2SensorValue = ");
Serial.println(co2SensorValue);
updateCloudDatastreamValue(CHANNEL_CO2_SENSOR_ID, co2SensorValue);
// -- Analyze Value
if (co2SensorValue < CO2_SENSOR_OPTIMAL) {
airQuality = AIR_QUALITY_OPTIMAL;
}
else if (co2SensorValue < CO2_SENSOR_GOOD) {
airQuality = AIR_QUALITY_GOOD;
}
else {
airQuality = AIR_QUALITY_BAD;
}
return airQuality;
}
分析总空气质量:此函数通过分析传递给该函数的气体、co2 和灰尘空气质量值来确定该区域的总空气质量。该函数返回该区域的总空气质量水平。
int analyzeTotalAirQuality(int gasAirQuality, int co2AirQuality, int dustAirQuality) {
int airQuality = 0;
Serial.println("-Analyze Total Air Quality");
if (gasAirQuality==AIR_QUALITY_BAD \
|| dustAirQuality==AIR_QUALITY_BAD \
|| co2AirQuality==AIR_QUALITY_BAD) {
Serial.println("--Air Quality Is BAD");
airQuality = AIR_QUALITY_BAD;
}
else if (gasAirQuality == AIR_QUALITY_OPTIMAL \
&& dustAirQuality == AIR_QUALITY_OPTIMAL \
&& co2AirQuality==AIR_QUALITY_OPTIMAL) {
Serial.println("--Air Quality Is OPTIMAL");
airQuality = AIR_QUALITY_OPTIMAL;
}
else {
Serial.println("--Air Quality Is Good");
airQuality = AIR_QUALITY_GOOD;
}
return airQuality;
}
更新视觉指示 LED:此函数更新指示 LED,使其颜色与传递给该函数的空气质量值相匹配。LED 在空气质量水平最佳时呈蓝色,在空气质量水平良好时呈绿色,在空气质量水平差时呈红色。检测到运动时,LED 呈品红色。
void updateIndicationLED(int airQuality) {
Serial.println("-Update Indication LED");
// --Turn off all colors
digitalWrite(redRGBLEDPin,LOW);
digitalWrite(greenRGBLEDPin,LOW);
digitalWrite(blueRGBLEDPin,LOW);
// --Update Indication LED
if (airQuality == AIR_QUALITY_UNKNOWN) {
digitalWrite(redRGBLEDPin,HIGH);
digitalWrite(greenRGBLEDPin,HIGH);
digitalWrite(blueRGBLEDPin,HIGH);
}
else if (airQuality == AIR_QUALITY_OPTIMAL) {
digitalWrite(blueRGBLEDPin, HIGH);
}
else if (airQuality == AIR_QUALITY_GOOD) {
digitalWrite(greenRGBLEDPin, HIGH);
}
else {
digitalWrite(redRGBLEDPin, HIGH);
}
}
将数据发送到云服务提供商
如需将 Intel® Edison 连接到 WiFi 网络,请参阅以下链接
http://www.intel.com/support/edison/sb/CS-035342.htm
在本示例中,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 支持。
包含
#include <WiFi.h>
#include <HttpClient.h>
#include <Xively.h>
宏
//Xively.com Defines #define XIVELY_FEED <enter your feed number here> #define XIVELY_KEY <enter your key string here> #define XIVELY_HTTP_SUCCESS 200 #define CHANNEL_AIR_QUALITY "AIR_QUALITY" #define CHANNEL_AIR_QUALITY_ID 0 #define CHANNEL_GAS_SENSOR "GAS_SENSOR" #define CHANNEL_GAS_SENSOR_ID 1 #define CHANNEL_CO2_SENSOR "CO2_SENSOR" #define CHANNEL_CO2_SENSOR_ID 2 #define CHANNEL_DUST_SENSOR "DUST_SENSOR" #define CHANNEL_DUST_SENSOR_ID 3 #define MAX_CHANNELS 4
全局变量
//Xively Datastream
XivelyDatastream datastreams[] = {
XivelyDatastream(CHANNEL_AIR_QUALITY, strlen(CHANNEL_AIR_QUALITY), DATASTREAM_FLOAT),
XivelyDatastream(CHANNEL_GAS_SENSOR, strlen(CHANNEL_GAS_SENSOR), DATASTREAM_FLOAT),
XivelyDatastream(CHANNEL_CO2_SENSOR, strlen(CHANNEL_CO2_SENSOR), DATASTREAM_FLOAT),
XivelyDatastream(CHANNEL_DUST_SENSOR, strlen(CHANNEL_DUST_SENSOR), DATASTREAM_FLOAT)
};
//Xively Feed
XivelyFeed feed(XIVELY_FEED, datastreams, MAX_CHANNELS);
//Xively Client
WiFiClient client;
XivelyClient xivelyclient(client);
函数
更新数据流:调用此函数来更新 xively.com 通道数据流的值。将通道 ID 和数据流值传递给该函数。在此系统中,如图 2 所示,使用了四个数据流。数据流使用来自气体、co2 和灰尘传感器函数的原始传感器数据进行更新。此外,在主循环中还使用总空气质量值更新了一个数据流。
void updateCloudDatastreamValue(int channelID, int value) {
// -- Update the Datastream Value
datastreams[channelID].setFloat(value);
}
将数据流发送到 Xively:此函数对 xively.com 提要执行 PUT 操作。该函数返回成功状态或错误代码。主循环调用此函数。
void sendToCloudService() {
int status=0;
Serial.println("-Send To Cloud Service”);
// -- Upload the Datastream to Xively
status = xivelyclient.put(feed, XIVELY_KEY);
// -- Verify Transaction
if (status == XIVELY_HTTP_SUCCESS) {
Serial.println("--HTTP OK");
}
else {
Serial.print("--ERROR: ");
Serial.println(status);
}
}
摘要
希望您喜欢使用 Intel Edison 平台探索空气质量监测。挑战自己添加额外的指示来显示每个传感器的状态,为云服务体验添加警报触发器以应对空气质量变化,并寻找将空气质量监测与其他系统集成的机会。
关于作者
Mike Rylee 是 Intel 公司的软件工程师,在嵌入式系统以及 Android*、Windows*、iOS* 和 Mac* 应用程序开发方面拥有丰富的经验。他目前致力于 Android 和物联网的开发。
++本示例源代码根据 Intel Sample Source License 发布
声明本文档不授予任何知识产权的许可(明示或暗示,通过禁止反悔或其他方式)。
Intel 否认所有明示和暗示的保证,包括但不限于适销性、特定用途的适用性以及非侵权性的暗示保证,以及因履约过程、交易过程或贸易用途而产生的任何保证。
本文档包含关于正在开发的产品、服务和/或流程的信息。此处提供所有信息如有更改,恕不另行通知。请联系您的 Intel 代表以获取最新的预测、计划、规格和路线图。
所描述的产品和服务可能包含称为勘误的缺陷或错误,这可能导致与公布的规格不符。当前的已特性化勘误可应要求提供。
可以通过致电 1-800-548-4725 或访问 www.intel.com/design/literature.htm 获取包含订单号且本文档中引用的文件的副本。
Intel 和 Intel 标志是 Intel Corporation 在美国和/或其他国家/地区的商标。
*其他名称和品牌可能被声明为他方财产
© 2015 Intel Corporation。
立即开始创新!Intel® 物联网开发者计划提供知识、工具、套件以及专家社区,助您快速轻松地将您的创新想法转化为物联网解决方案。
通过 Intel® IoT Developer Kit for Intel® Edison 和 Intel® Galileo 平台,尽情畅想,动手创造。这些套件是多功能、性能优化且完全集成的端到端物联网解决方案,支持各种编程环境、工具、安全、云连接和硬件。
如需更多资源并了解新的 Intel® 物联网开发者套件 v1.0 如何帮助您简化物联网项目
- 下载 Intel® 物联网开发者套件
- 访问 Intel® 物联网开发者中心
- 参加我们的 Roadshows,获取创建您自己的物联网项目的实践培训