forked from Open-Acidification/TankController
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPHProbe.cpp
More file actions
126 lines (113 loc) · 4.59 KB
/
PHProbe.cpp
File metadata and controls
126 lines (113 loc) · 4.59 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
#include "Devices/PHProbe.h"
#include <avr/wdt.h>
#include <stdlib.h>
#include "Devices/Serial_TC.h"
// class instance variables
/**
* static variable for singleton
*/
PHProbe *PHProbe::_instance = nullptr;
// class methods
/**
* static member function to return singleton
*/
PHProbe *PHProbe::instance() {
if (!_instance) {
_instance = new PHProbe();
}
return _instance;
}
// instance methods
/**
* constructor (private so clients use the singleton)
*/
PHProbe::PHProbe() {
Serial1.begin(9600);
// wait for Serial Monitor to connect. Needed for native USB port boards only:
while (!Serial1)
;
Serial1.print(F("*OK,0\r")); // Turn off the returning of OK after command to EZO pH
Serial1.print(F("C,1\r")); // Reset pH stamp to continuous measurement: once per second
}
void PHProbe::clearCalibration() {
Serial1.print(F("Cal,clear\r")); // send that string to the Atlas Scientific product
}
void PHProbe::sendSlopeRequest() {
// Sending request for Calibration Slope
Serial1.print(F("SLOPE,?\r"));
strncpy_P(slopeResponse, (PGM_P)F(" Slope requested!"), sizeof(slopeResponse)); // Flawfinder: ignore
}
void PHProbe::getSlope(char *buffer, int size) {
// for example "?SLOPE,99.7,100.3, -0.89"
if (strlen(slopeResponse) > 10) { // Flawfinder: ignore
strncpy(buffer, slopeResponse + 7, size); // Flawfinder: ignore
} else {
buffer[0] = '\0';
}
}
/**
* interrupt handler for data arriving from probe
*/
void PHProbe::serialEvent1() {
// if we see that the Atlas Scientific product has sent a character
while (Serial1.available() > 0) {
String string = Serial1.readStringUntil('\r'); // read the string until we see a <CR>
if (string.length() > 0 && string[string.length() - 1] == '\r') {
// We should not see the CR (https://github.com/Arduino-CI/arduino_ci/pull/302)
string.remove(string.length() - 1);
}
if (string.length() > 0) {
if (isdigit(string[0])) { // if the first character in the string is a digit
// convert the string to a floating point number so it can be evaluated by the Arduino
value = string.toFloat();
// we have seen situations where the CO2 bubbler stays on and drives the pH down
if (value && value < 7.0) { // hang so as to trigger the watchdog timer reset
// treat 0 as valid since probe might not be connected
wdt_disable();
wdt_enable(WDTO_120MS); // allow enough time to print message
char buffer[50];
strncpy_P(buffer, (PGM_P)F("Triggering a reset because pH dropped to "), sizeof(buffer));
dtostrf(value, 5, 3, buffer + strnlen(buffer, sizeof(buffer)));
serial(buffer);
while (true) {
}
}
} else if (string[0] == '?') { // answer to a previous query
serial(F("PHProbe serialEvent1: \"%s\""), string.c_str());
if (string.length() > 7 && string.substring(0, 7) == "?SLOPE,") {
// for example "?SLOPE,16.1,100.0"
strncpy(slopeResponse, string.c_str(), sizeof(slopeResponse)); // Flawfinder: ignore
}
}
}
}
}
// "pH decreases with increase in temperature. But this does not mean that
// water becomes more acidic at higher temperatures."
// https://www.westlab.com/blog/2017/11/15/how-does-temperature-affect-ph
void PHProbe::setTemperatureCompensation(float temperature) {
char buffer[10];
if (temperature > 0 && temperature < 100) {
snprintf_P(buffer, sizeof(buffer), (PGM_P)F("T,%i.%i\r"), (int)temperature, (int)(temperature * 100 + 0.5) % 100);
} else {
snprintf_P(buffer, sizeof(buffer), (PGM_P)F("T,20\r"));
}
serial(F("PHProbe::setTemperatureCompensation() - %s"), buffer);
Serial1.print(buffer); // send that string to the Atlas Scientific product
}
void PHProbe::setHighpointCalibration(float highpoint) {
char buffer[17];
snprintf_P(buffer, sizeof(buffer), (PGM_P)F("Cal,High,%i.%i\r"), (int)highpoint,
(int)(highpoint * 1000 + 0.5) % 1000);
Serial1.print(buffer); // send that string to the Atlas Scientific product
}
void PHProbe::setLowpointCalibration(float lowpoint) {
char buffer[16];
snprintf_P(buffer, sizeof(buffer), (PGM_P)F("Cal,low,%i.%i\r"), (int)lowpoint, (int)(lowpoint * 1000 + 0.5) % 1000);
Serial1.print(buffer); // send that string to the Atlas Scientific product
}
void PHProbe::setMidpointCalibration(float midpoint) {
char buffer[16];
snprintf_P(buffer, sizeof(buffer), (PGM_P)F("Cal,mid,%i.%i\r"), (int)midpoint, (int)(midpoint * 1000 + 0.5) % 1000);
Serial1.print(buffer); // send that string to the Atlas Scientific product
}