这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » AAS-AQS-UNO开发板使用指南之【软件篇】

共1条 1/1 1 跳转至

AAS-AQS-UNO开发板使用指南之【软件篇】

菜鸟
2025-10-20 16:10:40     打赏

一、硬件介绍

1、产品特点

空气质量评估板用于评估 Telaire 空气质量传感器,可支持 SM-PWM-01C 粉尘传感器,串行输出可以配置为通过 USB 连接将传感器数据发送到 PC,进行记录和分析等。

image-20251007221412779.png


特性

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屏幕模块    


实物图

image-20251008152439656.png




2、粉尘传感器

SM-PWM-01C是一款利用光学方法检测空气中粉尘浓度的传感器。在传感器中一个红外LED 和一个光接收器光轴相交,当带粉尘的气流通过交叉区域,产生折射光。光接收器检测到粉尘反射的红外LED光线,根据输出信号的强弱判断粉尘的浓度。粉尘传感器能检测像香烟颗粒大小的颗粒物与室内灰尘等大颗粒,通过输出PWM脉冲信号宽度来区分。

image-20251008230943861.png



管脚     管脚定义

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等;

    

二、环境搭建

1、下载Arduino IDE

image-20251009205311004.png



2、下载相关例程

示例程序

image-20251009211136921.png


解压后工程文件目录

image-20251010220728667.png



3、安装所需相关库

pinchangeint

Adafruit_SSD1306


三、程序代码分析

主要功能

1、传感器监测

T6700 CO2传感器:检测二氧化碳浓度;

T9602温湿度传感器:检测温度和湿度;

SM-PWM-01C粉尘传感器:检测PM2.5颗粒物浓度


2、输出方式

串口输出(USB模式):通过串口向电脑发送数据;

OLED显示屏输出:在OLED(SSD1306)屏上显示相关数据;


代码结构分析

传感器部分:

getT6700data():读取CO2浓度;

getT9602data():读取温湿度;

CalculateDustValue():计算粉尘浓度;

calcPM2():粉尘传感器中断服务程序;


显示部分:

displaySetupScreen():初始化显示;

displayReading():显示传感器读数;


轮询显示:温度 → 湿度 → CO₂ → AQI 颜色(带 PM2.5 值)

由于只有粉尘传感器,所以只会显示 PM2.5值、AQI 颜色;


#define USB  //enable or disable monitoring on serial output, alternate with display, 19200 baud
//#define OELCD_OP    //enable or disable LCD Output, alternate with serial output

#define DustSensor true  // true or false dependent upon if dust sensor present, true by default as we cannot handshake

#include "Wire.h"
#include <SPI.h>
#include <PinChangeInterrupt.h>

//  Width Guide      "---------------------"
#define SplashScreen "Telaire eval, v1.4"
char ScreenHeader[] = "  Amphenol Sensors";
char ScreenFooter[] = " Telaire Technology";

#ifdef OELCD_OP
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "OELCD.h"
#endif

#include "T9602.h"
#include "T6700.h"
#include "SM-PWM-01C.h"

byte error;
byte Connected = 0; // bit values define sensor presence B1 -  T6700, B10 T9602 Temp, B100 T9602 Hum, B1000 Dust
byte data[6];
byte kk = 1;
unsigned int Offset = 0;

//_______________________________________________setup_________________________________

void setup()
{
#ifdef USB //output to PC through USB
  Serial.begin(19200);  // start serial for output
  Serial.println(SplashScreen);
#endif

  Wire.begin();

#ifdef OELCD_OP
  // by default, we'll generate the high voltage from the 3.3v line internally
  display.begin(SSD1306_SWITCHCAPVCC);
  displaySetupScreen();
#endif

  Wire.beginTransmission(ADDR_6700); // check if T6700 series is present
  error = Wire.endTransmission();
  if (error == 0)
  {
#ifdef USB //output to PC through USB
    Serial.println("T6700 Detected");
#endif
    Connected = 1;
  }

  Wire.beginTransmission(ADDR_9602); // check if T9602 series is present
  error = Wire.endTransmission();
  if (error == 0)
  {
#ifdef USB //output to PC through USB
    Serial.println("T9602 Detected");
#endif
    Connected = Connected + 6;
  }

  // assume Dust Sensor is present as we cannot handshake it
  if (DustSensor) {
#ifdef USB //output to PC through USB
    Serial.println("Dust Sensor Detected");
#endif
    Connected = Connected + 8;

    pinMode(PM2_IN_PIN, INPUT);  //setup SWM PWM 01C Pins to work with pininterrupt algorithm
    pinMode(PM2_OUT_PIN, OUTPUT);

    // using the PinChangeInt library, attach the interrupts
    // used to read the channels
    attachPCINT(digitalPinToPCINT(PM2_IN_PIN), calcPM2, CHANGE);
  }

#ifdef USB //output to PC through USB
  if ((Connected & B00000001) == 1 ) {
    Serial.print("CO2ppm");
    Serial.print (",");
  }
  if ((Connected & B00000110) == 6 ) {
    Serial.print("Temperature"); Serial.print (",");
    Serial.print("Humidity"); Serial.print (",");
  }
  if ((Connected & B00001000) == 8 ) {
    Serial.print("PM2_Value"); Serial.print (",");
    Serial.print ("AQIColour");
  }
  Serial.println (" ");

#endif

#ifdef OELCD_OP
  if ((Connected & B00000001) == 1 ) {
    displayReading("", "CO2 Sensor", "", Offset);
    delay(1000);
  }
  if ((Connected & B00000110) == 6 ) {
    displayReading("", "T9602 Sensor", "", Offset);
    delay(1000);
  }
  if ((Connected & B00001000) == 8 ) {
    displayReading("", "Dust Sensor", "", Offset);
    delay(1000);
  }
#endif
}

