• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 0 głosów - średnia: 0
  • 1
  • 2
  • 3
  • 4
  • 5
Miernik czystości powietrza
#1
Witam. Zbudowałem taką małą konstrukcje.
Arduino Mega 2560, TFT 3,2" 320x480, DS3231, PMS5003, DHT22, BMP280, konwerter napięć 3.3V na 5V.
Wgrałem taki projekt i wyszło coś takiego jak na zdjęciach.
Mam prośbę może ktoś zerknie i poprawi lub usprawni, uprości szkic, doda coś. Wszystko działa mam tylko wątpliwość co do PM2.5 i PM10.
Jak się komuś przyda to bardzo proszę. Jest to praca sporej ilości ludzi posklejana przeze mnie. 

Kod:
#include <Wire.h>
#include "i2c.h"
#include "i2c_BMP280.h"
BMP280 bmp280;
#include <RTClib.h>
#include <TFT_HX8357.h> // Hardware-specific library
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <SimpleDHT.h>
int pinDHT22 = 19;
SimpleDHT22 dht22;
TFT_HX8357 tft = TFT_HX8357();       // Invoke custom library
RTC_DS3231 rtc;
unsigned long drawTime = 0;
//================================================================
 float pascal;
#define LENG 31   //0x42 + 31 bytes equal to 32 bytes
unsigned char buf[LENG];
int PM01Value=0;          //define PM1.0 value of the air detector module
int PM2_5Value=0;         //define PM2.5 value of the air detector module
int PM10Value=0;         //define PM10 value of the air detector module
//=============================================================
#define LOAD_GLCD
char daysOfTheWeek[7][12] = {"Sunday   ", "Monday   ", "Tuesday  ", "Wednesday", "Thursday ", "Friday   ", "Saturday "};
//char  daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
//char daysOfTheWeek[7][12] = {"Niedziela   ", "Poniedzialek", "Wtorek      ", "Sroda       ", "Czwartek    ", "Piatek      ", "Poniedzialek"};
// char miesiac[12][11] = {" Grudzien  ","  Styczen  ","   Luty    ","  Marzec   "," Kwiecien  ","    Maj    "," Czerwiec  ","  Lipiec   "," Sierpien  "," Wrzesien  ","Pazdziernik"," Listopad  "};
unsigned long aktualnyCzas = 0;
unsigned long zapamietanyCzas = 0;
unsigned long aktualnyCzas2 = 0;
unsigned long zapamietanyCzas2 = 0;
unsigned long roznicaCzasu = 0;
unsigned long roznicaCzasu2 = 0;
void setup() {
  Serial.begin(9600);
  bmp280.initialize();
    // onetime-measure:
  bmp280.setEnabled(3);
  bmp280.triggerMeasurement();
  pinMode(8, OUTPUT); //31(8) pin on/off dust sensor
  rtc.begin();
  //tft.begin();
  tft.init();
  tft.setRotation(1);
  tft.invertDisplay(1);
  tft.fillScreen(TFT_BLACK);
  tft.setFreeFont(FM9);
  tft.setTextColor(0xFFAA,TFT_BLACK);
  tft.drawLine(0,22,479,22,0xFFFF);
 
tft.drawLine(0,0,479,0,0xFFFF);
tft.drawLine(479,0,479,319,0xFFFF);
tft.drawLine(0,319,479,319,0xFFFF);
tft.drawLine(0,319,0,0,0xFFFF);
//===============kratki=======================
tft.drawLine(300,22,300,260,0xFFFF);
tft.drawLine(0,260,479,260,0xFFFF);
tft.drawLine(300,101,479,101,0xFFFF);
tft.drawLine(300,180,479,180,0xFFFF);
tft.drawLine(0,160,300,160,0xFFFF);
tft.drawLine(150,160,150,260,0xFFFF);
//===========skala======================
/*
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
*/
tft.fillRect(170,300,48,10,0x55FF); //0x55FB
tft.fillRect(218,300,48,10,0x07E0);
tft.fillRect(266,300,48,10,0xFFE0);
tft.fillRect(314,300,48,10,0xF555);
tft.fillRect(362,300,48,10,0xA355);
tft.fillRect(410,300,48,10,0xF800);
tft.drawRect(169,299,290,12,0xFFFF);
tft.drawString("0", 166, 275, 2);
tft.drawString("50", 205, 275, 2);
tft.drawString("100", 250, 275, 2);
tft.drawString("150", 298, 275, 2);
tft.drawString("200", 346, 275, 2);
tft.drawString("300", 394, 275, 2);
tft.drawString(">500", 440, 275, 2);
//=============napisy====================
tft.setFreeFont(FM12);
tft.drawString("PM 2.5", 20, 35,GFXFF );
tft.drawString("ug/m", 214, 35, GFXFF);
tft.drawString("3", 275, 30, GFXFF);

tft.drawString("PM 1.0", 20, 170, 2);
tft.drawString("ug/m", 100, 170, 2);
tft.drawString("3", 133, 165, 2);

tft.drawString("PM 10", 170, 170, 2);
tft.drawString("ug/m", 250, 170, 2);
tft.drawString("3", 283, 165, 2);

tft.drawString("Temp.", 320, 30, 2);
tft.drawString("o", 446, 23, 2);
tft.drawString("C", 457, 30, 2);

tft.drawString("RH", 320, 110, 2);
tft.drawString("%", 455, 110, 2);

tft.drawString("Cisnienie", 320, 187, 2);
tft.drawString("hPa", 445, 187, 2);
//============================================
  tft.drawString("DATA :", 30, 2, 2);
  tft.drawString("CZAS :", 304, 2, 2);

// jak chcesz zmienić date i czas
// rtc.adjust(DateTime(2018, 3, 25, 11, 32, 0));

  digitalWrite(8, LOW); //pin 8
  Serial3.begin(9600);
}

