diff --git a/include/ec.h b/include/ec.h index 17710b5..9957685 100644 --- a/include/ec.h +++ b/include/ec.h @@ -6,6 +6,10 @@ bool ec_flag_measurement_available=false; +#define EC_ADC_UNAVAILABLE 0 +#define EC_UNAVAILABLE -1 + + #define EC_PIN_RELAY_PROBE 27 @@ -16,7 +20,7 @@ bool ec_flag_measurement_available=false; #define EC_RESOLUTION 8 #define EC_FREQUENCY 5000 -#define EC_CALIB_ARRAY_SIZE 256 +#define EC_CALIB_ARRAY_SIZE 128 uint16_t ec_calib_array[EC_CALIB_ARRAY_SIZE]; uint16_t ec_calib_array_pos=0; #define EC_CALIB_READ_INTERVAL 250 //interval of reading adc value inside a measurement @@ -46,8 +50,10 @@ float ec_calib_adc; float ec; //ec value after adjustment for reference (at current temperature) float ec25; //ec value but temperature adjusted for 25 degC -float ec_tempadjust_alpa=0.2; //TODO +float ec_tempadjust_alpa=0.02; float ec_reference_adc=6016.88; //adc reference value for the calibration resistor measurement. +//EC short circuit adc value: 17497 (for connection restistance testing) +//EC open circuit adc value: 738 //x^0*p[0] + ... + x^n*p[n] //float ec_calibration_polynom[]={691.5992624638029,-1.4015367296761692,0.0008513503472324141,-2.2140576823179093e-07,2.8962580780180067e-11,-1.8577565383307114e-15,4.7162479484903865e-20}; @@ -62,6 +68,7 @@ void ec_setRange(uint8_t range); void ec_connectProbe(bool); void ec_releaseRelay(); float ec_getECfromADC(float adc); +float ec_calculateEC25(float pEC,float pTemp); void ec_setup() { ledcSetup(EC_PWM_CH, EC_FREQUENCY, EC_RESOLUTION); @@ -93,10 +100,16 @@ void ec_loop(unsigned long loopmillis) { if (ec_measurementReady()) { ec_releaseRelay(); ec_adc=getMean(ec_array,EC_ARRAY_SIZE); - if (isValueArrayOK(ec_calib_array,EC_CALIB_ARRAY_SIZE,0)){ + if (isValueArrayOK(ec_calib_array,EC_CALIB_ARRAY_SIZE,EC_ADC_UNAVAILABLE)){ ec_calib_adc=getMean(ec_calib_array,EC_CALIB_ARRAY_SIZE); ec_adc_adjusted=mapf(ec_adc,0,ec_calib_adc,0,ec_reference_adc); ec=ec_getECfromADC(ec_adc_adjusted); + ec25=ec_calculateEC25(ec,tempC_reservoir); + }else{ + ec_calib_adc=EC_ADC_UNAVAILABLE; + ec_adc_adjusted=EC_ADC_UNAVAILABLE; + ec=EC_UNAVAILABLE; + ec25=EC_UNAVAILABLE; } ec_flag_measurement_available=true; @@ -189,5 +202,10 @@ float ec_getECfromADC(float adc) { return _ec; } +float ec_calculateEC25(float pEC,float pTemp) +{ + return pEC/(1.0+ec_tempadjust_alpa*(pTemp-25.0)); +} + #endif \ No newline at end of file diff --git a/include/flow.h b/include/flow.h index 2ce4b6b..d60a18f 100644 --- a/include/flow.h +++ b/include/flow.h @@ -5,7 +5,7 @@ uint16_t flow_counter=0; //maximum counts/s measured with Eden 128 Pump was 171 void IRAM_ATTR isr_flow(); unsigned long last_read_flow=0; -#define READINTERVAL_FLOW 1000 +#define READINTERVAL_FLOW 2000 float flow_factor=7.5; //F=7.5*flowrate[L/min] float flow; diff --git a/include/soilmoisture.h b/include/soilmoisture.h index 81eae04..503fa31 100644 --- a/include/soilmoisture.h +++ b/include/soilmoisture.h @@ -2,25 +2,95 @@ #define _SOILMOISTURE_H_ #define SM1_ADS_CHANNEL 1 +#define SM2_ADS_CHANNEL 2 +#define SM3_ADS_CHANNEL 3 #define READINTERVAL_SM 100 + +//Calibration values +//high=adc value for sensor in air +//low=adc value for sensor in NaCl solution at 25°C with 12880 uS/cm +float sm1_low=45555; +float sm1_high=11799; +float sm2_low=3235; +float sm2_high=16050; +float sm3_low=0; +float sm3_high=16000; +//sm1 is underwater reservoir soilmoisture sensor (#2) +//sm2 is soilmoisture sensor (#1) + + unsigned long last_read_sm=0; #define SM_SIZE 16 uint8_t sm_mean_pos=0; -uint16_t sm_mean[SM_SIZE]; +uint16_t sm_mean1array[SM_SIZE]; +uint16_t sm_mean2array[SM_SIZE]; +uint16_t sm_mean3array[SM_SIZE]; +#define SM_DISCONNECTED -1 + +float sm_mean1=SM_DISCONNECTED; +float sm_mean2=SM_DISCONNECTED; +float sm_mean3=SM_DISCONNECTED; + + + +uint8_t sm_readchannel=0; + + +void sm_setup() { + for (uint16_t i=0;i=last_read_sm+READINTERVAL_SM) { - last_read_sm=loopmillis; + + switch (sm_readchannel) { + case 0: + sm_mean1array[sm_mean_pos]=ADS.readADC(SM1_ADS_CHANNEL); + sm_readchannel++; - uint16_t value = ADS.readADC(SM1_ADS_CHANNEL); - sm_mean[sm_mean_pos]=value; - sm_mean_pos++; - sm_mean_pos%=SM_SIZE; + break; + case 1: + sm_mean2array[sm_mean_pos]=ADS.readADC(SM2_ADS_CHANNEL); + sm_readchannel++; + + break; + + default: //2 and above + + sm_mean3array[sm_mean_pos]=ADS.readADC(SM3_ADS_CHANNEL); + sm_readchannel=0; + + sm_mean_pos++; + sm_mean_pos%=SM_SIZE; + last_read_sm=loopmillis; + + + + if (isValueArrayOK(sm_mean1array,SM_SIZE,SM_DISCONNECTED)){ + float _sm_mean_raw; + _sm_mean_raw=getMean(sm_mean1array,SM_SIZE); + sm_mean1=mapf(_sm_mean_raw,sm1_low,sm1_high,1.0,0.0); + + _sm_mean_raw=getMean(sm_mean2array,SM_SIZE); + sm_mean2=mapf(_sm_mean_raw,sm2_low,sm2_high,1.0,0.0); + + _sm_mean_raw=getMean(sm_mean3array,SM_SIZE); + sm_mean3=mapf(_sm_mean_raw,sm3_low,sm3_high,1.0,0.0); + } + + break; + } //Serial.print(getMean(sm_mean,SM_SIZE)); Serial.print("\t "); Serial.println(value); } diff --git a/include/temperature.h b/include/temperature.h index e59534d..e1cd37e 100644 --- a/include/temperature.h +++ b/include/temperature.h @@ -25,30 +25,34 @@ DallasTemperature sensors(&oneWire); uint16_t tempCmean_pos=0; // arrays to hold device addresses DeviceAddress thermometerReservoir={0x28,0xFF,0x30,0xBA,0x85,0x16,0x03,0xB5}; -float tempC_reservoir; -float tempCmean_reservoir[TEMPMEAN_SIZE]; +float tempC_reservoir; //last reading +float tempCmean_reservoir_array[TEMPMEAN_SIZE]; +float tempCmean_reservoir=DEVICE_DISCONNECTED_C; + + DeviceAddress thermometerAir={0x28,0xFF,0x6C,0x1C,0x72,0x16,0x05,0x8B}; -float tempC_air; -float tempCmean_air[TEMPMEAN_SIZE]; +float tempC_air; //last reading +float tempCmean_air_array[TEMPMEAN_SIZE]; +float tempCmean_air=DEVICE_DISCONNECTED_C; void temperature_setup() { //initialize mean array for (uint16_t i=0;i=last_read_hcsr04+READINTERVAL_HCSR04) { last_read_hcsr04=loopmillis; float temperature=20.0; - if (tempC_air!=DEVICE_DISCONNECTED_C && isValueArrayOKf(tempCmean_air,TEMPMEAN_SIZE,DEVICE_DISCONNECTED_C)) { //sensor ok - temperature=getMeanf(tempCmean_air,TEMPMEAN_SIZE); + if (tempCmean_air!=DEVICE_DISCONNECTED_C) { //sensor ok + temperature=tempCmean_air; } double* distances = HCSR04.measureDistanceMm(temperature); + double distance=distances[0]; + //Serial.print("Distance reading:"); Serial.println(distance); + + if (distance!=WATERLEVEL_UNAVAILABLE) { //successful + waterlevelMean_array[waterlevelMean_array_pos]=distance; + waterlevelMean_array_pos++; + waterlevelMean_array_pos%=WATERLEVELMEAN_SIZE; + if (waterlevel_failcounter>0) { //reduce failcounter if sucessfull + waterlevel_failcounter--; + } + }else{ + if (waterlevel_failcounter=WATERLEVEL_FAILTHRESHOLD) { //too many failed readings + waterlevel=-1; + /*if (debug) { + Serial.print("Waterlevel Failcounter="); Serial.println(waterlevel_failcounter); + }*/ + } - waterlevelMean[waterlevelMean_pos]=distances[0]; - waterlevelMean_pos++; - waterlevelMean_pos%=WATERLEVELMEAN_SIZE; } } + +float waterlevel_distanceToVolume(float distance){ + return distance; +} + #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 53dc362..ae1f39c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,18 +1,20 @@ #include -bool flag_print=false; +bool debug=true; //print Serial information #include "helpfunctions.h" #include "ADS1X15.h" ADS1115 ADS(0x48); -// ######## EC -#include "ec.h" // ######## Temperature #include "temperature.h" +// ######## EC +#include "ec.h" + + // ######## Water Level #include "waterlevel.h" @@ -25,13 +27,13 @@ ADS1115 ADS(0x48); #include "soilmoisture.h" -unsigned long last_print=0; - +unsigned long last_check=0; +bool valueError=false; #define PIN_BUTTON 12 #define PIN_LED 13 @@ -50,15 +52,19 @@ void setup() { ADS.setGain(0); + Serial.println("Setup EC"); ec_setup(); + Serial.println("Setup Waterlevel"); waterlevel_setup(); + Serial.println("Setup Temperature"); temperature_setup(); + Serial.println("Setup Flow"); flow_setup(); - //Serial.println("Setup finished"); + Serial.println("Finished Setup"); delay(200); //Test adc to ec function output @@ -76,102 +82,177 @@ void setup() { //Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,EC,EC25"); - Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,sm"); + //Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,sm"); } void loop() { unsigned long loopmillis=millis(); - - flag_print=false; - - ec_loop(loopmillis); - temperature_loop(loopmillis); - - //waterlevel_loop(loopmillis); + waterlevel_loop(loopmillis); - - //flow_loop(loopmillis); + flow_loop(loopmillis); sm_loop(loopmillis); - static bool getReading=false; - if (!getReading && !digitalRead(PIN_BUTTON)) { - getReading=true; - last_measurement_ec=0; //force ec reading now - - ec_flag_measurement_available=false; - digitalWrite(PIN_LED,HIGH); + if (!digitalRead(PIN_BUTTON)) { + valueError=false; + Serial.println("Reset ValueError flag by user"); + digitalWrite(PIN_LED,valueError); + delay(100); } - + if (loopmillis>last_check+2000) { //check values - if (loopmillis>last_print+2000) { - //if (ec_flag_measurement_available && getReading) { - if (ec_flag_measurement_available) { - last_print=loopmillis; - getReading=false; - ec_flag_measurement_available=false; - digitalWrite(PIN_LED,LOW); + last_check=loopmillis; - Serial.print(millis()/1000.0,2); Serial.print(","); - - Serial.print(getMeanf(tempCmean_reservoir,TEMPMEAN_SIZE)); Serial.print(","); - //Serial.print(getMean(sm_mean,SM_SIZE)); Serial.print(","); - - Serial.print(ec_calib_adc); Serial.print(","); - Serial.print(ec_adc); Serial.print(","); - Serial.print(ec_adc_adjusted); Serial.print(","); - //Serial.print(ec); Serial.print(","); - //Serial.print(ec25); - Serial.print(getMean(sm_mean,SM_SIZE)); - - - + + if (tempCmean_air==DEVICE_DISCONNECTED_C || tempCmean_reservoir==DEVICE_DISCONNECTED_C) { + valueError=true; + } + if (waterlevel==WATERLEVEL_UNAVAILABLE) { + valueError=true; + } + if (sm_mean1==SM_DISCONNECTED || sm_mean2==SM_DISCONNECTED) { + valueError=true; + } + if (ec==EC_UNAVAILABLE){ + valueError=true; + } + + + digitalWrite(PIN_LED,valueError); + + + + + if (debug) { + Serial.println("_______________________"); + Serial.print(millis()/1000.0,2); Serial.println(":"); + + Serial.print("temperature reservoir,air = "); + Serial.print(tempCmean_reservoir); Serial.print(","); Serial.print(tempCmean_air); Serial.println(); + + Serial.print("sm_mean 1,2,3 = "); + Serial.print(sm_mean1); Serial.print(","); + Serial.print(sm_mean2); Serial.print(","); + Serial.print(sm_mean3); + Serial.println(); + /* - - - if (isValueArrayOKf(tempCmean_reservoir,TEMPMEAN_SIZE,DEVICE_DISCONNECTED_C)){ - Serial.print("\t Treservoir="); Serial.print(getMeanf(tempCmean_reservoir,TEMPMEAN_SIZE)); Serial.print("\t Tair="); Serial.print(getMeanf(tempCmean_air,TEMPMEAN_SIZE)); - }else{ - Serial.print("\t waiting for temperature"); - } - - - if (isValueArrayOKf(waterlevelMean,WATERLEVELMEAN_SIZE,-1.0)){ - float _max=getMaxf(waterlevelMean,WATERLEVELMEAN_SIZE); - float _min=getMinf(waterlevelMean,WATERLEVELMEAN_SIZE); - - float _filteredWaterlevel=getFilteredf(waterlevelMean,WATERLEVELMEAN_SIZE,8); - float _meanWaterlevel=getMeanf(waterlevelMean,WATERLEVELMEAN_SIZE); - - - Serial.print("\t Dist="); Serial.print(_filteredWaterlevel); Serial.print("mm"); Serial.print("(+- "); Serial.print((_max-_min)/2.0); Serial.print(")"); Serial.print(" [mean="); Serial.print(_meanWaterlevel); Serial.print("]"); - - }else{ - Serial.print("\t waiting for distance"); - } - - Serial.print("\t Flow="); Serial.print(flow,2); - Serial.print("\t Flowsum="); Serial.print(flow_counter_sum); - - - - Serial.println(); + Serial.print("sm_mean 1,2,3 = "); + Serial.print(getMean(sm_mean1array,SM_SIZE)); Serial.print(","); + Serial.print(getMean(sm_mean2array,SM_SIZE)); Serial.print(","); + Serial.print(getMean(sm_mean3array,SM_SIZE)); + Serial.println(); + Serial.print("sm_max 1,2,3 = "); + Serial.print(getMax(sm_mean1array,SM_SIZE)); Serial.print(","); + Serial.print(getMax(sm_mean2array,SM_SIZE)); Serial.print(","); + Serial.print(getMax(sm_mean3array,SM_SIZE)); + Serial.println(); + Serial.print("sm_min 1,2,3 = "); + Serial.print(getMin(sm_mean1array,SM_SIZE)); Serial.print(","); + Serial.print(getMin(sm_mean2array,SM_SIZE)); Serial.print(","); + Serial.print(getMin(sm_mean3array,SM_SIZE)); + Serial.println(); + //Serial.print(getMax(sm_mean3array,SM_SIZE)); Serial.println(); */ + + Serial.print("Flow = "); Serial.print(flow); + Serial.println(); + + Serial.print("EC ec_calib_adc,ec_adc,ec_adc_adjusted = "); + Serial.print(ec_calib_adc); Serial.print(","); + Serial.print(ec_adc); Serial.print(","); + Serial.print(ec_adc_adjusted); + Serial.println(); + Serial.print("EC ec,ec25 = "); + Serial.print(ec); Serial.print(","); + Serial.print(ec25); + Serial.println(); + + Serial.print("Waterlevel="); Serial.print(waterlevel); + Serial.println(); + + } + + + + + + + /* + Serial.print(millis()/1000.0,2); Serial.print(","); + + Serial.print(getMeanf(tempCmean_reservoir_array,TEMPMEAN_SIZE)); Serial.print(","); + //Serial.print(getMean(sm_mean,SM_SIZE)); Serial.print(","); + + Serial.print(ec_calib_adc); Serial.print(","); + Serial.print(ec_adc); Serial.print(","); + Serial.print(ec_adc_adjusted); Serial.print(","); + Serial.print(ec); Serial.print(","); + Serial.print(ec25); + Serial.print(getMean(sm_mean,SM_SIZE)); + + + + + Serial.println(); + + + + if (tempCmean_reservoir!=DEVICE_DISCONNECTED_C){ + Serial.print("\t Treservoir="); Serial.print(tempCmean_reservoir); Serial.print("\t Tair="); Serial.print(tempCmean_air); + }else{ + Serial.print("\t waiting for temperature"); + } + + + if (isValueArrayOKf(waterlevelMean,WATERLEVELMEAN_SIZE,-1.0)){ + float _max=getMaxf(waterlevelMean,WATERLEVELMEAN_SIZE); + float _min=getMinf(waterlevelMean,WATERLEVELMEAN_SIZE); + + float _filteredWaterlevel=getFilteredf(waterlevelMean,WATERLEVELMEAN_SIZE,8); + float _meanWaterlevel=getMeanf(waterlevelMean,WATERLEVELMEAN_SIZE); + + + Serial.print("\t Dist="); Serial.print(_filteredWaterlevel); Serial.print("mm"); Serial.print("(+- "); Serial.print((_max-_min)/2.0); Serial.print(")"); Serial.print(" [mean="); Serial.print(_meanWaterlevel); Serial.print("]"); + + }else{ + Serial.print("\t waiting for distance"); + } + + Serial.print("\t Flow="); Serial.print(flow,2); + Serial.print("\t Flowsum="); Serial.print(flow_counter_sum); + + + + Serial.println(); + */ + + + } } + + + +/* +TODO: +- waterlevel nur -1 +- waterlevel distance to volume fukntion +- soilmoisture min max calibartion einfügen +*/ \ No newline at end of file