一、硬件介绍
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等;
二、代码编写
//#define USB // 启用串口
#define OELCD_OP //启用OLED屏幕
#define DustSensor true // 开启粉尘PWM检测传感器
#include <SPI.h>
#include <Wire.h>
#include <PinChangeInterrupt.h>
#include "SM-PWM-01C.h"
// 屏幕上方显示内容
char ScreenHeader[] = " Amphenol Sensors";
char ScreenFooter[] = " Air Quality Display";
//OLED部分库
#ifdef OELCD_OP
#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
#define OLED_MOSI 11 //SDA
#define OLED_CLK 12 //SCL
#define OLED_DC 9 // D/C
#define OLED_CS 11// not used
#define OLED_RESET 10 //RESET
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT,
OLED_MOSI, OLED_CLK, OLED_DC, OLED_RESET, OLED_CS);
#endif
void setup()
{
#ifdef USB
Serial.begin(115200);
Serial.println("串口输出模式");
#endif
#ifdef OELCD_OP
// OELD初始化
display.begin(SSD1306_SWITCHCAPVCC);
display.clearDisplay();
display.display();
#endif
// 灰尘传感器初始化
if (DustSensor) {
#ifdef USB //output to PC through USB
Serial.println("Dust Sensor初始化...");
#endif
pinMode(PM2_IN_PIN, INPUT); // Pin 7
pinMode(PM2_OUT_PIN, OUTPUT); //Pin 13
//设置中断引脚 / 回调函数(calcPM2) / 状态改变时
attachPCINT(digitalPinToPCINT(PM2_IN_PIN), calcPM2, CHANGE);
}
}
void loop() {
//每隔samplerate时间刷新显示
if (millis() >= (samplerate + sampletime))
{
CalculateDustValue();
sampletime = millis();
#ifdef OELCD_OP
String SensorReading;
String AuxInfo;
String Units;
// 显示PM2.5数值
SensorReading = "PM2.5: ";
SensorReading += String(PM2_Value);
Units = "ug/m3"; // 添加单位
// 显示空气质量等级
AuxInfo = "Air Quality: ";
AuxInfo += AQIColour;
int Offset = 10;
// 显示内容
displayReading(SensorReading, AuxInfo, Units, Offset);
#endif
#ifdef USB
Serial.print("PM2.5值:");
Serial.print(PM2_Value);
Serial.print(" μg/m³ ");
Serial.print ("空气质量:");
Serial.println(AQIColour);
#endif
}
}
#ifdef OELCD_OP
/*
aa: 传感器读数(主要显示内容)
bb: 辅助信息(底部显示)
cc: 单位(如℃、%等)
dd: 水平偏移量,用于调整读数位置
*/
void displayReading(String aa, String bb, String cc, int dd) {
display.clearDisplay();
// 屏幕标题
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0, 0); //header
display.print(ScreenHeader);
// 屏幕副标题
display.setCursor(0, 12);
display.setTextSize(1);
display.print(ScreenFooter);
// 读数区域
display.setTextSize(1);
display.setCursor(1 + dd, 30);
display.print(aa); //Sensor Reading
// 单位显示
display.setTextSize(1);
display.setCursor(70+dd, 30);
display.print(cc); //units
// 辅助信息
display.setTextSize(1);
display.setCursor(15, 57);
display.print(bb); //aux info
display.display();
}
#endif
//灰尘传感器相关函数
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;
// Serial.print (PM2_Output[SampleCount]); Serial.print("\t");
if (SampleCount >= NoOfSamples)
{
SampleCount = 1;
// Serial.print (PM2_Output[0]); Serial.print("\t");Serial.println("\t");
}
else
{
SampleCount++;
}
// 空气质量指数等级
if (PM2_Value <= 12)
{
AQIColour = "A";
}
else if (PM2_Value <= 35)
{
AQIColour = "B";
}
else if (PM2_Value <= 55)
{
AQIColour = "C";
}
else if (PM2_Value <= 150)
{
AQIColour = "D";
}
else if (PM2_Value <= 250)
{
AQIColour = "E";
}
else {
AQIColour = "F";
}
}
// 回调函数 引脚状态变化时,改变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的数值,以及对应的空气质量等级;

我要赚赏金