void wilgotnosc(){
    float temperature=0;
    float humidity=0;
    float tep1;
    float hum1;
//==================wilgoć&temp=================
  int err = SimpleDHTErrSuccess;
  if ((err = dht22.read2(pinDHT22, &temperature, &humidity, NULL)) != SimpleDHTErrSuccess) {
   // tft.print("Read DHT22 failed, err="); tft.println(err);delay(2000);
    return;
  }
  tft.setFreeFont(FM18);
  if (tep1!=(temperature,1)){
  tft.fillRect(350,50,95,35,0x0000);
  tft.drawFloat(temperature,1, 350, 55, GFXFF);}
  else{
  tft.drawFloat(temperature,1, 350, 55, GFXFF);}
  if (hum1!=(humidity,1)){
  tft.fillRect(350,120,95,35,0x0000);
  tft.drawFloat(humidity,1, 350, 130, GFXFF);}
  else{ tft.drawFloat(humidity,1, 350, 130, GFXFF);}
  tep1=(temperature,1);
  hum1=(humidity,1);
   // aaa=0;
  }
//======================PM2.5==================================
void dust () {
  for (int i=0; i <= 10; i++){
  if(Serial3.find(0x42)){    //start to read when detect 0x42
    Serial3.readBytes(buf,LENG);

    if(buf[0] == 0x4d){
      if(checkValue(buf,LENG)){
        PM01Value=transmitPM01(buf); //count PM1.0 value of the air detector module
        PM2_5Value=transmitPM2_5(buf);//count PM2.5 value of the air detector module
        PM10Value=transmitPM10(buf); //count PM10 value of the air detector module
      }           
    }
  }
  int aqi=0;
   tft.setTextColor(0x7FFF,TFT_BLACK);
 // delay(50);  aqi=(PM2_5Value/0.25);

  tft.setFreeFont(FM24);
  tft.fillRect(100,75,130,65,0x0000);
  tft.drawNumber(PM2_5Value, 105, 85, GFXFF);
  tft.setFreeFont(FM18);
  tft.fillRect(40,205,95,35,0x0000);
  tft.drawNumber(PM01Value, 40, 209, GFXFF);
  tft.fillRect(190,205,95,35,0x0000);
  tft.drawNumber(PM10Value, 195, 209, GFXFF);
  tft.setFreeFont(FM12);
  tft.fillRect(15,277,150,30,0x0000);
  tft.drawString("%", 30, 280, GFXFF);
  tft.drawNumber(aqi, 55, 280, GFXFF);
    delay(1000);
  }
  delay(100);
  digitalWrite(8, LOW); //31
  tft.setTextColor(0x00FF,TFT_BLACK);
  tft.drawString("OFF", 235, 120, 4);
  tft.setTextColor(0x7FF7,TFT_BLACK);
  zapamietanyCzas2 = aktualnyCzas2;
  }
