一、硬件介绍
1、产品特点
空气质量评估板用于评估 Telaire 空气质量传感器,可支持 SM-PWM-01C 粉尘传感器,串行输出可以配置为通过 USB 连接将传感器数据发送到 PC,进行记录和分析等。
特性
Arduino 平台
保留的 SM-PWM-01C 传感器接口
保留的 T6713 二氧化碳传感器接口
保留的 T9602 温度和湿度传感器接口
支持蓝牙 BLE4.0 OSPF 模块
支持 128*64 OLED 屏幕
外部 USB 电源
参数 额定值
供电电源 5V DC
供电电流 1A
工作温度范围 0~60°
工作湿度范围 0~95%RH
输出电平(3V3) Low:0.8V Hight:2.7V
支持接口 I2C:T9602 温湿度传感器 UART:T6713 二氧化碳传感器 PWM:灰尘传感器 I2C:OLED屏幕模块
实物图
2、粉尘传感器
SM-PWM-01C是一款利用光学方法检测空气中粉尘浓度的传感器。在传感器中一个红外LED 和一个光接收器光轴相交,当带粉尘的气流通过交叉区域,产生折射光。光接收器检测到粉尘反射的红外LED光线,根据输出信号的强弱判断粉尘的浓度。粉尘传感器能检测像香烟颗粒大小的颗粒物与室内灰尘等大颗粒,通过输出PWM脉冲信号宽度来区分。
管脚 管脚定义
GND 地
P2 大颗粒粉尘的低脉冲输出P2
VCC 电源电压
P1 小颗粒粉尘的低脉冲输出P1
NC ——
3、OLED屏幕
0.96寸6针oled屏幕
主要参数
通信方式:lIC、SPI。 亮度、对比度可以通过程序指令控制。 OLED屏幕内部驱动芯片:SSD1306。
可根据后面焊接电阻R的选择,从而选择不同的通信方式(SPI / I2C)
引脚 定义
GND 电源负
VCC 电源正 3.3V-5V
SCL 时钟信号线
SDA 双向数据线
RES 复位
D/C 数据或命令切换
4、Arduino 兼容板(Ardunio UNO)
板载的MCU为8位微控制器 ATMEGA328P-PU
ATMEGA328P-PU 是高性能Atmel picoPower 8位AVR基于RISC的微控制器结合了32KB ISP闪存存储器,1024B EEPROM,2KB SRAM等;
5、气体检测模块(Arduino Nicla Sense ME)
Nicla Sense ME,具有低功耗气体、压力、温度和湿度传感器;
能够检测挥发性有机化合物(VOC)以及CO2等其他气体。
二、硬件连接
AAS-AQS-UNO Nicla ME
5V 5V
GND GND
RX(D3) TX
TX(D2) RX
实物图
三、功能实现思想
室内空气质量监测警报系统
1、实时在OLED屏幕上显示当前 CO₂、温湿度、PM2.5、空气质量指标等数据;
2、当空气质量指标超出设定的范围值,将触发警报在OLED屏幕上显示相关警告信息;
实现方法:
通过软件串口功能接收模块检测到处理后的数据,将数据实时显示到OLED屏幕上;
当数据变化时,将更新显示新数据,若Air Quality(空气质量指数)超过100时,OLED屏幕上将输出警告信息:
display.print("Warning: Air Quality Bad!");
四、代码编写
检测模块输出数据内容
例:
iaq: 50 // 室内空气质量指数: 50 (优秀)
co2_eq: 600 // CO2当前浓度: 600 ppm (良好)
comp_t: 22 // 温度: 22°C
comp_h: 73 // 湿度: 73%
#include <SPI.h> #include <Wire.h> #include <PinChangeInterrupt.h> #include "SM-PWM-01C.h" #include <SoftwareSerial.h> #include <string.h> // 屏幕上方显示内容 char ScreenHeader[] = " Air Quality Display"; // OLED部分库 #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 64 #define OLED_MOSI 11 #define OLED_CLK 12 #define OLED_DC 9 #define OLED_CS 11 #define OLED_RESET 10 Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS); SoftwareSerial mySerial(3, 2); // RX, TX static int tempData, humData, co2Data, airData; bool newDataReceived = false; void calcPM2(); void setup() { Serial.begin(115200); mySerial.begin(9600); // OELD初始化 display.begin(SSD1306_SWITCHCAPVCC); display.clearDisplay(); display.display(); pinMode(PM2_IN_PIN, INPUT); // Pin 7 pinMode(PM2_OUT_PIN, OUTPUT); // Pin 13 // 设置中断引脚 / 回调函数(calcPM2) / 状态改变时 attachPCINT(digitalPinToInterrupt(PM2_IN_PIN), calcPM2, CHANGE); } void showData(){ if (mySerial.available() >= 4) { // 数据格式: 25,50,800,60 tempData = mySerial.parseInt(); humData = mySerial.parseInt(); co2Data = mySerial.parseInt(); airData = mySerial.parseInt(); newDataReceived = true; // 清空缓冲区直到换行 while (mySerial.available() && mySerial.read() != '\n') { } } } void loop() { showData(); // 每隔samplerate时间刷新显示 if (millis() >= (samplerate + sampletime)) { CalculateDustValue(); sampletime = millis(); // 显示内容 displayReading(); } } void displayReading() { display.clearDisplay(); // 屏幕标题 display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(0, 0); // header display.print(ScreenHeader); // 读数区域 if(newDataReceived){ // PM2.5 display.setTextSize(1); display.setCursor(1, 15); display.print("PM2.5 Value: "); display.print(PM2_Value); display.print(" ug/m3"); // 温度 display.setTextSize(1); display.setCursor(1, 30); display.print("T: "); display.print(tempData); display.print(" C"); // 湿度 display.setCursor(80, 30); display.print("H: "); display.print(humData); display.print(" %"); // CO2 display.setCursor(20, 45); display.print("CO2: "); display.print(co2Data); display.print(" ppm"); // 空气质量指标 display.setTextSize(1); display.setCursor(10, 57); display.print("Air Quality: "); display.print(airData); // 超过范围 屏幕显示警告 if(airData>100){ display.clearDisplay(); display.setTextSize(3); display.setCursor(1, 10); display.print("Warning: Air Quality Bad!"); } display.display(); newDataReceived = false; } } // 灰尘传感器相关函数 void CalculateDustValue() { static uint16_t unPM2_In; static uint16_t unPM2_Time; // local copy of update flags static uint8_t bUpdateFlags; static long PM2_Output[25]; // 判断是否有新信号 if (bUpdateFlagsShared) { noInterrupts(); // 关闭中断 bUpdateFlags = bUpdateFlagsShared; if (bUpdateFlags & PM2_FLAG) { unPM2_In = unPM2_InShared; unPM2_Time = (unPM2_Time + unPM2_In); // 记录PWM高电平时间 } // 清除标志位 bUpdateFlagsShared = 0; interrupts(); // 开启中断 } // maximum 24 PM2_Output[SampleCount] = unPM2_Time; unPM2_Time = 0; // 25个样本的高电平时间总和 PM2_Output[0] = PM2_Output[1] + PM2_Output[2] + PM2_Output[3] + PM2_Output[4] + PM2_Output[5] + PM2_Output[6] + PM2_Output[7] + PM2_Output[8] + PM2_Output[9] + PM2_Output[10] + PM2_Output[11] + PM2_Output[12] + PM2_Output[13] + PM2_Output[14] + PM2_Output[15] + PM2_Output[16] + PM2_Output[17] + PM2_Output[18] + PM2_Output[19] + PM2_Output[20] + PM2_Output[21] + PM2_Output[22] + PM2_Output[23] + PM2_Output[24]; /* 高浓度情况(≥3%占空比) PM2_Value = (PM2_Output总和)/(采样时间×样本数×10) × 600/7 + 250 低浓度情况(<3%占空比) PM2_Value = (PM2_Output总和)/(采样时间×样本数×10) × 250/3 */ // PWM信号的占空比 if (PM2_Output[0] / (samplerate * NoOfSamples * 10) >= 3) { PM2_Value = round((float)PM2_Output[0] / (samplerate * NoOfSamples * 10) * 600 / 7 + 250); } else { PM2_Value = round((float)PM2_Output[0] / (samplerate * NoOfSamples * 10) * 250 / 3); } bUpdateFlags = 0; if (SampleCount >= NoOfSamples) { SampleCount = 1; } else { SampleCount++; } } // 回调函数 引脚状态变化时,改变bUpdateFlagsShared状态 void calcPM2() { if (digitalRead(PM2_IN_PIN) == LOW) { ulPM2_Start = micros(); } else { unPM2_InShared = (uint16_t)(micros() - ulPM2_Start); bUpdateFlagsShared |= PM2_FLAG; // true } }
五、程序烧录
1、连接USB数据线至开发板;
2、选择端口号对应的开发板;
3、点击 上传 烧录程序到开发板上;
六、演示效果
OLED屏幕上实时显示PM2.5、温度、湿度、CO2浓度以及空气质量指标数据;