//___________________________________________________loop______________________

void loop() {
  if (millis() >= (samplerate + sampletime))
  {
    if ((Connected & B00000001) == 1 ) {
      getT6700data();
    }
    if ((Connected & B00000110) == 6 ) {
      getT9602data();
    }
    if ((Connected & B00001000) == 8 ) {
      CalculateDustValue();
    }
    sampletime = millis();  //resets timer before printing output

#ifdef OELCD_OP
    String SensorReading;
    String AuxInfo;
    String Units;

    if (kk >= 5) {
      kk = 1;
    }


    if (kk == 1) {
      if ((Connected & B00000010) == 2 )    //is T9602 temp present?
      { SensorReading = String(temperature);
        SensorReading.remove(4);
        Units =  char(247); Units += "C";
        AuxInfo = "Temperature";
        Offset = 10;
      }
      else {
        kk++;
      }
    }

    if (kk == 2) {
      if ((Connected & B00000100) == 4 ) {    //is T9602 hum present?
        SensorReading = String(humidity);
        SensorReading.remove(4);
        Units = "%rH";
        AuxInfo = char(32); AuxInfo += char(32);
        AuxInfo += "Humidity";
        Offset = 10;
      }
      else {
        kk++;
      }
    }

    if (kk == 3) {
      if ((Connected & B00000001) == 1 ) //is T6700 present?
      { SensorReading = CO2ppmValue;
        SensorReading.remove(4);
        Units = "ppm";
        AuxInfo = "Carbon"; AuxInfo += char(32); AuxInfo += "Dioxide";
        Offset = 15;
      }
      else {
        kk++;
      }
    }


    if (kk == 4) {
      if ((Connected & B00001000) == 8) {    //is dust sensor present?
        SensorReading = String(AQIColour);
        Units = "";
        
        AuxInfo = "AQI"; AuxInfo += char(32); AuxInfo += "Colour  [";
        AuxInfo += String(PM2_Value); AuxInfo += "]";
        Offset = 0;
      }
      else {
        kk++;
      }
    }

    displayReading(SensorReading, AuxInfo, Units, Offset);

    kk++;


#endif

#ifdef USB //output to PC through USB
    if ((Connected & B00000001) == 1 ) {    //is T6700 present?
      Serial.print(CO2ppmValue);
      Serial.print (",");
    }
    if ((Connected & B00000110) == 6 ) {    //is T9602 present?
      Serial.print(temperature); Serial.print (",");
      Serial.print(humidity); Serial.print (",");
    }
    if ((Connected & B00001000) == 8 ) {    //is dust sensor present?
      Serial.print(PM2_Value); Serial.print (",");
      Serial.print (AQIColour);
    }
    Serial.println ("");
#endif
  }
}

//________________________________Screen Sub Routines_______________________________


#ifdef OELCD_OP
void displaySetupScreen() {
  // Clear the buffer.
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 30);
  display.print(SplashScreen);
  display.display();
  delay(2000);
  display.clearDisplay();
}

void displayReading(String aa, String bb, String cc, int dd) {
  display.clearDisplay();

  // display header detail
  display.setTextColor(WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0); //header
  display.print(ScreenHeader);

  // display screen header 2nd line
  display.setCursor(0, 12);
  display.setTextSize(1);
  display.print(ScreenFooter);

  // display reading
  display.setTextSize(3);
  display.setCursor(10 + dd, 28);
  display.print(aa);  //Sensor Reading

  // display units
  display.setTextSize(1);
  display.setCursor(100, 35);
  display.print(cc);  //units

  // display aux info
  display.setTextSize(1);
  display.setCursor(25, 57);
  display.print(bb);  //aux info



  display.display();
}
#endif

//________________________________________Sensor Sub Routines____________________________

