From 53c65bd46c4c20ee143b41fd6d6b2c9a7ab45235 Mon Sep 17 00:00:00 2001 From: Fisch Date: Fri, 23 Oct 2020 09:14:43 +0200 Subject: [PATCH] add sensoresp2 with mhz19 and sds018 --- platformio.ini | 32 +++++++++- src/main.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 195 insertions(+), 5 deletions(-) diff --git a/platformio.ini b/platformio.ini index e9d6a8b..d2540db 100644 --- a/platformio.ini +++ b/platformio.ini @@ -13,9 +13,9 @@ [platformio] #For Config upload comment in data_dir line and flash with platformio run -t uploadfs --environment sensorespx #data_dir=data_sensoresp1 - +data_dir=data_sensoresp2 #data_dir=data_sensoresp3 -data_dir=data_sensoresp4 +#data_dir=data_sensoresp4 #Arbeitszimmer [env:sensoresp1] @@ -55,6 +55,34 @@ lib_deps = Homie@3.0.0 +#Wohnzimmer Air Quality +[env:sensoresp2] +platform = espressif8266 +board = d1_mini +framework = arduino + +monitor_port = /dev/ttyUSB0 +monitor_speed = 115200 + +build_flags = + -D SENSOR_MHZ19 + -D MHZ19_SERIAL_RX=D5 + -D MHZ19_SERIAL_TX=D6 + -D dataMHZ19_minchange=10 + -D dataMHZ19_readdelay=10*1000 + + -D SENSOR_SDS018 + -D SDS018_SERIAL_RX=D7 + -D SDS018_SERIAL_TX=D8 + -D dataSDS018_pm25_minchange=4 + -D dataSDS018_pm10_minchange=4 + +lib_deps = + MHZ19@0.0.1 + EspSoftwareSerial@6.8.1 + Homie@3.0.0 + + #Wohnzimmer [env:sensoresp3] platform = espressif8266 diff --git a/src/main.cpp b/src/main.cpp index 27f3606..95467ac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,7 +104,7 @@ struct sensordata // SW Serial //SW Serial RX: to mhz19 tx (green cable) //SW Serial TX: to mhz19 rx (blue cable) - //co2 sensor needs 5v. Connect USB 5V directly (not through wemos d1 onboard diode which gives only 4.7V!) + //co2 sensor needs 5v. Maybe better to Connect USB 5V directly (not through wemos d1 onboard diode which gives only 4.7V! at '5V' output) //if ABC is disabled (see in setup function) sensor should be calibrated manually. leave outdoors (=400ppm) with no direct sunlight for >20min, then connect HD pin to GND for at least 7 seconds. /* Pinout (view from top, connector at the bottom) @@ -118,9 +118,15 @@ struct sensordata * \-----------------/ * | | | | | * Vo Rx Tx NC HD + * + * [Connector] */ + + #ifndef SOFTWARESERIAL_H #include + #define SOFTWARESERIAL_H + #endif SoftwareSerial mhz19_swSerial; #define BAUD_RATE_MHZ19 9600 @@ -133,6 +139,31 @@ struct sensordata int mhz19_readValue_reimplemented(Stream *_streamRef, MHZ19 *_mhz19Ref); //declare function #endif + +#ifdef SENSOR_SDS018 + struct sensordata dataSDS018_pm25; + struct sensordata dataSDS018_pm10; + + //SDS18 dust sensor for 2.5µm and 10µm + //Needs 5V + + bool sds018_dustok=false; + float value_pm25=-1; + float value_pm10=-1; + + #ifndef SOFTWARESERIAL_H + #include + #define SOFTWARESERIAL_H + #endif + + SoftwareSerial sds018_swSerial; + #define BAUD_RATE_SDS018 9600 + + unsigned long lastread_sds018=0; //to save last read time for both readings + + void readSDS018(); +#endif + // data/homie/config.json hochladen mit platformio run --target uploadfs // config contains homie device name, mqtt ip and wifi credentials @@ -251,6 +282,17 @@ void setup() { } #endif + #ifdef SENSOR_SDS018 + Serial.println("initializing sds018"); + sds018_swSerial.begin(BAUD_RATE_SDS018, SWSERIAL_8N1, SDS018_SERIAL_RX, SDS018_SERIAL_TX, false, 256); + #ifdef dataSDS018_pm25_minchange + dataSDS018_pm25.minchange=dataSDS018_pm25_minchange; + #endif + #ifdef dataSDS018_pm10_minchange + dataSDS018_pm10.minchange=dataSDS018_pm10_minchange; + #endif + #endif + Homie_setFirmware(FW_NAME, FW_VERSION); Homie_setBrand(FW_NAME); @@ -290,6 +332,11 @@ void setup() { #ifdef SENSOR_MHZ19 sensorNode.advertise("co2"); #endif + + #ifdef SENSOR_SDS018 + sensorNode.advertise("dust_pm25"); + sensorNode.advertise("dust_pm10"); + #endif Serial.println("connecting.."); @@ -547,7 +594,74 @@ void loop_MHZ19() } #endif +#ifdef SENSOR_SDS018 +void loop_SDS018_pm25() +{ + sensordata &d=dataSDS018_pm25; + bool _changed=false; + if (millis() >= (d.lastreadtime+d.readdelay)) { + if (millis() >= (lastread_sds018+d.readdelay)) { + readSDS018(); //reads values into value_pm25 und value_pm10 + } + //Homie.getLogger() << "read pm25: " << value_pm25 << ".read pm10: " << value_pm10 << " status=" << dust_ok << endl; + if (fabs(d.lastsentvalue-value_pm25)>=d.minchange){ + _changed=true; + } + d.lastreadtime=millis(); + } + + if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { + Serial.print("Sending SDS018_pm25. reason="); + if (_changed) Serial.println("change"); else Serial.println("time"); + checkESPStatus(); + + Homie.getLogger() << "read pm25: " << value_pm25 << " status=" << sds018_dustok << endl; + if (sds018_dustok){ //send no dust values if sensor not ok + sensorNode.setProperty("dust_pm25").send(String(value_pm25)); + }else{ + Homie.getLogger() << "sds018 dust not ok. didnt sent" << endl; + } + + d.lastsentvalue=value_pm25; + + d.lastsent=millis(); + } +} +void loop_SDS018_pm10() +{ + sensordata &d=dataSDS018_pm10; + + bool _changed=false; + if (millis() >= (d.lastreadtime+d.readdelay)) { + if (millis() >= (lastread_sds018+d.readdelay)) { + readSDS018(); //reads values into value_pm25 und value_pm10 + } + //Homie.getLogger() << "read pm25: " << value_pm25 << ".read pm10: " << value_pm10 << " status=" << dust_ok << endl; + if (fabs(d.lastsentvalue-value_pm10)>=d.minchange){ + _changed=true; + } + d.lastreadtime=millis(); + } + + if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { + Serial.print("Sending SDS018_pm10. reason="); + if (_changed) Serial.println("change"); else Serial.println("time"); + checkESPStatus(); + + Homie.getLogger() << "read pm10: " << value_pm10 << " status=" << sds018_dustok << endl; + if (sds018_dustok){ //send no dust values if sensor not ok + sensorNode.setProperty("dust_pm10").send(String(value_pm10)); + }else{ + Homie.getLogger() << "sds018 dust not ok. didnt sent" << endl; + } + + d.lastsentvalue=value_pm10; + + d.lastsent=millis(); + } +} +#endif @@ -579,8 +693,10 @@ void loopHandler() { loop_MHZ19(); #endif - - + #ifdef SENSOR_SDS018 + loop_SDS018_pm25(); + loop_SDS018_pm10(); + #endif @@ -671,4 +787,50 @@ int mhz19_readValue_reimplemented(Stream *_streamRef, MHZ19 *_mhz19Ref) { //same return co2; } +#endif + +#ifdef SENSOR_SDS018 +void readSDS018() +{ + lastread_sds018=millis(); + // https://github.com/crystaldust/sds018/blob/master/sds018.ino + uint8_t mData = 0; + uint8_t mPkt[10] = {0}; + uint8_t mCheck = 0; + while( sds018_swSerial.available() > 0 ) { + //Serial.println("serial available"); + for( int i=0; i<10; ++i ) { + mPkt[i] = sds018_swSerial.read(); + //Serial.println( mPkt[i], HEX ); + } + if( 0xC0 == mPkt[1] ) { + Serial.println("read density"); + // Read dust density. + // Check + uint8_t sum = 0; + for( int i=2; i<=7; ++i ) { + sum += mPkt[i]; + } + if( sum == mPkt[8] ) { + uint8_t pm25Low = mPkt[2]; + uint8_t pm25High = mPkt[3]; + uint8_t pm10Low = mPkt[4]; + uint8_t pm10High = mPkt[5]; + + value_pm25 = ( ( pm25High * 256.0 ) + pm25Low ) / 10.0; + value_pm10 = ( ( pm10High * 256.0 ) + pm10Low ) / 10.0; + + sds018_dustok=true; + + /*Serial.print( "PM2.5: " ); + Serial.print( pm25 ); + Serial.print( "\nPM10 :" ); + Serial.print( pm10 ); + Serial.println();*/ + } + } + + sds018_swSerial.flush(); + } +} #endif \ No newline at end of file