//======================Koniec PM2.5============================
void loop() {
  aktualnyCzas = millis();
  roznicaCzasu = aktualnyCzas - zapamietanyCzas;
  aktualnyCzas2 = millis();
  roznicaCzasu2 = aktualnyCzas2 - zapamietanyCzas2;
  DateTime now = rtc.now();
  int czass;
  int czasm;
  int czasg;
  int datar;
  int datam;
  int datad;
  int datat;
  czasm=(now.minute());
  czasg=(now.hour());
  czass=(now.second());
  datar=(now.year());
  datam=(now.month());
  datad=(now.day());
  datat=(now.dayOfTheWeek());
//================CZAS=====================       
  tft.setTextColor(0xffff,TFT_BLACK);
  if (czasg<=9) {
  tft.drawString("0",365,2,2);
  tft.drawNumber(czasg, 375, 2,2);
  }else{
  tft.drawNumber(czasg, 365, 2,2);}
  tft.drawString(":",388,2,2);
  if (czasm<=9) {
  tft.drawString("0",400,2,2);
  tft.drawNumber(czasm, 409, 2,2);
  }else{
  tft.drawNumber(czasm, 400, 2,2);}
  tft.drawString(":",423, 2, 2);
  if (czass <= 9) {
  tft.drawString("0",435, 2, 2);
  tft.drawNumber(czass, 444, 2, 2);  
  }else{
  tft.drawNumber(czass, 435, 2, 2);}
 //==================DATA==============================
  tft.setFreeFont(FM9);
  tft.setTextColor(0xFFFF,TFT_BLACK);
  if (datad<=9) {
  tft.drawNumber("0",90,2,2);
  tft.drawNumber(datad,99,2,2);
  }else{
  tft.drawNumber(datad, 90, 2,2);}
  tft.drawString(".",106,2,GFXFF);
  if (datam<=9) {
  tft.drawString("0",118,2,2);
  tft.drawNumber(datam,127,2,2);   
  }else{
  tft.drawNumber(datam, 118, 2, 2);}
  tft.drawString(".",137,2,GFXFF);
  tft.drawNumber(datar, 150, 2,2);
  tft.drawString("r.",188,2,2);
  tft.setTextColor(0x7FF7,TFT_BLACK);
  tft.drawString( daysOfTheWeek[(datat)], 207, 2,2);
  if (czasg<=6){
  tft.setTextColor(0xF00F,TFT_BLACK);
  tft.drawString("OFF", 235, 120, 4);
  tft.setTextColor(0x7FF7,TFT_BLACK);
  }
  else{
  if (roznicaCzasu2 >= 285000UL){
  digitalWrite(8, HIGH); //31
  tft.setTextColor(0xF800,TFT_BLACK);
  tft.drawString("ON*", 235, 120, 4);
  tft.setTextColor(0x7FF7,TFT_BLACK);
  }
  if (roznicaCzasu2 >= 300000UL) {
    //Zapamietaj aktualny czas
  dust();
}}
//============Cisnienie=====================
    bmp280.awaitMeasurement();
    float temperature;
    bmp280.getTemperature(temperature);
    float pascal;
    bmp280.getPressure(pascal);
    static float meters, metersold;
    bmp280.getAltitude(meters);
    metersold = (metersold * 10 + meters)/11;
    bmp280.triggerMeasurement();
    if (roznicaCzasu >= 120000UL){
    float hpascal;
    hpascal=(pascal/100);
    if (hpascal<1000){
    tft.setFreeFont(FM18);
    tft.fillRect(325,210,125,35,0x0000);
    tft.drawFloat(hpascal,2, 325, 215, GFXFF);}
    else{
    tft.setFreeFont(FM18);
    tft.fillRect(325,210,125,35,0x0000);
    tft.drawFloat(hpascal,1, 325, 215, GFXFF);}
//==========Temp Cisnienie====================
    wilgotnosc();
    zapamietanyCzas = aktualnyCzas;
    }
    delay (200);
}