void getT9602data() //gets temp and hum values from T9602 over I2C
{
  Wire.beginTransmission(ADDR_9602);
  Wire.write(0);
  Wire.endTransmission();

  byte aa, bb, cc, dd;

  Wire.requestFrom(ADDR_9602, 4);
  data[0] = Wire.read();
  data[1] = Wire.read();
  data[2] = Wire.read();
  data[3] = Wire.read();


  // humidity = (rH_High [5:0] x 256 + rH_Low [7:0]) / 16384 x 100
  humidity = (float)(((data[0] & 0x3F ) << 8) + data[1]) / 16384.0 * 100.0;
  humidity = round(humidity);
  // temperature = (Temp_High [7:0] x 64 + Temp_Low [7:2]/4 ) / 16384 x 165 - 40
  temperature = (float)((unsigned)(data[2]  * 64) + (unsigned)(data[3] >> 2 )) / 16384.0 * 165.0 - 40.0;
  temperature = round(temperature * 10);
  temperature = temperature / 10;

}


//gets CO2 ppm value from T6700 series over I2C bus
void getT6700data()
{
  // start I2C
  Wire.beginTransmission(ADDR_6700);
  Wire.write(0x04); Wire.write(0x13); Wire.write(0x8B); Wire.write(0x00); Wire.write(0x01);
  // end transmission
  Wire.endTransmission();

  // read report of current gas measurement in ppm
  delay(1);
  Wire.requestFrom(ADDR_6700, 6);    // request 4 bytes from slave device
  data[0] = Wire.read();
  data[1] = Wire.read();
  data[2] = Wire.read();
  data[3] = Wire.read();

  CO2ppmValue = ((data[2] & 0x3F ) << 8) | data[3];
}


//calculates the dust value from the stored
void CalculateDustValue()
// sample times accumulated by the interupts.
{ 
  // create local variables to hold a local copies of the channel inputs
  // these are declared static so that thier values will be retained
  // between calls to loop.
  static uint16_t unPM2_In;
  static uint16_t unPM2_Time;
  // local copy of update flags
  static uint8_t bUpdateFlags;
  static long    PM2_Output[25];

  // check shared update flags to see if any channels have a new signal
  if (bUpdateFlagsShared)
  {
    noInterrupts(); // turn interrupts off quickly while we take local copies of the shared variables
    bUpdateFlags = bUpdateFlagsShared;


    if (bUpdateFlags & PM2_FLAG)
    {
      unPM2_In = unPM2_InShared;
      unPM2_Time = (unPM2_Time + unPM2_In);
    }
    bUpdateFlagsShared = 0;

    interrupts(); 
  }


  PM2_Output[SampleCount] = unPM2_Time ;
  unPM2_Time = 0;

  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];

  /* converts LP outputs to values, calculate % LPO first, then converet to µg/m3 assuming conversion is linear
              output (µS)                           concentration change (250 or 600)
     -----------------------------------    x 100 x ---------------------------------  + offset (0 or 250)
     sample rate (mS) x 1000 x NoOfSamples               percentage change (3 0r 7)

  */
  if (PM2_Output[0] / (samplerate * NoOfSamples * 10 ) >= 3);
  {
    PM2_Value = round((float)PM2_Output[0] / (samplerate * NoOfSamples * 10 ) * 600 / 7 + 250);
  }
  {
    PM2_Value = round((float)PM2_Output[0] / (samplerate * NoOfSamples * 10 ) * 250 / 3);
  }
  bUpdateFlags = 0;  //reset flags and variables

  // 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++;
  }

  // Colour Values based on US EPA Air Quality Index for PM 2.5 and PM 10
  if (PM2_Value <= 12)
  {
    AQIColour = "Green ";
  }
  else if (PM2_Value <= 35)
  {
    AQIColour = "Yellow";
  }
  else if (PM2_Value <= 55)
  {
    AQIColour = "Orange";
  }
  else if (PM2_Value <= 150)
  {
    AQIColour = char(32);
    AQIColour += "Red";
  }
  else if (PM2_Value <= 250)
  {
    AQIColour = "Purple";
  }
  else {
    AQIColour = "Maroon";
  }
}

// simple interrupt service routine
void calcPM2()
{
  if (digitalRead(PM2_IN_PIN) == LOW)
  {
    ulPM2_Start = micros();
  }
  else
  {
    unPM2_InShared = (uint16_t)(micros() - ulPM2_Start);
    bUpdateFlagsShared |= PM2_FLAG;
  }
}



四、程序烧录

1、连接USB数据线至开发板;

2、选择端口号对应的开发板;

3、点击 上传 烧录程序到开发板上;

image-20251011114911784.png



五、演示效果

启用 #define USB 将在串口输出相关信息;

输出板载 SM-PWM-01C 传感器检测到的数值;


image-20251012230912706.png








共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]