//#define DEBUG //Compile with platformio run --environment sensorespx //Compile and upload: platformio run --environment sensorespx -t upload //Spiffs data upload with (comment in data_dir line unter platformio section): platformio run --environment sensorespx -t uploadfs //GPIO2 is blue led on wemos_d1 #include "Arduino.h" #ifndef HOMIE_H #include #define HOMIE_H #endif #define FW_NAME "sensoresp" //gets printed on topic/$fw/name #define FW_VERSION "1.0.0" //gets printed on topic/$fw/version #define STATUSNODE #include "sensordata.h" #ifdef SENSOR_DHT22 #include "sensor_dht22.cpp" Sensor_DHT22 sensor_dht22(SENSOR_DHT22_PIN); #ifndef SENSOR_DHT22_temperature_minchange #define SENSOR_DHT22_temperature_minchange 0.2 #endif #ifndef SENSOR_DHT22_temperature_senddelaymax #define SENSOR_DHT22_temperature_senddelaymax 5*60*1000 #endif #ifndef SENSOR_DHT22_temperature_readdelay #define SENSOR_DHT22_temperature_readdelay 10000 #endif #ifndef SENSOR_DHT22_humidity_minchange #define SENSOR_DHT22_humidity_minchange 2.0 #endif #ifndef SENSOR_DHT22_humidity_senddelaymax #define SENSOR_DHT22_humidity_senddelaymax 10*60*1000 #endif #ifndef SENSOR_DHT22_humidity_readdelay #define SENSOR_DHT22_humidity_readdelay 10000 #endif #endif #ifdef SENSOR_BMP180 #include "sensor_bmp180.cpp" Sensor_BMP180 sensor_bmp180; #ifndef SENSOR_BMP180_temperature_minchange #define SENSOR_BMP180_temperature_minchange 0.2 #endif #ifndef SENSOR_BMP180_temperature_senddelaymax #define SENSOR_BMP180_temperature_senddelaymax 5*60*1000 #endif #ifndef SENSOR_BMP180_temperature_readdelay #define SENSOR_BMP180_temperature_readdelay 10000 #endif #ifndef SENSOR_BMP180_pressure_minchange #define SENSOR_BMP180_pressure_minchange 0.5 #endif #ifndef SENSOR_BMP180_pressure_senddelaymax #define SENSOR_BMP180_pressure_senddelaymax 30*60*1000 #endif #ifndef SENSOR_BMP180_pressure_readdelay #define SENSOR_BMP180_pressure_readdelay 10000 #endif #endif #ifdef SENSOR_HTU21D #include "sensor_htu21d.cpp" Sensor_HTU21D sensor_htu21d; #ifndef SENSOR_HTU21D_temperature_minchange #define SENSOR_HTU21D_temperature_minchange 0.2 #endif #ifndef SENSOR_HTU21D_temperature_senddelaymax #define SENSOR_HTU21D_temperature_senddelaymax 300000 #endif #ifndef SENSOR_HTU21D_temperature_readdelay #define SENSOR_HTU21D_temperature_readdelay 10000 #endif #ifndef SENSOR_HTU21D_humidity_minchange #define SENSOR_HTU21D_humidity_minchange 2.0 #endif #ifndef SENSOR_HTU21D_humidity_senddelaymax #define SENSOR_HTU21D_humidity_senddelaymax 10*60*1000 #endif #ifndef SENSOR_HTU21D_humidity_readdelay #define SENSOR_HTU21D_humidity_readdelay 10000 #endif #endif #ifdef SENSOR_HS1101 #include "sensor_hs1101.cpp" Sensor_HS1101 sensor_hs1101(SENSOR_HS1101_PIN); #ifndef SENSOR_HS1101_humidity_minchange #define SENSOR_HS1101_humidity_minchange 2.0 #endif #ifndef SENSOR_HS1101_humidity_senddelaymax #define SENSOR_HS1101_humidity_senddelaymax 10*60*1000 #endif #ifndef SENSOR_HS1101_humidity_readdelay #define SENSOR_HS1101_humidity_readdelay 10000 #endif #endif #ifdef SENSOR_BH1750 #include "sensor_bh1750.cpp" Sensor_BH1750 sensor_bh1750; #ifndef SENSOR_BH1750_light_minchange #define SENSOR_BH1750_light_minchange 10 #endif #ifndef SENSOR_BH1750_light_senddelaymax #define SENSOR_BH1750_light_senddelaymax 5*60*1000 #endif #ifndef SENSOR_BH1750_light_readdelay #define SENSOR_BH1750_light_readdelay 1000*10 #endif #endif #ifdef SENSOR_ML8511 #include "sensor_ml8511.cpp" Sensor_ML8511 sensor_ml8511(SENSOR_ML8511_PIN); #ifndef SENSOR_ML8511_minchange #define SENSOR_ML8511_minchange 0.2 #endif #ifndef SENSOR_ML8511_senddelaymax #define SENSOR_ML8511_senddelaymax 5*60*1000 #endif #ifndef SENSOR_ML8511_readdelay #define SENSOR_ML8511_readdelay 1000*10 #endif #endif #ifdef SENSOR_HCSR501 #include "sensor_hcsr501.cpp" Sensor_HCSR501 sensor_hcsr501(SENSOR_HCSR501_PIN); #ifndef SENSOR_HCSR501_senddelaymax #define SENSOR_HCSR501_senddelaymax 1000*60*10 #endif #ifndef SENSOR_HCSR501_readdelayML8511 #define SENSOR_HCSR501_readdelay 100 #endif #endif #ifdef SENSOR_RADAR #include "sensor_radar.cpp" Sensor_Radar sensor_radar(SENSOR_RADAR_PIN); #ifndef SENSOR_RADAR_senddelaymax #define SENSOR_RADAR_senddelaymax 1000*60*10 #endif #ifndef SENSOR_RADAR_readdelayML8511 #define SENSOR_RADAR_readdelay 100 #endif #endif #ifdef SENSOR_LDR #include "sensor_ldr.cpp" Sensor_LDR sensor_ldr(SENSOR_LDR_PIN); #ifndef SENSOR_LDR_minchange #define SENSOR_LDR_minchange 10.0 #endif #ifndef SENSOR_LDR_senddelaymax #define SENSOR_LDR_senddelaymax 1000*60*1 #endif #ifndef SENSOR_LDR_readdelay #define SENSOR_LDR_readdelay 1000*2 #endif #endif #ifdef SENSOR_MHZ19B #include "sensor_mhz19b.cpp" Sensor_MHZ19B sensor_mhz19b(SENSOR_MHZ19B_SERIAL_RX,SENSOR_MHZ19B_SERIAL_TX); #ifndef SENSOR_MHZ19B_minchange #define SENSOR_MHZ19B_minchange 10.0 #endif #ifndef SENSOR_MHZ19B_senddelaymax #define SENSOR_MHZ19B_senddelaymax 1000*60*10 #endif #ifndef SENSOR_MHZ19B_readdelay #define SENSOR_MHZ19B_readdelay 1000*10 #endif #endif #ifdef SENSOR_SDS018 #include "sensor_sds018.cpp" Sensor_SDS018 sensor_sds018(SENSOR_SDS018_SERIAL_RX,SENSOR_SDS018_SERIAL_TX); #ifndef SENSOR_SDS018_PM10_minchange #define SENSOR_SDS018_PM10_minchange 10.0 #endif #ifndef SENSOR_SDS018_PM10_senddelaymax #define SENSOR_SDS018_PM10_senddelaymax 1000*60*5 #endif #ifndef SENSOR_SDS018_PM10_readdelay #define SENSOR_SDS018_PM10_readdelay 1000*10 #endif #ifndef SENSOR_SDS018_PM25_minchange #define SENSOR_SDS018_PM25_minchange 10.0 #endif #ifndef SENSOR_SDS018_PM25_senddelaymax #define SENSOR_SDS018_PM25_senddelaymax 1000*60*5 #endif #ifndef SENSOR_SDS018_PM25_readdelay #define SENSOR_SDS018_PM25_readdelay 1000*10 #endif #endif #ifdef SENSOR_TCS34725 //#include "Adafruit_TCS34725.h" #include "tcs34725_agc.h" //class code from example https://github.com/adafruit/Adafruit_TCS34725/blob/master/examples/tcs34725autorange/tcs34725autorange.ino //Connect SCL to D1, SDA to D2, GND and 3v3 //Maximum measurable light is around 20k Lux. (direct sunlight is easily above 20k Lux) //Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X); //initializer from standart class tcs34725 tcs; //wrapper class with agc bool tcs34725init_ok=false; struct sensordata dataTCS34725_lux; struct sensordata dataTCS34725_colortemp; uint16_t value_colortemp, value_tcs_lux, value_tcs_r,value_tcs_g,value_tcs_b,value_tcs_c; unsigned long lastread_tcs34725=0; #define TCS34725_MINLUXFORCT 30 //send only colortemperature values if lux is at least this high #ifndef TCS34725_LUXFACTOR #define TCS34725_LUXFACTOR 1 #endif #endif #ifdef SENSOR_VL53L1X #ifndef WIRE_H #include #define WIRE_H #endif #include VL53L1X vl53l1x; bool vl53l1xinit_ok=false; struct sensordata dataVL53L1X; uint16_t value_vl53l1x_range; unsigned long lastread_vl53l1x=0; VL53L1X::RangeStatus lastsentvalue_vl53l1x_status; #endif #ifdef SENSOR_ANEMOMETER //uses ATS177 Latched hall sensor for rotation sensing sensordata dataAnemometer; unsigned long anemometer_lasttimereset=0; uint16_t anemometer_pulsecounter=0; //counted pulses since last reset #define ANEMOMETER_DEBOUNCETIME 15 //15ms between pulses is approx 85m/s windspeed unsigned long anemometer_lastpulse_fordebounce=0; float value_anemometer=0; // [m/s] void ICACHE_RAM_ATTR interrupt_anemometer(); void updateAnemometer(); #endif #ifdef SENSOR_RAINGAUGE //uses ATS177 Latched Hall Sensor for rauge flip sensing sensordata dataRaingauge; unsigned long raingauge_lasttimereset=0; uint16_t raingauge_pulsecounter=0; //counted pulses since last reset bool raingauge_idleflag=true; #define RAINGAUGE_DEBOUNCETIME 1000 unsigned long raingauge_lastpulse_fordebounce=0; float value_raingauge=0; // [mm] or [L/m^2] #define RAINGAUGE_FLIPAMOUNT 0.38888 //how much mm rain (L/m^2) per gauge flip. mL (rain to flip) / A (opening area) //was 0.69292 until 201702 /* Calibration: * Test1: 1000mL -> 259 Flips * Test2: 1000mL -> 256 in ca 10min * -> 3,9mL per Flip, opening diameter =113mm -> A=0,010028749 */ void ICACHE_RAM_ATTR interrupt_raingauge(); void updateRaingauge(); #endif // data/homie/config.json hochladen mit platformio run --target uploadfs // config contains homie device name, mqtt ip and wifi credentials HomieNode sensorNode("sensors", "Sensors","sensors"); //id, name, type char tempstring[16]; //for dtostrf void loopHandler(); void checkESPStatus(); void setup() { Serial.begin(115200); Serial.println(); Serial.println("Booting"); delay(1000); //wait for sensors to get powered #ifdef SENSOR_DHT22 sensor_dht22.init(); sensor_dht22.setSettings_Temperature(SENSOR_DHT22_temperature_minchange,SENSOR_DHT22_temperature_senddelaymax,SENSOR_DHT22_temperature_readdelay); sensor_dht22.setSettings_Humidity(SENSOR_DHT22_humidity_minchange,SENSOR_DHT22_humidity_senddelaymax,SENSOR_DHT22_humidity_readdelay); #endif #ifdef SENSOR_BMP180 sensor_bmp180.init(); sensor_bmp180.setSettings_Temperature(SENSOR_BMP180_temperature_minchange,SENSOR_BMP180_temperature_senddelaymax,SENSOR_BMP180_temperature_readdelay); sensor_bmp180.setSettings_Pressure(SENSOR_BMP180_temperature_minchange,SENSOR_BMP180_temperature_senddelaymax,SENSOR_BMP180_temperature_readdelay); #endif #ifdef SENSOR_HTU21D sensor_htu21d.init(); sensor_htu21d.setSettings_Temperature(SENSOR_HTU21D_temperature_minchange,SENSOR_HTU21D_temperature_senddelaymax,SENSOR_HTU21D_temperature_readdelay); sensor_htu21d.setSettings_Humidity(SENSOR_HTU21D_humidity_minchange,SENSOR_HTU21D_humidity_senddelaymax,SENSOR_HTU21D_humidity_readdelay); #endif #ifdef SENSOR_HS1101 sensor_hs1101.init(); sensor_hs1101.setSettings(SENSOR_HS1101_humidity_minchange,SENSOR_HS1101_humidity_senddelaymax,SENSOR_HS1101_humidity_readdelay); #endif #ifdef SENSOR_BH1750 sensor_bh1750.init(); sensor_bh1750.setSettings(SENSOR_BH1750_light_minchange,SENSOR_BH1750_light_senddelaymax,SENSOR_BH1750_light_readdelay); #endif #ifdef SENSOR_ML8511 sensor_ml8511.init(); sensor_ml8511.setSettings(SENSOR_ML8511_minchange,SENSOR_ML8511_senddelaymax,SENSOR_ML8511_readdelay); #endif #ifdef SENSOR_HCSR501 sensor_hcsr501.init(); sensor_hcsr501.setSettings(SENSOR_HCSR501_senddelaymax,SENSOR_HCSR501_readdelay); #endif #ifdef SENSOR_RADAR sensor_radar.init(); sensor_radar.setSettings(SENSOR_RADAR_senddelaymax,SENSOR_RADAR_readdelay); #endif #ifdef SENSOR_LDR sensor_ldr.init(); sensor_ldr.setSettings(SENSOR_LDR_minchange,SENSOR_LDR_senddelaymax,SENSOR_LDR_readdelay); #endif #ifdef SENSOR_MHZ19B sensor_mhz19b.init(); sensor_mhz19b.setSettings(SENSOR_MHZ19B_minchange,SENSOR_MHZ19B_senddelaymax,SENSOR_MHZ19B_readdelay); #endif #ifdef SENSOR_SDS018 sensor_sds018.init(); sensor_sds018.setSettings_pm10(SENSOR_SDS018_PM10_minchange,SENSOR_SDS018_PM10_senddelaymax,SENSOR_SDS018_PM10_readdelay); sensor_sds018.setSettings_pm25(SENSOR_SDS018_PM25_minchange,SENSOR_SDS018_PM25_senddelaymax,SENSOR_SDS018_PM25_readdelay); #endif #ifdef SENSOR_TCS34725 Serial.println("initializing tcs34725"); if (!tcs.begin()) { Serial.println("No TCS34725 found!"); }else{ tcs34725init_ok=true; } #ifdef dataTCS34725_lux_minchange dataTCS34725_lux.minchange=dataTCS34725_lux_minchange; #endif #ifdef dataTCS34725_lux_senddelaymax dataTCS34725_lux.senddelaymax=dataTCS34725_lux_senddelaymax; #endif #ifdef dataTCS34725_colortemp_minchange dataTCS34725_colortemp.minchange=dataTCS34725_colortemp_minchange; #endif #endif #ifdef SENSOR_VL53L1X Serial.println("initializing vl53l1x"); vl53l1x.setTimeout(500); if (!vl53l1x.init()) { Serial.println("No vl53l1x found!"); }else{ vl53l1xinit_ok=true; vl53l1x.setDistanceMode(VL53L1X::Long); vl53l1x.setMeasurementTimingBudget(50000); vl53l1x.startContinuous(1000); //This period should be at least as long as the timing budget. } #ifdef dataVL53L1X_minchange dataVL53L1X.minchange=dataVL53L1X_minchange; #endif #ifdef dataVL53L1X_senddelaymax dataVL53L1X.senddelaymax=dataVL53L1X_senddelaymax; #endif #ifdef dataVL53L1X_readdelay dataVL53L1X.readdelay=dataVL53L1X_readdelay; #endif #endif #ifdef SENSOR_ANEMOMETER pinMode(ANEMOMETERPIN,INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(ANEMOMETERPIN),interrupt_anemometer,CHANGE); //anemometer interrupt #ifdef dataAnemometer_minchange dataAnemometer.minchange=dataAnemometer_minchange; #endif #ifdef dataAnemometer_readdelay dataAnemometer.readdelay=dataAnemometer_readdelay; #endif #ifdef dataAnemometer_senddelaymax dataAnemometer.senddelaymax=dataAnemometer_senddelaymax; #endif #endif #ifdef SENSOR_RAINGAUGE pinMode(RAINGAUGEPIN,INPUT_PULLUP); attachInterrupt(digitalPinToInterrupt(RAINGAUGEPIN),interrupt_raingauge,CHANGE); //anemometer interrupt #ifdef dataRaingauge_senddelaymax dataRaingauge.senddelaymax=dataRaingauge_senddelaymax; #endif #ifdef dataRaingauge_readdelay dataRaingauge.readdelay=dataRaingauge_readdelay; #endif #endif // ##### Advertise topics below here ##### //Homie_setFirmware(FW_NAME, FW_VERSION); //Homie_setBrand(FW_NAME); Homie_setFirmware(FW_NAME, FW_VERSION); Homie.setLoopFunction(loopHandler); #ifdef STATUSNODE //to return some stuff about status, errors etc. Serial.println("Using status node"); sensorNode.advertise("status"); #endif #ifdef SENSOR_DHT22 sensor_dht22.advertise(sensorNode); #endif #ifdef SENSOR_BMP180 sensor_bmp180.advertise(sensorNode); #endif #ifdef SENSOR_HTU21D sensor_htu21d.advertise(sensorNode); #endif #ifdef SENSOR_HS1101 sensor_hs1101.advertise(sensorNode); #endif #ifdef SENSOR_BH1750 sensor_bh1750.advertise(sensorNode); #endif #ifdef SENSOR_ML8511 sensor_ml8511.advertise(sensorNode); #endif #ifdef SENSOR_HCSR501 sensor_hcsr501.advertise(sensorNode); #endif #ifdef SENSOR_RADAR sensor_radar.advertise(sensorNode); #endif #ifdef SENSOR_LDR sensor_ldr.advertise(sensorNode); #endif #ifdef SENSOR_MHZ19B sensor_mhz19b.advertise(sensorNode); #endif #ifdef SENSOR_SDS018 sensor_sds018.advertise(sensorNode); #endif #ifdef SENSOR_TCS34725 #if defined(SENSOR_LDR) || defined(SENSOR_BH1750) sensorNode.advertise("light_tcs"); #else sensorNode.advertise("light"); #endif sensorNode.advertise("colortemp"); #endif #ifdef SENSOR_VL53L1X sensorNode.advertise("tofstatus"); sensorNode.advertise("tofrange"); sensorNode.advertise("tofpeaksignal"); sensorNode.advertise("tofambient"); #endif #ifdef SENSOR_ANEMOMETER sensorNode.advertise("windspeed"); #endif #ifdef SENSOR_RAINGAUGE sensorNode.advertise("rain"); #endif Serial.println("connecting.."); Homie.setup(); Serial.println(""); Serial.println("connected"); //wird nicht ausgegeben. keine ahnung warum. } void loop() { Homie.loop(); } #ifdef SENSOR_TCS34725 void loop_TCS34725_lux() { sensordata &d=dataTCS34725_lux; bool _changed=false; if (millis() >= (d.lastreadtime+d.readdelay)) { if (millis() >= (lastread_tcs34725+d.readdelay)) { //avoid reading sensor twice in a short time //tcs.getRawData(&value_tcs_r, &value_tcs_g, &value_tcs_b, &value_tcs_c); tcs.getData(); lastread_tcs34725=millis(); if (tcs.isSaturated){ Serial.println("Warning: tcs34725 is saturated"); #ifdef STATUSNODE sensorNode.setProperty("status").send("TCS34725 is saturated"); #endif } } //value_tcs_lux = tcs.calculateLux(value_tcs_r, value_tcs_g, value_tcs_b); uint16_t _value_tcs_lux = tcs.lux*TCS34725_LUXFACTOR; if (!tcs.isSaturated && _value_tcs_lux<65535){ //sometimes false high reading accur around 65535 sometimes less. with isSaturated check only 65535 values appeared. value_tcs_lux = _value_tcs_lux; } if (abs((int)d.lastsentvalue-value_tcs_lux)>=d.minchange){ //int abs _changed=true; } d.lastreadtime=millis(); } if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { Serial.print("Sending TCS Lux. reason="); if (_changed) Serial.println("change"); else Serial.println("time"); checkESPStatus(); Homie.getLogger() << "light tcs " << ": " << value_tcs_lux << endl; #if defined(SENSOR_LDR) || defined(SENSOR_BH1750) sensorNode.setProperty("light_tcs").send(String(value_tcs_lux)); #else sensorNode.setProperty("light").send(String(value_tcs_lux)); #endif d.lastsentvalue=value_tcs_lux; d.lastsent=millis(); } } void loop_TCS34725_colortemp() { sensordata &d=dataTCS34725_colortemp; bool _changed=false; if (millis() >= (d.lastreadtime+d.readdelay)) { if (millis() >= (lastread_tcs34725+d.readdelay)) { //avoid reading sensor twice in a short time //tcs.getRawData(&value_tcs_r, &value_tcs_g, &value_tcs_b, &value_tcs_c); tcs.getData(); lastread_tcs34725=millis(); if (tcs.isSaturated){ Serial.println("Warning: tcs34725 is saturated"); } } // colorTemp = tcs.calculateColorTemperature(r, g, b); //value_colortemp = tcs.calculateColorTemperature_dn40(value_tcs_r, value_tcs_g, value_tcs_b, value_tcs_c); if (!tcs.isSaturated){ value_colortemp = tcs.ct; //with agc } if (abs((int)d.lastsentvalue-value_colortemp)>=d.minchange){ //int abs _changed=true; } d.lastreadtime=millis(); } if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { Serial.print("Sending TCS colortemp. reason="); if (_changed) Serial.println("change"); else Serial.println("time"); checkESPStatus(); Homie.getLogger() << "colortemp tcs " << ": " << value_colortemp << endl; if (tcs.lux>=TCS34725_MINLUXFORCT) { if (value_colortemp > 1) { sensorNode.setProperty("colortemp").send(String(value_colortemp)); }else{ Homie.getLogger() << "didn't send tcs ct because value is too low" << endl; sensorNode.setProperty("colortemp").send(String(-1)); } }else{ Homie.getLogger() << "didn't send tcs ct because light too low: " << tcs.lux << "lux" << endl; sensorNode.setProperty("colortemp").send(String(-1)); } d.lastsentvalue=value_colortemp; d.lastsent=millis(); } } #endif #ifdef SENSOR_VL53L1X void loop_VL53L1X() { sensordata &d=dataVL53L1X; bool _changed=false; if (millis() >= (d.lastreadtime+d.readdelay)) { if (millis() >= (lastread_vl53l1x+d.readdelay)) { //avoid reading sensor twice in a short time //tcs.getRawData(&value_tcs_r, &value_tcs_g, &value_tcs_b, &value_tcs_c); vl53l1x.read(); lastread_vl53l1x=millis(); } value_vl53l1x_range=vl53l1x.ranging_data.range_mm; /* for debugging Serial.print("range: "); Serial.print(vl53l1x.ranging_data.range_mm); Serial.print("\tstatus: "); Serial.print(VL53L1X::rangeStatusToString(vl53l1x.ranging_data.range_status)); Serial.print("\tstatus="); Serial.print(vl53l1x.ranging_data.range_status); Serial.print("\tpeak signal: "); Serial.print(vl53l1x.ranging_data.peak_signal_count_rate_MCPS); Serial.print("\tambient: "); Serial.print(vl53l1x.ranging_data.ambient_count_rate_MCPS); Serial.println(); */ if (abs((int)d.lastsentvalue-value_vl53l1x_range)>=d.minchange){ //int abs _changed=true; } if (lastsentvalue_vl53l1x_status!=vl53l1x.ranging_data.range_status) { //sensor status changed _changed=true; } d.lastreadtime=millis(); } if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { Serial.print("Sending VL53L1X range. reason="); if (_changed) Serial.println("change"); else Serial.println("time"); checkESPStatus(); Homie.getLogger() << "range vl53l1x " << ": " << value_vl53l1x_range << endl; sensorNode.setProperty("tofstatus").send(VL53L1X::rangeStatusToString(vl53l1x.ranging_data.range_status)); sensorNode.setProperty("tofrange").send(String(value_vl53l1x_range)); sensorNode.setProperty("tofpeaksignal").send(String(vl53l1x.ranging_data.peak_signal_count_rate_MCPS)); sensorNode.setProperty("tofambient").send(String(vl53l1x.ranging_data.ambient_count_rate_MCPS)); d.lastsentvalue=value_vl53l1x_range; lastsentvalue_vl53l1x_status=vl53l1x.ranging_data.range_status; d.lastsent=millis(); } } #endif #ifdef SENSOR_ANEMOMETER void loop_anemometer() { sensordata &d=dataAnemometer; bool _changed=false; if (millis() >= (d.lastreadtime+d.readdelay)) { uint16_t _anepulsesPerMinute=anemometer_pulsecounter/((millis()-anemometer_lasttimereset)/60000.0); value_anemometer = _anepulsesPerMinute*ANEMOMETER_PPMtoMPS; if (abs((int)d.lastsentvalue-value_anemometer)>=d.minchange){ //int abs _changed=true; } d.lastreadtime=millis(); } if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { Serial.print("Sending windspeed. reason="); if (_changed) Serial.println("change"); else Serial.println("time"); checkESPStatus(); Homie.getLogger() << "windspeed tcs " << ": " << value_anemometer << endl; sensorNode.setProperty("windspeed").send(String(value_anemometer)); //reset when sent. makes it more accurate but keeps fast response anemometer_pulsecounter=0; //reset counter anemometer_lasttimereset=millis(); d.lastreadtime=millis(); //also set lastread time to avoid having 1 count with a low time = high windspeed d.lastsentvalue=value_anemometer; d.lastsent=millis(); } } #endif #ifdef SENSOR_RAINGAUGE void loop_raingauge() { sensordata &d=dataRaingauge; bool _changed=false; if (millis() >= (d.lastreadtime+d.readdelay)) { if (millis()-raingauge_lasttimereset > d.senddelaymax) { raingauge_idleflag=true; //raingauge didn't flip for a long time } if (raingauge_pulsecounter>0){ //if rg flipped if (raingauge_idleflag) { //last flip is before reset time value_raingauge=raingauge_pulsecounter*RAINGAUGE_FLIPAMOUNT; //set to fixed amount if flip was exactly at that time raingauge_idleflag=false; }else{ value_raingauge=3600000/(millis()-raingauge_lasttimereset)/raingauge_pulsecounter*RAINGAUGE_FLIPAMOUNT; raingauge_idleflag=false; } _changed=true; } d.lastreadtime=millis(); } if (_changed || millis() >= (d.lastsent+d.senddelaymax)) { Serial.print("Sending rain. reason="); if (_changed) Serial.println("change"); else Serial.println("time"); checkESPStatus(); if (!_changed) { //no flip since a long time value_raingauge=0; //set to no rain } Homie.getLogger() << "rain " << ": " << value_raingauge << endl; sensorNode.setProperty("rain").send(String(value_raingauge)); //reset when sent. makes it more accurate but keeps fast response raingauge_pulsecounter=0; //reset counter raingauge_lasttimereset=millis(); d.lastsentvalue=value_raingauge; d.lastsent=millis(); } } #endif void loopHandler() { checkESPStatus(); #ifdef SENSOR_DHT22 sensor_dht22.sensorloop(); #endif #ifdef SENSOR_BMP180 sensor_bmp180.sensorloop(); #endif #ifdef SENSOR_HTU21D sensor_htu21d.sensorloop(); #endif #ifdef SENSOR_HS1101 sensor_hs1101.sensorloop(); #endif #ifdef SENSOR_BH1750 sensor_bh1750.sensorloop(); #endif #ifdef SENSOR_ML8511 sensor_ml8511.sensorloop(); #endif #ifdef SENSOR_HCSR501 sensor_hcsr501.sensorloop(); #endif #ifdef SENSOR_RADAR sensor_radar.sensorloop(); #endif #ifdef SENSOR_LDR sensor_ldr.sensorloop(); #endif #ifdef SENSOR_MHZ19B sensor_mhz19b.sensorloop(); #endif #ifdef SENSOR_SDS018 loop_SDS018_pm25(); loop_SDS018_pm10(); #endif #ifdef SENSOR_TCS34725 if (tcs34725init_ok) { loop_TCS34725_lux(); loop_TCS34725_colortemp(); } #endif #ifdef SENSOR_VL53L1X if (vl53l1xinit_ok) { loop_VL53L1X(); } #endif #ifdef SENSOR_ANEMOMETER loop_anemometer(); #endif #ifdef SENSOR_RAINGAUGE loop_raingauge(); #endif } void checkESPStatus() { if (WiFi.status() != WL_CONNECTED) //restart if wifi signal loss { ESP.reset(); } } #ifdef SENSOR_ANEMOMETER void ICACHE_RAM_ATTR interrupt_anemometer() { if (millis() - anemometer_lastpulse_fordebounce >= ANEMOMETER_DEBOUNCETIME) { //ignore if pulse came too fast anemometer_pulsecounter++; anemometer_lastpulse_fordebounce=millis(); } } #endif #ifdef SENSOR_RAINGAUGE void ICACHE_RAM_ATTR interrupt_raingauge() { if (millis() - raingauge_lastpulse_fordebounce >= RAINGAUGE_DEBOUNCETIME) { //ignore if pulse came too fast raingauge_pulsecounter++; raingauge_lastpulse_fordebounce=millis(); } } #endif /*################################## * ######## HELPER FUNCTIONS ######## */ //quelle: https://groups.google.com/forum/#!topic/souliss/1kMAltPB2ME[1-25] int get_mapped(const unsigned int* _in, const unsigned int* _out, byte size,int val) //map with constrain { // take care the value is within range // val = constrain(val, _in[0], _in[size-1]); if (val <= _in[0]) return _out[0]; if (val >= _in[size-1]) return _out[size-1]; // search right interval byte pos = 1; // _in[0] allready tested while(val > _in[pos]) pos++; // this will handle all exact "points" in the _in array if (val == _in[pos]) return _out[pos]; // interpolate in the right segment for the rest return map(val, _in[pos-1], _in[pos], _out[pos-1], _out[pos]); } //The Arduino Map function but for floats //From: http://forum.arduino.cc/index.php?topic=3922.0 float mapfloat(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; }