Miernik czystości powietrza - OMK - 01-04-2018
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
RE: Miernik czystości powietrza - Yobi - 09-02-2019
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
RE: Miernik czystości powietrza - Jarewa0606 - 09-02-2019
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
|