本网页已闲置超过3分钟,按键盘任意键或点击空白处,即可回到网页

使用MH-Z19C-PH和AHT10制作空气监测仪

发布时间:2021-04-27
分享到:

使用MH-Z19C-PH和AHT10制作空气监测仪

发布时间:2021-04-27
分享到:

该项目用于监视房间空气质量,通过MH-Z19C-PH传感器和AHT10传感器来测量湿度和温度,并通过屏幕实时监控二氧化碳、温湿度的水平,在该项目中,还设置了按键功能,按一下可看到24小时以前二氧化碳水平记录的图表,再按一下,即可关掉显示屏。

硬件部件:

  • MH-Z19c-PH
  • 通孔电阻,6.8 kohm
  • 触觉开关,顶部致动
  • 面包板(通用)
  • Arduino UNO
  • 跳线(通用)
  • AHT10
  • 128*32 SSD1306

 

手绘接线图:

代码:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


#include <Arduino.h>
#include "MHZ19.h"                                        
#include <SoftwareSerial.h>                                // 如果使用HardwareSerial,则将其删除

#define RX_PIN 10                                          // MHZ19 Tx引脚连接到的Rx引脚
#define TX_PIN 11                                          //  MHZ19 Rx引脚连接到的Tx引脚
#define BAUDRATE 9600                                      // 设备为MH-Z19串行波特率(不应更改) 

#define buttonPin 2     // 按钮的针脚编号


MHZ19 myMHZ19;                                             // 库的构造函数
SoftwareSerial mySerial(RX_PIN, TX_PIN);                   // (Uno示例)将设备创建为MH-Z19串行

unsigned long getDataTimer = 0;
unsigned long getDataHour = 0;

#define SCREEN_WIDTH 128 // OLED显示宽度(以像素为单位)
#define SCREEN_HEIGHT 32 //OLED显示高度,以像素为单位

//声明连接到I2C的SSD1306显示器(SDA,SCL引脚)
// I2C的引脚由Wire-library定义。 
//在arduino UNO上:A4(SDA),A5(SCL)
//在arduino MEGA 2560上:20(SDA),21(SCL)
//在arduino LEONARDO上:2(SDA),3(SCL),...
#define OLED_RESET     4 //重置引脚号(如果共享Arduino重置引脚,则为-1)
#define SCREEN_ADDRESS 0x3C // <参见数据表中的地址; 0x3D表示128x64,0x3C表示128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#include <Adafruit_AHT10.h>
Adafruit_AHT10 aht;

void setup() {
  Serial.begin(9600);

   // SSD1306_SWITCHCAPVCC =内部产生3.3V的显示电压
  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    //Serial.println(F("SSD1306分配失败“));
    for(;;); // 死循环
  }

  //在屏幕上显示初始显示缓冲区的内容-
  //该库使用Adafruit初始屏幕对此进行初始化。
  display.display();
  delay(2000); // Pause for 2 seconds

  // 清除缓冲区
  display.clearDisplay();


  if (! aht.begin()) {
    //Serial.println(“找不到AHT10?检查接线”);
    while (1) delay(10);
  }
  //Serial.println(“找到AHT10”);

   
  mySerial.begin(BAUDRATE);                              //(Uno示例)设备到MH-Z19串行启动  
  myMHZ19.begin(mySerial);                                // * Serial(Stream)参考必须传递给库begin() 

  myMHZ19.autoCalibration();                               //开启自动校正功能(关闭autoCalibration(false))

  pinMode(buttonPin, INPUT);
}

char CO2String[10];
char outstr[6];
    
void loop() {
  // 将您的主代码放在此处,以重复运行
  static int buttonState = 0;         // 用于读取按钮状态的变量
  static int level = 0; //0级正常工作,1级图表,2级关闭
  buttonState = digitalRead(buttonPin);


  if (buttonState == HIGH) {
    level++;
  } 
  if(level==3) {
    level=0;
  }


    static int CO2=0; 
    if (millis() - getDataTimer >= 2000)
    {
        CO2 = myMHZ19.getCO2();  //请求二氧化碳(以ppm计)
        //Serial.print("CO2 (ppm): ");Serial.println(CO2);                                
        getDataTimer = millis();
    }

    if (level==0){ //操作规范
      display.clearDisplay();
        
       sensors_event_t humidity, temp;
       aht.getEvent(&humidity, &temp);// 用新数据填充温度和湿度对象

       ScreenPrint("Temperature:",4,3,1,false);
       dtostrf(temp.temperature,5, 2, outstr);
       ScreenPrint(outstr,78,3,1,false);
       ScreenPrint("*C",112,3,1,false); 
        
       ScreenPrint("Humidity:",4,11,1,false);
       dtostrf(humidity.relative_humidity,5, 2, outstr);
       ScreenPrint(outstr,59,11,1,false);
       ScreenPrint("%rH",95,11,1,false);

       ScreenPrint("CO2:",4,21,1,false);
       sprintf (CO2String, "%i", CO2);
       ScreenPrint(CO2String,30,21,1,false);
       ScreenPrint("ppm",60,21,1,false); 

      display.drawRect(1,1,126,31,WHITE);
      display.display();
    }
    if (level==1){ //图像显示
      display.clearDisplay();
      printGraph();
    }
    if (level==2){ //关闭屏幕
      blackScreen();                 
    }

    if (millis() - getDataHour >= 1800000){ //如果节省半小时(36000)/1800000半小时
       SaveDataGraph(CO2);//salva dati CO2
       getDataHour = millis();
    }


  delay(500);


}

 int graph[23]={400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400,400}; 

uint8_t moment=0; 

void SaveDataGraph(int data){
  graph[moment]=data;
  moment++;  
  if (moment==23){
  moment=0;
  }
  }

void printGraph(void){
  static int tempo=0;
  int resizeData;
  int PosizioneX=0;
  while(tempo!=23){
    resizeData = 30-(graph[tempo]*0.012); //范围0 到 2500
    display.drawLine(PosizioneX+4,resizeData,PosizioneX+4,32,WHITE); //从x1,y1到x2,y2绘制一个矩形 x2,y2
    PosizioneX=PosizioneX+5;
    tempo++;
  }
  display.drawLine(0,24,1,24,WHITE);  // 线性500ppm
  display.drawLine(0,18,128,18,WHITE);  //线性1000ppm
  display.drawLine(0,12,1,12,WHITE);  //线性1500ppm
  display.drawLine(0,6,128,6,WHITE);  // 线性 2000ppm
  
  display.drawLine((moment+1)*5,0,(moment+1)*5,1,WHITE);  //  当前线性mom参考

  display.display(); // 更新画面
  PosizioneX=0;
  tempo=0;
  }


void blackScreen(void){
    display.clearDisplay();
    display.display();
  }


void ScreenPrint(String text, int x, int y, int size, bool d){

  display.setTextSize(size);
  display.setTextColor(WHITE);
  display.setCursor(x,y);
  display.println(text); //发送文本显示器
  if(d){
    display.display(); 
    }
  }

视频演示:

附:

二氧化碳数值及其影响的列表:

  • 250-400ppm->室外环境空气中的正常背景浓度。
  • 400-1,000ppm->空气交换良好的室内典型浓度。
  • 1,000-2,000ppm->嗜睡和空气不佳的投诉。
  • 2,000-5,000 ppm->头痛,嗜睡和停滞,陈旧,闷气。还可能出现注意力不集中,注意力不集中,心律加快和轻微的恶心。
加入微信技术交流群

技术交流,职业进阶

关注与非网服务号

获取电子工程师福利

加入电路城 QQ 交流群

与技术大牛交朋友

讨论