calibration ec manual
This commit is contained in:
parent
a8def64601
commit
8cf4395827
13
include/ec.h
13
include/ec.h
|
@ -29,7 +29,7 @@ uint16_t ec_calib_array_pos=0;
|
||||||
uint16_t ec_array[EC_ARRAY_SIZE];
|
uint16_t ec_array[EC_ARRAY_SIZE];
|
||||||
uint16_t ec_array_pos=EC_ARRAY_SIZE;
|
uint16_t ec_array_pos=EC_ARRAY_SIZE;
|
||||||
unsigned long last_measurement_ec=0;
|
unsigned long last_measurement_ec=0;
|
||||||
#define EC_MEASUREMENT_INTERVAL 30000 //complete filtered measurement every x ms
|
#define EC_MEASUREMENT_INTERVAL 60000 //complete filtered measurement every x ms
|
||||||
//One filtered measurement takes EC_READ_INTERVAL*EC_ARRAY_SIZE*4
|
//One filtered measurement takes EC_READ_INTERVAL*EC_ARRAY_SIZE*4
|
||||||
#define EC_READ_INTERVAL 10 //interval of reading adc value inside a measurement. one reading takes about 9-10ms
|
#define EC_READ_INTERVAL 10 //interval of reading adc value inside a measurement. one reading takes about 9-10ms
|
||||||
|
|
||||||
|
@ -52,14 +52,15 @@ float ec25; //ec value but temperature adjusted for 25 degC
|
||||||
|
|
||||||
float ec_tempadjust_alpa=0.02;
|
float ec_tempadjust_alpa=0.02;
|
||||||
float ec_reference_adc=6016.88; //adc reference value for the calibration resistor measurement.
|
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 short circuit adc value: 17497, 17861.4 (for connection resistance testing)
|
||||||
//EC open circuit adc value: 738
|
//EC open circuit adc value: 738, 730, 737.27
|
||||||
|
|
||||||
//x^0*p[0] + ... + x^n*p[n]
|
//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};
|
//float ec_calibration_polynom[]={691.5992624638029,-1.4015367296761692,0.0008513503472324141,-2.2140576823179093e-07,2.8962580780180067e-11,-1.8577565383307114e-15,4.7162479484903865e-20};
|
||||||
float ec_calibration_polynom[]={1033.928052655456,-3.8909104921922895,0.005627541436014758,-4.103988840997024e-06,1.7231981870816133e-09,-4.433707707721975e-13,7.203892111369395e-17,-7.406549810844244e-21,4.667420606439905e-25,-1.6439457516812463e-29,2.477292190335455e-34};
|
//float ec_calibration_polynom[]={1033.928052655456,-3.8909104921922895,0.005627541436014758,-4.103988840997024e-06,1.7231981870816133e-09,-4.433707707721975e-13,7.203892111369395e-17,-7.406549810844244e-21,4.667420606439905e-25,-1.6439457516812463e-29,2.477292190335455e-34};
|
||||||
float ec_calibration_linearize_below_adc=0; //use linear approximation below this adc value. 0=disable
|
float ec_calibration_polynom[]={212.6826331524675,-0.6043878865263305,0.000571551634082491,-1.827897106718841e-07,2.682337041246909e-11,-1.8368511021965982e-15,4.8269168538877025e-20};
|
||||||
float ec_calibration_linear_lowADC=830; //x0
|
float ec_calibration_linearize_below_adc=6500; //use linear approximation below this adc value. 0=disable
|
||||||
|
float ec_calibration_linear_lowADC=750; //x0
|
||||||
float ec_calibration_linear_lowEC=0; //y0
|
float ec_calibration_linear_lowEC=0; //y0
|
||||||
|
|
||||||
bool ec_measurementReady();
|
bool ec_measurementReady();
|
||||||
|
|
|
@ -6,20 +6,28 @@
|
||||||
#define HCSR04_PIN_ECHO 17
|
#define HCSR04_PIN_ECHO 17
|
||||||
#define HCSR04_PIN_TRIGGER 16
|
#define HCSR04_PIN_TRIGGER 16
|
||||||
#define HCSR04_TIMEOUT 5000 //default is 100000 (uS)
|
#define HCSR04_TIMEOUT 5000 //default is 100000 (uS)
|
||||||
#define READINTERVAL_HCSR04 500
|
#define READINTERVAL_HCSR04 200
|
||||||
|
|
||||||
#define WATERLEVELMEAN_SIZE 32
|
#define WATERLEVELMEAN_SIZE 32
|
||||||
|
#define WATERLEVELMEAN_FILTER_CUTOFF 8 //max value is around WATERLEVELMEAN_SIZE/2
|
||||||
float waterlevelMean_array[WATERLEVELMEAN_SIZE];
|
float waterlevelMean_array[WATERLEVELMEAN_SIZE];
|
||||||
uint16_t waterlevelMean_array_pos=0;
|
uint16_t waterlevelMean_array_pos=0;
|
||||||
#define WATERLEVEL_UNAVAILABLE -1
|
#define WATERLEVEL_UNAVAILABLE -1
|
||||||
float waterlevel=WATERLEVEL_UNAVAILABLE;
|
float waterlevel=WATERLEVEL_UNAVAILABLE; //distance from floor to water surface [mm]
|
||||||
|
float watervolume=WATERLEVEL_UNAVAILABLE; //calculated Volume in Reservoir
|
||||||
|
|
||||||
uint16_t waterlevel_failcounter=0;
|
uint16_t waterlevel_failcounter=0;
|
||||||
#define WATERLEVEL_MAXFAILS 15 //maximum counter value
|
#define WATERLEVEL_MAXFAILS 15 //maximum counter value
|
||||||
#define WATERLEVEL_FAILTHRESHOLD 10 //if failcounter is greater or equal this value waterlevel will not be valid
|
#define WATERLEVEL_FAILTHRESHOLD 10 //if failcounter is greater or equal this value waterlevel will not be valid
|
||||||
|
|
||||||
|
//Calibration
|
||||||
|
float waterlevel_calib_offset_measured=0; //Sollwert
|
||||||
|
float waterlevel_calib_offset_sensor=178.67; //Istwert
|
||||||
|
|
||||||
float waterlevel_distanceToVolume(float distance);
|
float waterlevel_calib_reservoirArea=27*36.5; //area in cm^2
|
||||||
|
|
||||||
|
|
||||||
|
float waterlevel_heightToVolume(float distance);
|
||||||
|
|
||||||
|
|
||||||
void waterlevel_setup() {
|
void waterlevel_setup() {
|
||||||
|
@ -62,16 +70,20 @@ void waterlevel_loop(unsigned long loopmillis) {
|
||||||
|
|
||||||
|
|
||||||
if (isValueArrayOKf(waterlevelMean_array,WATERLEVELMEAN_SIZE,WATERLEVEL_UNAVAILABLE)){
|
if (isValueArrayOKf(waterlevelMean_array,WATERLEVELMEAN_SIZE,WATERLEVEL_UNAVAILABLE)){
|
||||||
float _distance=getFilteredf(waterlevelMean_array,WATERLEVELMEAN_SIZE,8);
|
//float _distance=getFilteredf(waterlevelMean_array,WATERLEVELMEAN_SIZE,WATERLEVELMEAN_FILTER_CUTOFF);
|
||||||
|
float _distance=getMaxf(waterlevelMean_array,WATERLEVELMEAN_SIZE);
|
||||||
|
|
||||||
waterlevel=waterlevel_distanceToVolume(_distance);
|
//Invert distance and offset
|
||||||
|
waterlevel=distance-(waterlevel_calib_offset_sensor+waterlevel_calib_offset_measured);
|
||||||
|
watervolume=waterlevel_heightToVolume(_distance);
|
||||||
|
|
||||||
//float _meanWaterlevel=getMeanf(waterlevelMean,WATERLEVELMEAN_SIZE);
|
//float _meanWaterlevel=getMeanf(waterlevelMean,WATERLEVELMEAN_SIZE);
|
||||||
//Serial.print("\t Dist="); Serial.print(_filteredWaterlevel); Serial.print("mm"); Serial.print("(+- "); Serial.print((getMaxf(waterlevelMean,WATERLEVELMEAN_SIZE)-getMinf(waterlevelMean,WATERLEVELMEAN_SIZE))/2.0); Serial.print(")"); Serial.print(" [mean="); Serial.print(_meanWaterlevel); Serial.print("]");
|
//Serial.print("\t Dist="); Serial.print(_filteredWaterlevel); Serial.print("mm"); Serial.print("(+- "); Serial.print((getMaxf(waterlevelMean,WATERLEVELMEAN_SIZE)-getMinf(waterlevelMean,WATERLEVELMEAN_SIZE))/2.0); Serial.print(")"); Serial.print(" [mean="); Serial.print(_meanWaterlevel); Serial.print("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (waterlevel_failcounter>=WATERLEVEL_FAILTHRESHOLD) { //too many failed readings
|
if (waterlevel_failcounter>=WATERLEVEL_FAILTHRESHOLD) { //too many failed readings
|
||||||
waterlevel=-1;
|
waterlevel=WATERLEVEL_UNAVAILABLE;
|
||||||
|
watervolume=WATERLEVEL_UNAVAILABLE;
|
||||||
/*if (debug) {
|
/*if (debug) {
|
||||||
Serial.print("Waterlevel Failcounter="); Serial.println(waterlevel_failcounter);
|
Serial.print("Waterlevel Failcounter="); Serial.println(waterlevel_failcounter);
|
||||||
}*/
|
}*/
|
||||||
|
@ -80,8 +92,8 @@ void waterlevel_loop(unsigned long loopmillis) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float waterlevel_distanceToVolume(float distance){
|
float waterlevel_heightToVolume(float distance){
|
||||||
return distance;
|
return waterlevel_calib_reservoirArea/100 * distance/100; //area[cm^2] in dm^2 * height in dm = dm^3= L
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -8,7 +8,7 @@ import matplotlib.pyplot as plt
|
||||||
from pandas import *
|
from pandas import *
|
||||||
|
|
||||||
# reading CSV file
|
# reading CSV file
|
||||||
data = read_csv("20230505_NaCl_optimized.csv")
|
data = read_csv("20230509_NaCl_manuell.csv")
|
||||||
|
|
||||||
# converting column data to list
|
# converting column data to list
|
||||||
#solutionAdded = data['solutionAdded'].tolist() #in ml
|
#solutionAdded = data['solutionAdded'].tolist() #in ml
|
||||||
|
@ -68,7 +68,7 @@ xmodel = np.arange(xstart,xstop,increment)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
for model_order in [9,10,11]:
|
for model_order in [3,4,5,6]:
|
||||||
print("model order="+str(model_order))
|
print("model order="+str(model_order))
|
||||||
# Finding the Model
|
# Finding the Model
|
||||||
p = np.polyfit(x, y, model_order)
|
p = np.polyfit(x, y, model_order)
|
||||||
|
|
41
src/main.cpp
41
src/main.cpp
|
@ -1,6 +1,6 @@
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
bool debug=true; //print Serial information
|
bool debug=false; //print Serial information
|
||||||
|
|
||||||
#include "helpfunctions.h"
|
#include "helpfunctions.h"
|
||||||
#include "ADS1X15.h"
|
#include "ADS1X15.h"
|
||||||
|
@ -82,7 +82,7 @@ void setup() {
|
||||||
|
|
||||||
|
|
||||||
//Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,EC,EC25");
|
//Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,EC,EC25");
|
||||||
//Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted,sm");
|
Serial.println("time,tempReservoir,ECadcCalib,ECadc,ECadcAdjusted");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,14 +100,34 @@ void loop() {
|
||||||
sm_loop(loopmillis);
|
sm_loop(loopmillis);
|
||||||
|
|
||||||
|
|
||||||
|
static bool getReading=false;
|
||||||
|
|
||||||
if (!digitalRead(PIN_BUTTON)) {
|
if (!digitalRead(PIN_BUTTON)) {
|
||||||
|
last_check=loopmillis;
|
||||||
valueError=false;
|
valueError=false;
|
||||||
Serial.println("Reset ValueError flag by user");
|
//Serial.println("Reset ValueError flag by user");
|
||||||
digitalWrite(PIN_LED,valueError);
|
//digitalWrite(PIN_LED,valueError);
|
||||||
delay(100);
|
delay(100);
|
||||||
|
last_measurement_ec=0; //force reading
|
||||||
|
getReading=true;
|
||||||
|
ec_flag_measurement_available=false;
|
||||||
|
digitalWrite(PIN_LED,HIGH);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loopmillis>last_check+2000) { //check values
|
if (ec_flag_measurement_available && getReading) {
|
||||||
|
ec_flag_measurement_available=false;
|
||||||
|
getReading=false;
|
||||||
|
digitalWrite(PIN_LED,LOW);
|
||||||
|
Serial.print(loopmillis); Serial.print(",");
|
||||||
|
Serial.print(tempCmean_reservoir); Serial.print(",");
|
||||||
|
Serial.print(ec_calib_adc); Serial.print(",");
|
||||||
|
Serial.print(ec_adc); Serial.print(",");
|
||||||
|
Serial.print(ec_adc_adjusted);
|
||||||
|
Serial.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loopmillis>last_check+2000 && 1==2) { //check values
|
||||||
|
|
||||||
last_check=loopmillis;
|
last_check=loopmillis;
|
||||||
|
|
||||||
|
@ -181,11 +201,12 @@ void loop() {
|
||||||
Serial.print(ec25);
|
Serial.print(ec25);
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
||||||
Serial.print("Waterlevel="); Serial.print(waterlevel);
|
Serial.print("Waterlevel distance,volume = "); Serial.print(waterlevel); Serial.print(","); Serial.print(watervolume);
|
||||||
|
if (waterlevel_failcounter>0) {
|
||||||
|
Serial.print(" fails="); Serial.print(waterlevel_failcounter);
|
||||||
|
}
|
||||||
Serial.println();
|
Serial.println();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -252,7 +273,5 @@ void loop() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
- waterlevel nur -1
|
- recalibrate EC. Note min max (shorted, open) values. Test screw terminal connection. Recalibrate EC Probe.
|
||||||
- waterlevel distance to volume fukntion
|
|
||||||
- soilmoisture min max calibartion einfügen
|
|
||||||
*/
|
*/
|
Loading…
Reference in New Issue