-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathec.cpp
More file actions
141 lines (111 loc) · 2.92 KB
/
ec.cpp
File metadata and controls
141 lines (111 loc) · 2.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "GrowduinoFirmware.h"
#include "ec.h"
// #include <stdlib.h>
extern Config config;
void ec_enable() {
#ifdef USE_EC_SENSOR
pinMode(EC_DATA, INPUT);
pinMode(EC_ENABLE, OUTPUT);
#endif
}
long ec_read_raw() {
long lowPulseTime_t = 0;
long highPulseTime_t = 0;
long lowPulseTime = 0;
long highPulseTime = 0;
long pulseTime;
bool pulseError = false;
digitalWrite(EC_ENABLE, HIGH); // power up the sensor
delay(100);
#ifdef WATCHDOG
SERIAL.print(F("Watchdog reset: ec read"));
wdt_reset();
#endif
for (unsigned int j = 0; j < EC_SAMPLE_TIMES; j++) {
highPulseTime_t = pulseIn(EC_DATA, HIGH, EC_TIMEOUT);
if (j == 0 and highPulseTime_t == 0) {//abort on timeout on first read
#ifdef WATCHDOG
SERIAL.println(F(" - abort "));
wdt_reset();
#endif
return MINVALUE;
}
highPulseTime += highPulseTime_t;
if (highPulseTime_t == 0) {
pulseError = true;
}
lowPulseTime_t = pulseIn(EC_DATA, LOW, EC_TIMEOUT);
lowPulseTime += lowPulseTime_t;
if (lowPulseTime_t == 0) {
pulseError = true;
}
#ifdef WATCHDOG
SERIAL.print(F("."));
wdt_reset();
#endif
}
lowPulseTime = lowPulseTime / EC_SAMPLE_TIMES;
highPulseTime = highPulseTime / EC_SAMPLE_TIMES;
pulseTime = (lowPulseTime + highPulseTime) / 2;
digitalWrite(EC_ENABLE, LOW); // power down the sensor
#ifdef WATCHDOG
if (pulseError) {
SERIAL.println(F(" with errors"));
} else {
SERIAL.println(F(" OK"));
}
#endif
if (pulseTime >= EC_CUTOFF) {
return MINVALUE;
}
return pulseTime;
}
int ec_read() {
int ec = MINVALUE;
#ifdef USE_EC_SENSOR
long pulseTime;
float ec_a, ec_b;
float c_low = 1.278;
float c_high = 4.523;
float ec_high_ion = (float) (config.ec_high_ion + config.ec_offset);
float ec_low_ion = (float) (config.ec_low_ion + config.ec_offset);
ec_a = (c_high - c_low) / (1 / ec_high_ion - 1 / ec_low_ion);
ec_b = c_low - ec_a / (float) ec_low_ion;
pulseTime = ec_read_raw();
ec = (int) 100 * (ec_a / (pulseTime + config.ec_offset) + ec_b);
if (pulseTime == MINVALUE) {
ec = MINVALUE;
}
#endif
#ifdef DEBUG_CALIB
if (ec != MINVALUE) {
SERIAL.print(F("EC pulse time: "));
SERIAL.println(pulseTime);
}
#endif
return ec;
}
int compare(const void *p, const void *q) {
long x = *(const int *)p;
long y = *(const int *)q;
/* Avoid return x - y, which can cause undefined behaviour
because of signed integer overflow. */
if (x < y)
return -1; // Return -1 if you want ascending, 1 if you want descending order.
else if (x > y)
return 1; // Return 1 if you want ascending, -1 if you want descending order.
return 0;
}
long ec_calib_raw() {
int size = 7;
long rawdata[size];
for (int i = 0; i < size; i++) {
rawdata[i] = ec_read_raw();
}
qsort(rawdata, size, sizeof(long), compare);
long sum = 0;
for (int i = 1; i < size - 1; i++) {
sum += rawdata[i];
}
return sum / (size - 2);
}