//=================KONIEC LOOP=========================

char checkValue(unsigned char *thebuf, char leng)
{  
  char receiveflag=0;
  int receiveSum=0;

  for(int i=0; i<(leng-2); i++){
  receiveSum=receiveSum+thebuf[i];
  }
  receiveSum=receiveSum + 0x42;

  if(receiveSum == ((thebuf[leng-2]<<8)+thebuf[leng-1]))  //check the serial data
  {
    receiveSum = 0;
    receiveflag = 1;
  }
  return receiveflag;
}

int transmitPM01(unsigned char *thebuf)
{
  int PM01Val;
  PM01Val=((thebuf[3]<<8) + thebuf[4]); //count PM1.0 value of the air detector module
  return PM01Val;
}

//transmit PM Value to PC
int transmitPM2_5(unsigned char *thebuf)
{
  int PM2_5Val;
  PM2_5Val=((thebuf[5]<<8) + thebuf[6]);//count PM2.5 value of the air detector module
  return PM2_5Val;
  }

//transmit PM Value to PC
int transmitPM10(unsigned char *thebuf)
{
  int PM10Val;
  PM10Val=((thebuf[7]<<8) + thebuf[8]); //count PM10 value of the air detector module  
  return PM10Val;
} //cod dust sensor

//===========================================================
#ifndef LOAD_GLCD
//ERROR_Please_enable_LOAD_GLCD_in_User_Setup
#endif

#ifndef LOAD_FONT2
//ERROR_Please_enable_LOAD_FONT2_in_User_Setup!
#endif

#ifndef LOAD_FONT4
//ERROR_Please_enable_LOAD_FONT4_in_User_Setup!
#endif

#ifndef LOAD_FONT6
//ERROR_Please_enable_LOAD_FONT6_in_User_Setup!
#endif

#ifndef LOAD_FONT7
//ERROR_Please_enable_LOAD_FONT7_in_User_Setup!
#endif

#ifndef LOAD_FONT8
//ERROR_Please_enable_LOAD_FONT8_in_User_Setup!
#endif

#ifndef LOAD_GFXFF
ERROR_Please_enable_LOAD_GFXFF_in_User_Setup!
#endif


Załączone pliki Miniatury
       
 
Odpowiedź
#2
Witam
Tak oglądam Twoje fotki i widzę że pm2.5 wynosi ponad 300 mikrogram na metr sześcienny.
To bardzo dużo bo w Polsce norma to 24 mikro gramy na metr sześcienny. Jeśli jest to właśnie taka wartość to wtedy jest to 100% kiedy będzie 50 mikrogram to mamy 200% normy przekroczonej no a 314 mikro gram to bardzo dużo owszem takie stężenia są zimą a tu widzę że na wyświetlaczu jest kwiecień .
Czy aby na pewno masz dobry pomiar z tego czujnika wiem że on mierzy w jednostkach na 0,1Litra objętości.
(czujnik pms5003) i potem to chyba trzeba przeliczać no ale jak.


Yobi
 
Odpowiedź
#3
Wszytko zależy od regionu.. u mnie w stronach pm2.5 to średnio 300latem w porywach ponad 700mikrogram jedynie w nocy spada poniżej 300... zimą ciut mniej
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości