2020-08-15 17:45:02 +00:00
//#define DEBUG
2020-10-10 13:50:59 +00:00
//Compile with platformio run --environment sensorespx
2020-10-14 21:32:25 +00:00
//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
2020-10-10 13:50:59 +00:00
2020-10-02 17:45:33 +00:00
//GPIO2 is blue led on wemos_d1
2020-08-16 09:09:12 +00:00
2020-10-02 17:45:33 +00:00
# include "Arduino.h"
2021-10-31 13:07:09 +00:00
# ifndef HOMIE_H
# include <Homie.h>
# define HOMIE_H
# endif
2020-10-02 17:45:33 +00:00
# define FW_NAME "sensoresp" //gets printed on topic/$fw/name
# define FW_VERSION "1.0.0" //gets printed on topic/$fw/version
2020-08-15 17:45:02 +00:00
2020-12-31 16:47:13 +00:00
# define STATUSNODE
2020-10-02 18:28:14 +00:00
2021-11-02 17:51:55 +00:00
# include "sensordata.h"
2020-08-15 17:45:02 +00:00
2020-12-31 16:47:13 +00:00
2021-10-31 13:07:09 +00:00
# ifdef SENSOR_DHT22
# include "sensor_dht22.cpp"
Sensor_DHT22 sensor_dht22 ( SENSOR_DHT22_PIN ) ;
2021-11-02 19:13:38 +00:00
# ifndef SENSOR_DHT22_temperature_minchange
# define SENSOR_DHT22_temperature_minchange 0.2
# endif
# ifndef SENSOR_DHT22_temperature_senddelaymax
2021-11-03 18:03:28 +00:00
# define SENSOR_DHT22_temperature_senddelaymax 5*60*1000
2021-11-02 19:13:38 +00:00
# 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
2021-11-03 18:03:28 +00:00
# define SENSOR_DHT22_humidity_senddelaymax 10*60*1000
2021-11-02 19:13:38 +00:00
# endif
# ifndef SENSOR_DHT22_humidity_readdelay
# define SENSOR_DHT22_humidity_readdelay 10000
# endif
2021-10-31 13:07:09 +00:00
# endif
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_BMP180
2021-11-02 19:13:38 +00:00
# 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
2021-11-03 18:03:28 +00:00
# define SENSOR_BMP180_temperature_senddelaymax 5*60*1000
2021-11-02 19:13:38 +00:00
# endif
# ifndef SENSOR_BMP180_temperature_readdelay
# define SENSOR_BMP180_temperature_readdelay 10000
# endif
# ifndef SENSOR_BMP180_pressure_minchange
2021-11-03 18:03:28 +00:00
# define SENSOR_BMP180_pressure_minchange 0.5
2021-11-02 19:13:38 +00:00
# endif
# ifndef SENSOR_BMP180_pressure_senddelaymax
2021-11-03 18:03:28 +00:00
# define SENSOR_BMP180_pressure_senddelaymax 30*60*1000
2021-11-02 19:13:38 +00:00
# endif
# ifndef SENSOR_BMP180_pressure_readdelay
# define SENSOR_BMP180_pressure_readdelay 10000
# endif
2020-10-02 17:45:33 +00:00
# endif
2020-08-15 17:45:02 +00:00
2021-08-17 20:31:32 +00:00
# ifdef SENSOR_HTU21D
2021-11-03 18:03:28 +00:00
# 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
2021-08-17 20:31:32 +00:00
# endif
2021-11-03 18:03:28 +00:00
# ifndef SENSOR_HTU21D_humidity_readdelay
# define SENSOR_HTU21D_humidity_readdelay 10000
# endif
2021-08-17 20:31:32 +00:00
# endif
2020-10-29 17:53:05 +00:00
# ifdef SENSOR_HS1101
2021-11-04 16:52:39 +00:00
# include "sensor_hs1101.cpp"
2021-11-04 17:47:43 +00:00
Sensor_HS1101 sensor_hs1101 ( SENSOR_HS1101_PIN ) ;
2021-11-04 16:52:39 +00:00
# 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
2020-10-29 17:53:05 +00:00
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_BH1750
2021-11-04 17:21:31 +00:00
# include "sensor_bh1750.cpp"
Sensor_BH1750 sensor_bh1750 ;
2021-11-04 17:47:43 +00:00
# ifndef SENSOR_BH1750_light_minchange
# define SENSOR_BH1750_light_minchange 10
2021-11-04 17:21:31 +00:00
# endif
2021-11-04 17:47:43 +00:00
# ifndef SENSOR_BH1750_light_senddelaymax
# define SENSOR_BH1750_light_senddelaymax 5*60*1000
2021-11-04 17:21:31 +00:00
# endif
2021-11-04 17:47:43 +00:00
# ifndef SENSOR_BH1750_light_readdelay
# define SENSOR_BH1750_light_readdelay 1000*10
2021-08-17 20:31:32 +00:00
# endif
2020-10-02 17:45:33 +00:00
# endif
2020-08-16 09:09:12 +00:00
2020-10-30 08:23:05 +00:00
# ifdef SENSOR_ML8511
//ML8511 UV Sensor outputs an analog voltage. ML8511PIN needs to be an ADC pin
2021-11-04 17:47:43 +00:00
# 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
2020-10-30 08:23:05 +00:00
# endif
2020-08-15 17:45:02 +00:00
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_PIR
2020-11-08 10:59:34 +00:00
// PIR Sensors HC-SR501
// pir sensor needs 5v through an inductor for filtering. output level is 3.3v
2021-11-04 17:47:43 +00:00
// 100nF capacitor SENSOR_ML8511_minchangeshould be soldered between pins 12 and 13 of BISS0001 to stop interference from esp causing false triggers (in some setups). source: https://www.letscontrolit.com/forum/viewtopic.php?t=671
2020-11-08 10:59:34 +00:00
// hc-sr501 should also be a few cm away from the esp. interference can cause false triggering
// poti closer to jumper is sensitivity (cw increases). other poti is pulse time (cw increases).
// time set to output around 30s pulse
2020-10-02 18:28:14 +00:00
sensordata dataPIR ;
2020-10-02 21:25:33 +00:00
bool value_PIR = false ;
2020-10-02 17:45:33 +00:00
# endif
2020-08-15 17:45:02 +00:00
2021-07-14 19:09:23 +00:00
# ifdef SENSOR_RADAR
// High/Low Output Radar Sensor
// For example: RCWL-0516 (needs 5v input (gnd, vin), 3.3v output level. high for 2seconds when movement detected)
sensordata dataRADAR ;
bool value_RADAR = false ;
# endif
2020-08-15 17:45:02 +00:00
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_LDR
struct sensordata dataLDR ;
float value_ldr = 0 ;
# ifdef SENSOR_LDR_CALIB1
# define LDRARRAYSIZE 18
//black wire of ldr connects to A0 with 10k to gnd. red wire connects with 1k to gnd and 2k2 to 3v3
static const unsigned int out_ldr [ ] = { 0 , 30 , 50 , 60 , 130 , 170 , 250 , 420 , 780 , 1300 , 2600 , 5000 , 5350 , 7700 , 10900 , 12000 , 17000 , 20000 } ; // x10 (i.e. gets later divided by 10)
static const unsigned int in_ldr [ ] = { 0 , 12 , 100 , 150 , 350 , 400 , 450 , 650 , 730 , 780 , 840 , 930 , 948 , 970 , 993 , 1005 , 1019 , 1023 } ; // 0 - 1023
# endif
2020-10-23 20:13:32 +00:00
int get_lux ( const unsigned int * _in , const unsigned int * _out , byte size ) ; //for analog ldr light calculation
2020-10-10 13:50:59 +00:00
# endif
2020-10-14 21:32:25 +00:00
# ifdef SENSOR_MHZ19
struct sensordata dataMHZ19 ;
/*
* MHZ19 Library : https : //platformio.org/lib/show/1620/SevSegSPI
* Software Serial Library : https : //platformio.org/lib/show/168/EspSoftwareSerial
2020-12-31 16:47:13 +00:00
2020-10-14 21:32:25 +00:00
*/
// SW Serial
//SW Serial RX: to mhz19 tx (green cable)
//SW Serial TX: to mhz19 rx (blue cable)
2020-10-23 07:14:43 +00:00
//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)
2020-10-14 21:32:25 +00:00
2020-10-15 21:13:25 +00:00
//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.
2020-10-22 18:31:52 +00:00
/* Pinout (view from top, connector at the bottom)
* Vin , GND , NC , PWM
* | | | |
* / - - - - - - - - - - - - - - - - - \
* | |
* | |
* | |
* | |
* \ - - - - - - - - - - - - - - - - - /
* | | | | |
* Vo Rx Tx NC HD
2020-10-23 07:14:43 +00:00
*
* [ Connector ]
2020-10-22 18:31:52 +00:00
*/
2020-10-15 21:13:25 +00:00
2020-10-23 07:14:43 +00:00
# ifndef SOFTWARESERIAL_H
2020-10-14 21:32:25 +00:00
# include <SoftwareSerial.h>
2020-10-23 07:14:43 +00:00
# define SOFTWARESERIAL_H
# endif
2020-10-14 21:32:25 +00:00
SoftwareSerial mhz19_swSerial ;
# define BAUD_RATE_MHZ19 9600
2020-12-31 16:47:13 +00:00
# define MHZ19CALIBRATIONTOPIC
2020-10-14 21:32:25 +00:00
# include <MHZ19.h>
MHZ19 mhz19 ;
bool mhz19_ready = false ;
int value_co2 = - 1 ; //[ppm]
2020-10-22 21:00:33 +00:00
int mhz19_readValue_reimplemented ( Stream * _streamRef , MHZ19 * _mhz19Ref ) ; //declare function
2020-12-31 16:47:13 +00:00
# ifdef MHZ19CALIBRATIONTOPIC
bool mhz19calibrationHandler ( const HomieRange & range , const String & value ) ;
# endif
2020-10-14 21:32:25 +00:00
# endif
2020-10-10 13:50:59 +00:00
2020-10-23 07:14:43 +00:00
# ifdef SENSOR_SDS018
struct sensordata dataSDS018_pm25 ;
struct sensordata dataSDS018_pm10 ;
2020-12-31 16:47:13 +00:00
// SDS018 example: https://github.com/crystaldust/sds018/blob/master/sds018.ino
2020-10-23 07:14:43 +00:00
//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 <SoftwareSerial.h>
# 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
2020-10-23 21:09:01 +00:00
# ifdef SENSOR_TCS34725
2020-11-01 11:24:34 +00:00
//#include "Adafruit_TCS34725.h"
# include "tcs34725_agc.h" //class code from example https://github.com/adafruit/Adafruit_TCS34725/blob/master/examples/tcs34725autorange/tcs34725autorange.ino
2020-10-29 17:53:05 +00:00
//Connect SCL to D1, SDA to D2, GND and 3v3
2020-11-03 19:41:46 +00:00
//Maximum measurable light is around 20k Lux. (direct sunlight is easily above 20k Lux)
2020-11-01 11:24:34 +00:00
//Adafruit_TCS34725 tcs = Adafruit_TCS34725(TCS34725_INTEGRATIONTIME_700MS, TCS34725_GAIN_1X); //initializer from standart class
tcs34725 tcs ; //wrapper class with agc
2020-10-23 21:09:01 +00:00
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 ;
2020-11-01 11:28:45 +00:00
# define TCS34725_MINLUXFORCT 30 //send only colortemperature values if lux is at least this high
2020-11-14 16:38:54 +00:00
# ifndef TCS34725_LUXFACTOR
# define TCS34725_LUXFACTOR 1
# endif
2020-10-23 21:09:01 +00:00
# endif
2021-10-13 12:56:09 +00:00
# ifdef SENSOR_VL53L1X
# ifndef WIRE_H
# include <Wire.h>
# define WIRE_H
# endif
# include <VL53L1X.h>
VL53L1X vl53l1x ;
bool vl53l1xinit_ok = false ;
2021-10-13 17:01:22 +00:00
struct sensordata dataVL53L1X ;
2021-10-13 12:56:09 +00:00
uint16_t value_vl53l1x_range ;
2021-10-13 17:01:22 +00:00
2021-10-13 12:56:09 +00:00
unsigned long lastread_vl53l1x = 0 ;
2021-10-13 17:01:22 +00:00
VL53L1X : : RangeStatus lastsentvalue_vl53l1x_status ;
2021-10-13 12:56:09 +00:00
# endif
2020-10-30 16:51:03 +00:00
# ifdef SENSOR_ANEMOMETER
2020-11-01 13:40:23 +00:00
//uses ATS177 Latched hall sensor for rotation sensing
2020-10-30 16:51:03 +00:00
sensordata dataAnemometer ;
unsigned long anemometer_lasttimereset = 0 ;
uint16_t anemometer_pulsecounter = 0 ; //counted pulses since last reset
2020-11-01 12:44:42 +00:00
# define ANEMOMETER_DEBOUNCETIME 15 //15ms between pulses is approx 85m/s windspeed
2020-11-01 11:05:32 +00:00
unsigned long anemometer_lastpulse_fordebounce = 0 ;
2020-10-30 16:51:03 +00:00
float value_anemometer = 0 ; // [m/s]
void ICACHE_RAM_ATTR interrupt_anemometer ( ) ;
void updateAnemometer ( ) ;
# endif
2020-11-01 12:44:42 +00:00
# ifdef SENSOR_RAINGAUGE
2020-11-01 13:40:23 +00:00
//uses ATS177 Latched Hall Sensor for rauge flip sensing
2020-11-01 12:44:42 +00:00
sensordata dataRaingauge ;
unsigned long raingauge_lasttimereset = 0 ;
uint16_t raingauge_pulsecounter = 0 ; //counted pulses since last reset
2020-11-13 15:12:19 +00:00
bool raingauge_idleflag = true ;
2020-11-01 12:44:42 +00:00
# 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 : 1000 mL - > 259 Flips
* Test2 : 1000 mL - > 256 in ca 10 min
* - > 3 , 9 mL per Flip , opening diameter = 113 mm - > A = 0 , 01002 8749
*/
void ICACHE_RAM_ATTR interrupt_raingauge ( ) ;
void updateRaingauge ( ) ;
# endif
2020-10-02 17:45:33 +00:00
// data/homie/config.json hochladen mit platformio run --target uploadfs
// config contains homie device name, mqtt ip and wifi credentials
2020-08-15 17:45:02 +00:00
2020-10-02 17:45:33 +00:00
HomieNode sensorNode ( " sensors " , " Sensors " , " sensors " ) ; //id, name, type
2020-08-15 17:45:02 +00:00
char tempstring [ 16 ] ; //for dtostrf
void loopHandler ( ) ;
2020-10-02 17:45:33 +00:00
void checkESPStatus ( ) ;
2020-08-15 17:45:02 +00:00
void setup ( ) {
Serial . begin ( 115200 ) ;
Serial . println ( ) ;
2020-10-02 17:45:33 +00:00
Serial . println ( " Booting " ) ;
2020-08-15 17:45:02 +00:00
2020-10-15 21:13:25 +00:00
delay ( 1000 ) ; //wait for sensors to get powered
2021-10-31 13:07:09 +00:00
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_DHT22
2021-10-31 13:07:09 +00:00
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 ) ;
2020-10-10 13:50:59 +00:00
# endif
# ifdef SENSOR_BMP180
2021-11-02 19:13:38 +00:00
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 ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-08-16 09:09:12 +00:00
2021-08-17 20:31:32 +00:00
# ifdef SENSOR_HTU21D
2021-11-03 18:03:28 +00:00
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 ) ;
2021-08-17 20:31:32 +00:00
# endif
2020-10-29 17:53:05 +00:00
# ifdef SENSOR_HS1101
2021-11-04 16:52:39 +00:00
sensor_hs1101 . init ( ) ;
sensor_hs1101 . setSettings ( SENSOR_HS1101_humidity_minchange , SENSOR_HS1101_humidity_senddelaymax , SENSOR_HS1101_humidity_readdelay ) ;
2020-10-29 17:53:05 +00:00
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_BH1750
2021-11-04 17:21:31 +00:00
sensor_bh1750 . init ( ) ;
2021-11-04 17:47:43 +00:00
sensor_bh1750 . setSettings ( SENSOR_BH1750_light_minchange , SENSOR_BH1750_light_senddelaymax , SENSOR_BH1750_light_readdelay ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-10-30 08:23:05 +00:00
# ifdef SENSOR_ML8511
2021-11-04 17:47:43 +00:00
sensor_ml8511 . init ( ) ;
sensor_ml8511 . setSettings ( SENSOR_ML8511_minchange , SENSOR_ML8511_senddelaymax , SENSOR_ML8511_readdelay ) ;
2020-10-30 08:23:05 +00:00
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_PIR
2020-10-10 13:50:59 +00:00
Serial . println ( " initializing pir " ) ;
2020-10-02 17:45:33 +00:00
pinMode ( PIRPIN , INPUT_PULLUP ) ;
2020-10-09 15:14:43 +00:00
# ifdef dataPIR_readdelay
dataPIR . readdelay = dataPIR_readdelay ;
# endif
# ifdef dataPIR_senddelaymax
dataPIR . senddelaymax = dataPIR_senddelaymax ;
# endif
2020-10-02 17:45:33 +00:00
# endif
2020-08-15 17:45:02 +00:00
2021-07-14 19:09:23 +00:00
# ifdef SENSOR_RADAR
Serial . println ( " initializing radar " ) ;
pinMode ( RADARPIN , INPUT ) ;
# ifdef dataRADAR_readdelay
dataRADAR . readdelay = dataRADAR_readdelay ;
# endif
# ifdef dataRADAR_senddelaymax
dataRADAR . senddelaymax = dataRADAR_senddelaymax ;
# endif
# endif
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_LDR
Serial . println ( " initializing ldr " ) ;
2020-10-14 21:32:25 +00:00
pinMode ( LDR_PIN , INPUT ) ; //ldr
# ifdef dataLDR_readdelay
dataLDR . readdelay = dataLDR_readdelay ;
# endif
# ifdef dataLDR_senddelaymax
dataLDR . senddelaymax = dataLDR_senddelaymax ;
# endif
# ifdef dataLDR_minchange
dataLDR . minchange = dataLDR_minchange ;
# endif
# endif
# ifdef SENSOR_MHZ19
Serial . println ( " initializing mhz19 " ) ;
# ifdef dataMHZ19_minchange
dataMHZ19 . minchange = dataMHZ19_minchange ;
# endif
# ifdef dataMHZ19_readdelay
dataMHZ19 . readdelay = dataMHZ19_readdelay ;
# endif
mhz19_swSerial . begin ( BAUD_RATE_MHZ19 , SWSERIAL_8N1 , MHZ19_SERIAL_RX , MHZ19_SERIAL_TX , false , 256 ) ;
mhz19 . setSerial ( & mhz19_swSerial ) ;
2020-10-15 21:13:25 +00:00
uint8_t mhz19abctries = 10 ;
while ( ! mhz19 . disableABC ( ) & & mhz19abctries > 0 ) { //disable automatic baseline correction (abc does calibration every 24h -> needs to have 400ppm co2 level sometime during that time)
delay ( 500 ) ; //wait some time for mhz to be initialized
Serial . print ( " disableABC Failed! try= " ) ; Serial . println ( mhz19abctries ) ;
mhz19abctries - - ;
}
if ( mhz19abctries > 0 ) {
Serial . println ( " mhz19 abc disabled successfully " ) ;
}
2020-12-31 16:47:13 +00:00
2020-10-10 13:50:59 +00:00
# endif
2020-12-31 16:47:13 +00:00
2020-10-23 07:14:43 +00:00
# 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
2020-10-23 21:09:01 +00:00
# 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
2020-11-01 12:14:38 +00:00
# ifdef dataTCS34725_lux_senddelaymax
dataTCS34725_lux . senddelaymax = dataTCS34725_lux_senddelaymax ;
# endif
2020-10-23 21:09:01 +00:00
# ifdef dataTCS34725_colortemp_minchange
dataTCS34725_colortemp . minchange = dataTCS34725_colortemp_minchange ;
# endif
# endif
2021-10-13 12:56:09 +00:00
# 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 ) ;
2021-10-13 17:01:22 +00:00
vl53l1x . startContinuous ( 1000 ) ; //This period should be at least as long as the timing budget.
2021-10-13 12:56:09 +00:00
}
2021-10-13 17:01:22 +00:00
# ifdef dataVL53L1X_minchange
dataVL53L1X . minchange = dataVL53L1X_minchange ;
# endif
# ifdef dataVL53L1X_senddelaymax
dataVL53L1X . senddelaymax = dataVL53L1X_senddelaymax ;
# endif
# ifdef dataVL53L1X_readdelay
dataVL53L1X . readdelay = dataVL53L1X_readdelay ;
2021-10-13 12:56:09 +00:00
# endif
# endif
2020-10-30 16:51:03 +00:00
# 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
2020-11-01 12:44:42 +00:00
# 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
2020-10-30 16:51:03 +00:00
# endif
2020-12-31 16:47:13 +00:00
// ##### Advertise topics below here #####
2020-08-15 17:45:02 +00:00
2020-10-23 20:13:32 +00:00
//Homie_setFirmware(FW_NAME, FW_VERSION);
//Homie_setBrand(FW_NAME);
2020-08-15 17:45:02 +00:00
Homie_setFirmware ( FW_NAME , FW_VERSION ) ;
Homie . setLoopFunction ( loopHandler ) ;
2020-12-31 16:47:13 +00:00
# ifdef STATUSNODE
//to return some stuff about status, errors etc.
Serial . println ( " Using status node " ) ;
sensorNode . advertise ( " status " ) ;
# endif
2020-08-15 17:45:02 +00:00
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_DHT22
2021-10-31 13:07:09 +00:00
sensor_dht22 . advertise ( sensorNode ) ;
2020-10-02 17:45:33 +00:00
# endif
2021-11-02 19:13:38 +00:00
# ifdef SENSOR_BMP180
sensor_bmp180 . advertise ( sensorNode ) ;
# endif
2021-11-03 18:03:28 +00:00
# ifdef SENSOR_HTU21D
sensor_htu21d . advertise ( sensorNode ) ;
# endif
2020-10-29 17:53:05 +00:00
# ifdef SENSOR_HS1101
2021-11-04 16:52:39 +00:00
sensor_hs1101 . advertise ( sensorNode ) ;
2020-10-29 17:53:05 +00:00
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_BH1750
2021-11-04 17:21:31 +00:00
sensor_bh1750 . advertise ( sensorNode ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-10-30 08:23:05 +00:00
# ifdef SENSOR_ML8511
2021-11-04 17:47:43 +00:00
sensor_ml8511 . advertise ( sensorNode ) ;
2020-10-30 08:23:05 +00:00
# endif
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_LDR
sensorNode . advertise ( " light " ) ;
analogRead ( LDR_PIN ) ; //first reading could be false
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_PIR
2020-10-02 21:25:33 +00:00
sensorNode . advertise ( " motion " ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-10-10 13:50:59 +00:00
2021-07-14 19:09:23 +00:00
# ifdef SENSOR_RADAR
sensorNode . advertise ( " radar " ) ;
# endif
2020-10-14 21:32:25 +00:00
2021-11-03 18:03:28 +00:00
2021-08-17 20:31:32 +00:00
2020-10-14 21:32:25 +00:00
# ifdef SENSOR_MHZ19
sensorNode . advertise ( " co2 " ) ;
2020-12-31 16:47:13 +00:00
# ifdef MHZ19CALIBRATIONTOPIC
sensorNode . advertise ( " mhz19calibration " ) . settable ( mhz19calibrationHandler ) ;
# endif
2020-10-14 21:32:25 +00:00
# endif
2020-10-23 07:14:43 +00:00
# ifdef SENSOR_SDS018
sensorNode . advertise ( " dust_pm25 " ) ;
sensorNode . advertise ( " dust_pm10 " ) ;
# endif
2020-10-23 21:09:01 +00:00
# ifdef SENSOR_TCS34725
# if defined(SENSOR_LDR) || defined(SENSOR_BH1750)
sensorNode . advertise ( " light_tcs " ) ;
# else
sensorNode . advertise ( " light " ) ;
# endif
sensorNode . advertise ( " colortemp " ) ;
# endif
2020-10-30 16:51:03 +00:00
2021-10-13 12:56:09 +00:00
# ifdef SENSOR_VL53L1X
2021-10-13 17:01:22 +00:00
sensorNode . advertise ( " tofstatus " ) ;
sensorNode . advertise ( " tofrange " ) ;
sensorNode . advertise ( " tofpeaksignal " ) ;
sensorNode . advertise ( " tofambient " ) ;
2021-10-13 12:56:09 +00:00
# endif
2020-10-30 16:51:03 +00:00
# ifdef SENSOR_ANEMOMETER
sensorNode . advertise ( " windspeed " ) ;
# endif
2020-11-01 12:44:42 +00:00
# ifdef SENSOR_RAINGAUGE
sensorNode . advertise ( " rain " ) ;
# endif
2020-08-15 17:45:02 +00:00
2020-10-10 13:50:59 +00:00
Serial . println ( " connecting.. " ) ;
2020-08-15 17:45:02 +00:00
Homie . setup ( ) ;
2020-10-10 13:50:59 +00:00
Serial . println ( " " ) ;
2020-08-15 17:45:02 +00:00
Serial . println ( " connected " ) ; //wird nicht ausgegeben. keine ahnung warum.
}
void loop ( ) {
Homie . loop ( ) ;
}
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_LDR
void loop_LDR ( )
{
sensordata & d = dataLDR ;
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
value_ldr = get_lux ( in_ldr , out_ldr , LDRARRAYSIZE ) / 10.0 ; //read light level in lux
if ( fabs ( d . lastsentvalue - value_ldr ) > = d . minchange ) {
_changed = true ;
}
d . lastreadtime = millis ( ) ;
}
if ( _changed | | millis ( ) > = ( d . lastsent + d . senddelaymax ) ) {
Serial . print ( " Sending LDR. reason= " ) ;
if ( _changed ) Serial . println ( " change " ) ; else Serial . println ( " time " ) ;
checkESPStatus ( ) ;
Homie . getLogger ( ) < < " light " < < " : " < < value_ldr < < endl ;
sensorNode . setProperty ( " light " ) . send ( String ( value_ldr ) ) ;
d . lastsentvalue = value_ldr ;
d . lastsent = millis ( ) ;
}
}
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_PIR
void loop_PIR ( )
{
2020-10-02 21:25:33 +00:00
sensordata & d = dataPIR ;
2020-10-02 18:28:14 +00:00
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
2020-10-02 21:25:33 +00:00
if ( digitalRead ( PIRPIN ) ! = value_PIR ) {
2020-10-02 18:28:14 +00:00
_changed = true ;
2020-08-15 17:45:02 +00:00
}
2020-10-02 18:28:14 +00:00
d . lastreadtime = millis ( ) ;
2020-08-15 17:45:02 +00:00
}
2020-10-02 18:28:14 +00:00
if ( _changed | | millis ( ) > = ( d . lastsent + d . senddelaymax ) ) { //send current value after some long time
2020-10-02 21:25:33 +00:00
Serial . print ( " Sending motion. reason= " ) ;
if ( _changed ) Serial . println ( " change " ) ; else Serial . println ( " time " ) ;
2020-10-01 20:19:11 +00:00
if ( digitalRead ( PIRPIN ) ) {
2020-10-02 21:25:33 +00:00
Homie . getLogger ( ) < < " motion " < < " : " < < " true " < < endl ;
sensorNode . setProperty ( " motion " ) . send ( String ( " true " ) ) ;
value_PIR = true ;
2020-10-01 20:19:11 +00:00
} else {
2020-10-02 21:25:33 +00:00
Homie . getLogger ( ) < < " motion " < < " : " < < " false " < < endl ;
sensorNode . setProperty ( " motion " ) . send ( String ( " false " ) ) ;
value_PIR = false ;
2020-10-01 20:19:11 +00:00
}
2020-10-02 18:28:14 +00:00
d . lastsent = millis ( ) ;
2020-10-01 20:19:11 +00:00
}
2020-10-02 17:45:33 +00:00
}
# endif
2020-08-15 17:45:02 +00:00
2021-07-14 19:09:23 +00:00
# ifdef SENSOR_RADAR
void loop_RADAR ( )
{
sensordata & d = dataRADAR ;
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
if ( digitalRead ( RADARPIN ) ! = value_RADAR ) {
_changed = true ;
}
d . lastreadtime = millis ( ) ;
}
if ( _changed | | millis ( ) > = ( d . lastsent + d . senddelaymax ) ) { //send current value after some long time
Serial . print ( " Sending motion radar. reason= " ) ;
if ( _changed ) Serial . println ( " change " ) ; else Serial . println ( " time " ) ;
if ( digitalRead ( RADARPIN ) ) {
Homie . getLogger ( ) < < " radar " < < " : " < < " true " < < endl ;
sensorNode . setProperty ( " radar " ) . send ( String ( " true " ) ) ;
value_RADAR = true ;
} else {
Homie . getLogger ( ) < < " motion " < < " : " < < " false " < < endl ;
sensorNode . setProperty ( " radar " ) . send ( String ( " false " ) ) ;
value_RADAR = false ;
}
d . lastsent = millis ( ) ;
}
}
# endif
2020-10-14 21:32:25 +00:00
# ifdef SENSOR_MHZ19
void loop_MHZ19 ( )
{
sensordata & d = dataMHZ19 ;
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
mhz19_ready = mhz19 . isReady ( ) ;
2020-10-22 21:00:33 +00:00
//value_co2=mhz19.readValue(); //[ppm]
value_co2 = mhz19_readValue_reimplemented ( & mhz19_swSerial , & mhz19 ) ; //[ppm] reimplemented function to fix no response issue
Homie . getLogger ( ) < < " read co2 " < < " : " < < value_co2 < < " status= " < < mhz19_ready < < endl ;
2020-10-14 21:32:25 +00:00
if ( fabs ( d . lastsentvalue - value_co2 ) > = d . minchange ) {
_changed = true ;
}
d . lastreadtime = millis ( ) ;
}
if ( _changed | | millis ( ) > = ( d . lastsent + d . senddelaymax ) ) {
Serial . print ( " Sending MHZ19. reason= " ) ;
if ( _changed ) Serial . println ( " change " ) ; else Serial . println ( " time " ) ;
checkESPStatus ( ) ;
Homie . getLogger ( ) < < " co2 " < < " : " < < value_co2 < < endl ;
if ( mhz19_ready ) { //send no co2 values if not warmed up. can take several miniutes
sensorNode . setProperty ( " co2 " ) . send ( String ( value_co2 ) ) ;
} else {
Homie . getLogger ( ) < < " co2 not ready. didnt sent " < < endl ;
}
d . lastsentvalue = value_co2 ;
d . lastsent = millis ( ) ;
}
}
# endif
2020-10-23 07:14:43 +00:00
# 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 ( ) ;
2020-08-15 17:45:02 +00:00
2020-10-23 07:14:43 +00:00
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
2020-10-10 13:50:59 +00:00
2020-10-23 21:09:01 +00:00
# ifdef SENSOR_TCS34725
void loop_TCS34725_lux ( )
{
sensordata & d = dataTCS34725_lux ;
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
2020-12-26 11:29:32 +00:00
if ( millis ( ) > = ( lastread_tcs34725 + d . readdelay ) ) { //avoid reading sensor twice in a short time
2020-11-01 11:24:34 +00:00
//tcs.getRawData(&value_tcs_r, &value_tcs_g, &value_tcs_b, &value_tcs_c);
tcs . getData ( ) ;
2020-12-26 11:29:32 +00:00
lastread_tcs34725 = millis ( ) ;
2020-11-01 11:24:34 +00:00
if ( tcs . isSaturated ) {
Serial . println ( " Warning: tcs34725 is saturated " ) ;
2020-12-31 16:47:13 +00:00
# ifdef STATUSNODE
sensorNode . setProperty ( " status " ) . send ( " TCS34725 is saturated " ) ;
# endif
2020-11-01 11:24:34 +00:00
}
2020-10-23 21:09:01 +00:00
}
2020-11-01 11:24:34 +00:00
//value_tcs_lux = tcs.calculateLux(value_tcs_r, value_tcs_g, value_tcs_b);
2020-12-26 11:40:53 +00:00
uint16_t _value_tcs_lux = tcs . lux * TCS34725_LUXFACTOR ;
2021-01-27 21:57:03 +00:00
if ( ! tcs . isSaturated & & _value_tcs_lux < 65535 ) { //sometimes false high reading accur around 65535 sometimes less. with isSaturated check only 65535 values appeared.
2020-12-26 11:40:53 +00:00
value_tcs_lux = _value_tcs_lux ;
}
2020-10-23 21:09:01 +00:00
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 ) ) {
2020-12-26 11:29:32 +00:00
if ( millis ( ) > = ( lastread_tcs34725 + d . readdelay ) ) { //avoid reading sensor twice in a short time
2020-11-01 11:24:34 +00:00
//tcs.getRawData(&value_tcs_r, &value_tcs_g, &value_tcs_b, &value_tcs_c);
tcs . getData ( ) ;
2020-12-26 11:29:32 +00:00
lastread_tcs34725 = millis ( ) ;
2020-11-01 11:24:34 +00:00
if ( tcs . isSaturated ) {
Serial . println ( " Warning: tcs34725 is saturated " ) ;
}
2020-10-23 21:09:01 +00:00
}
// colorTemp = tcs.calculateColorTemperature(r, g, b);
2020-11-01 11:24:34 +00:00
//value_colortemp = tcs.calculateColorTemperature_dn40(value_tcs_r, value_tcs_g, value_tcs_b, value_tcs_c);
2020-12-26 11:40:53 +00:00
if ( ! tcs . isSaturated ) {
value_colortemp = tcs . ct ; //with agc
}
2020-10-23 21:09:01 +00:00
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 ;
2020-11-01 11:28:45 +00:00
if ( tcs . lux > = TCS34725_MINLUXFORCT ) {
2020-11-01 12:14:38 +00:00
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 ;
2020-11-01 19:20:03 +00:00
sensorNode . setProperty ( " colortemp " ) . send ( String ( - 1 ) ) ;
2020-11-01 12:14:38 +00:00
}
2020-11-01 11:28:45 +00:00
} else {
2020-11-01 12:14:38 +00:00
Homie . getLogger ( ) < < " didn't send tcs ct because light too low: " < < tcs . lux < < " lux " < < endl ;
2020-11-01 19:20:03 +00:00
sensorNode . setProperty ( " colortemp " ) . send ( String ( - 1 ) ) ;
2020-11-01 11:28:45 +00:00
}
2020-10-23 21:09:01 +00:00
d . lastsentvalue = value_colortemp ;
d . lastsent = millis ( ) ;
}
}
# endif
2020-10-10 13:50:59 +00:00
2021-10-13 12:56:09 +00:00
# ifdef SENSOR_VL53L1X
2021-10-13 17:01:22 +00:00
void loop_VL53L1X ( )
2021-10-13 12:56:09 +00:00
{
2021-10-13 17:01:22 +00:00
sensordata & d = dataVL53L1X ;
2021-10-13 12:56:09 +00:00
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 ;
2021-10-13 17:01:22 +00:00
/* for debugging
2021-10-13 12:56:09 +00:00
Serial . print ( " range: " ) ;
Serial . print ( vl53l1x . ranging_data . range_mm ) ;
Serial . print ( " \t status: " ) ;
Serial . print ( VL53L1X : : rangeStatusToString ( vl53l1x . ranging_data . range_status ) ) ;
2021-10-13 17:01:22 +00:00
Serial . print ( " \t status= " ) ;
Serial . print ( vl53l1x . ranging_data . range_status ) ;
2021-10-13 12:56:09 +00:00
Serial . print ( " \t peak signal: " ) ;
Serial . print ( vl53l1x . ranging_data . peak_signal_count_rate_MCPS ) ;
Serial . print ( " \t ambient: " ) ;
Serial . print ( vl53l1x . ranging_data . ambient_count_rate_MCPS ) ;
2021-10-13 17:01:22 +00:00
Serial . println ( ) ;
*/
2021-10-13 12:56:09 +00:00
if ( abs ( ( int ) d . lastsentvalue - value_vl53l1x_range ) > = d . minchange ) { //int abs
_changed = true ;
}
2021-10-13 17:01:22 +00:00
if ( lastsentvalue_vl53l1x_status ! = vl53l1x . ranging_data . range_status ) { //sensor status changed
_changed = true ;
}
2021-10-13 12:56:09 +00:00
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 ;
2021-10-13 17:01:22 +00:00
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 ) ) ;
2021-10-13 12:56:09 +00:00
d . lastsentvalue = value_vl53l1x_range ;
2021-10-13 17:01:22 +00:00
lastsentvalue_vl53l1x_status = vl53l1x . ranging_data . range_status ;
2021-10-13 12:56:09 +00:00
d . lastsent = millis ( ) ;
}
}
# endif
2020-10-30 16:51:03 +00:00
# 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
2020-11-01 12:44:42 +00:00
# ifdef SENSOR_RAINGAUGE
void loop_raingauge ( )
{
sensordata & d = dataRaingauge ;
bool _changed = false ;
if ( millis ( ) > = ( d . lastreadtime + d . readdelay ) ) {
2020-11-13 15:12:19 +00:00
if ( millis ( ) - raingauge_lasttimereset > d . senddelaymax ) {
raingauge_idleflag = true ; //raingauge didn't flip for a long time
}
2020-11-01 12:44:42 +00:00
if ( raingauge_pulsecounter > 0 ) { //if rg flipped
2020-11-13 15:12:19 +00:00
if ( raingauge_idleflag ) { //last flip is before reset time
2020-11-01 12:44:42 +00:00
value_raingauge = raingauge_pulsecounter * RAINGAUGE_FLIPAMOUNT ; //set to fixed amount if flip was exactly at that time
2020-11-13 15:12:19 +00:00
raingauge_idleflag = false ;
2020-11-01 12:44:42 +00:00
} else {
value_raingauge = 3600000 / ( millis ( ) - raingauge_lasttimereset ) / raingauge_pulsecounter * RAINGAUGE_FLIPAMOUNT ;
2020-11-13 15:12:19 +00:00
raingauge_idleflag = false ;
2020-11-01 12:44:42 +00:00
}
_changed = true ;
}
2020-11-01 19:20:03 +00:00
2020-11-01 12:44:42 +00:00
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
2020-08-15 17:45:02 +00:00
2020-10-02 17:45:33 +00:00
void loopHandler ( ) {
2021-10-31 13:07:09 +00:00
checkESPStatus ( ) ;
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_DHT22
2021-11-02 17:51:55 +00:00
sensor_dht22 . sensorloop ( ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_BMP180
2021-11-02 19:13:38 +00:00
sensor_bmp180 . sensorloop ( ) ;
2020-10-10 13:50:59 +00:00
# endif
2021-08-17 20:31:32 +00:00
# ifdef SENSOR_HTU21D
2021-11-03 18:03:28 +00:00
sensor_htu21d . sensorloop ( ) ;
2021-08-17 20:31:32 +00:00
# endif
2020-10-29 17:53:05 +00:00
# ifdef SENSOR_HS1101
2021-11-04 16:52:39 +00:00
sensor_hs1101 . sensorloop ( ) ;
2020-10-29 17:53:05 +00:00
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_BH1750
2021-11-04 17:21:31 +00:00
sensor_bh1750 . sensorloop ( ) ;
2020-10-02 17:45:33 +00:00
# endif
2020-10-30 08:23:05 +00:00
# ifdef SENSOR_ML8511
2021-11-04 17:47:43 +00:00
sensor_ml8511 . sensorloop ( ) ;
2020-10-30 08:23:05 +00:00
# endif
2020-10-10 13:50:59 +00:00
# ifdef SENSOR_LDR
loop_LDR ( ) ;
# endif
2020-10-02 17:45:33 +00:00
# ifdef SENSOR_PIR
loop_PIR ( ) ;
# endif
2020-08-15 17:45:02 +00:00
2021-07-14 19:09:23 +00:00
# ifdef SENSOR_RADAR
loop_RADAR ( ) ;
# endif
2020-10-14 21:32:25 +00:00
# ifdef SENSOR_MHZ19
loop_MHZ19 ( ) ;
# endif
2020-10-23 07:14:43 +00:00
# ifdef SENSOR_SDS018
loop_SDS018_pm25 ( ) ;
loop_SDS018_pm10 ( ) ;
# endif
2020-08-15 17:45:02 +00:00
2020-10-23 21:09:01 +00:00
# ifdef SENSOR_TCS34725
if ( tcs34725init_ok ) {
loop_TCS34725_lux ( ) ;
loop_TCS34725_colortemp ( ) ;
}
# endif
2021-10-13 17:01:22 +00:00
# ifdef SENSOR_VL53L1X
if ( vl53l1xinit_ok ) {
loop_VL53L1X ( ) ;
}
# endif
2020-10-30 16:51:03 +00:00
# ifdef SENSOR_ANEMOMETER
loop_anemometer ( ) ;
# endif
2020-08-15 17:45:02 +00:00
2020-11-01 12:44:42 +00:00
# ifdef SENSOR_RAINGAUGE
2020-11-01 13:40:23 +00:00
loop_raingauge ( ) ;
2020-11-01 12:44:42 +00:00
# endif
2020-10-02 17:45:33 +00:00
}
2020-08-15 17:45:02 +00:00
2020-10-02 17:45:33 +00:00
void checkESPStatus ( )
{
if ( WiFi . status ( ) ! = WL_CONNECTED ) //restart if wifi signal loss
{
ESP . reset ( ) ;
2020-08-15 17:45:02 +00:00
}
}
2020-10-10 13:50:59 +00:00
//////////////////////////////////////////////////////////////////////////////
// Calculate lux based on rawADC reading from LDR returns value in lux/10
//////////////////////////////////////////////////////////////////////////////
//quelle: https://groups.google.com/forum/#!topic/souliss/1kMAltPB2ME[1-25]
2020-10-14 21:32:25 +00:00
# ifdef SENSOR_LDR
2020-10-10 13:50:59 +00:00
int get_lux ( const unsigned int * _in , const unsigned int * _out , byte size )
{
// take care the value is within range
// val = constrain(val, _in[0], _in[size-1]);
unsigned int val = analogRead ( LDR_PIN ) ;
# ifdef DEBUG //DEBUG++++++++++++++++
Serial . print ( " LDR RAW=: " ) ;
Serial . println ( val ) ;
# endif
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 ] ) ;
2020-10-14 21:32:25 +00:00
}
2020-10-22 21:00:33 +00:00
# endif
# ifdef SENSOR_MHZ19
byte mhz19_getCheckSum ( byte * packet ) {
byte checksum = 0 ;
for ( uint8_t i = 1 ; i < 8 ; i + + ) {
checksum + = packet [ i ] ;
}
checksum = 0xff - checksum ;
checksum + = 1 ;
return checksum ;
}
int mhz19_readValue_reimplemented ( Stream * _streamRef , MHZ19 * _mhz19Ref ) { //same function as in mhz19 library from klevytskyi, but with delay between cmd send and response check
byte CMD_READ [ 9 ] = { 0xFF , 0x01 , 0x86 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x79 } ; // Read command
unsigned int co2 = - 1 ;
unsigned char response [ 9 ] ;
_streamRef - > write ( CMD_READ , 9 ) ;
unsigned long _startwait = millis ( ) ;
while ( millis ( ) - _startwait < 100 ) { //wait for mhz19 to send response
//wait
}
if ( _streamRef - > available ( ) ) {
_streamRef - > readBytes ( response , 9 ) ;
byte crc = mhz19_getCheckSum ( response ) ;
if ( response [ 0 ] = = 0xFF & & response [ 1 ] = = CMD_READ [ 2 ] & & response [ 8 ] = = crc ) {
unsigned int responseHigh = ( unsigned int ) response [ 2 ] ;
unsigned int responseLow = ( unsigned int ) response [ 3 ] ;
unsigned int ppm = ( 256 * responseHigh ) + responseLow ;
co2 = ppm ;
}
}
return co2 ;
}
2020-10-23 07:14:43 +00:00
# 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 ( " \n PM10 : " ) ;
Serial . print ( pm10 ) ;
Serial . println ( ) ; */
}
}
sds018_swSerial . flush ( ) ;
}
}
2020-10-29 17:53:05 +00:00
# endif
2020-10-30 08:23:05 +00:00
2020-10-29 17:53:05 +00:00
2020-10-30 16:51:03 +00:00
# ifdef SENSOR_ANEMOMETER
void ICACHE_RAM_ATTR interrupt_anemometer ( )
{
2020-11-01 11:05:32 +00:00
if ( millis ( ) - anemometer_lastpulse_fordebounce > = ANEMOMETER_DEBOUNCETIME ) { //ignore if pulse came too fast
anemometer_pulsecounter + + ;
anemometer_lastpulse_fordebounce = millis ( ) ;
2020-11-01 12:44:42 +00:00
}
}
# 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 ( ) ;
2020-11-01 11:05:32 +00:00
}
2020-10-30 16:51:03 +00:00
}
# endif
2020-12-31 16:47:13 +00:00
/* #################################
* # # # # # # # # # # # topic handler # # # # # # #
*/
# ifdef MHZ19CALIBRATIONTOPIC
bool mhz19calibrationHandler ( const HomieRange & range , const String & value ) {
if ( range . isRange ) {
return false ; //if range is given but index is not in allowed range
}
Homie . getLogger ( ) < < " mhz19 calibration " < < " : " < < value < < endl ;
if ( value = = " zero " ) {
mhz19 . calibrateZero ( ) ;
Homie . getLogger ( ) < < " mhz19 calibration " < < " : " < < value < < endl ;
# ifdef STATUSNODE
sensorNode . setProperty ( " status " ) . send ( " MHZ19 Zero Calibration triggered " ) ;
# endif
} else {
Homie . getLogger ( ) < < " Value outside range " < < endl ;
return false ;
}
return true ;
}
# endif
2020-10-30 16:51:03 +00:00
2020-10-30 08:23:05 +00:00
/*##################################
* # # # # # # # # HELPER FUNCTIONS # # # # # # # #
*/
2020-10-29 17:53:05 +00:00
//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 ] ) ;
}
2020-10-30 08:23:05 +00:00
//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 ;
}