-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSonde_Logging.ino
398 lines (311 loc) · 14.7 KB
/
Sonde_Logging.ino
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
#include <SoftwareSerial.h> //for communicating with the probes
#include <Wire.h> //for communicating with I2C devices - the RTC
#include "SD.h" //library for the SD Card
#include "RTClib.h" //library for the real-time clock(RTC)
#include <Time.h>
#define rxpin 2 //set the RX pin to pin 2 for the multiplexer
#define txpin 3 //set the TX pin to pin 3 for the multiplexer
#define WAIT_TO_START 0 // Wait for serial input in setup()
SoftwareSerial myserial(rxpin, txpin); //enable the soft serial port
String sensorstring = ""; //a string to hold the data from the Atlas Scientific product
String dosensorstring = "";
String logstring = "";
float temp; //final temp data stored here
boolean sensor_stringcomplete=false; //used to tell when you have received all the characters from the sensors
short ack_channel_read=0; //used to determine which channel from the multiplexer you are going to read from
RTC_DS1307 RTC; //defines the real-time clock
// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;
// the logging file
File logfile;
void error(char *str)
{
Serial.print("error: ");
Serial.println(str);
while(1);
}
time_t syncProvider() // function that does the syncing between the internal clock and the RTC
{
return RTC.now().unixtime();
}
void setup(){
Wire.begin(); // starts the Wire library transmission stuff
RTC.begin(); //starts the RTC
pinMode(4, OUTPUT); //used to control the S0 pin
pinMode(5, OUTPUT); //used to control the S1 pin
pinMode(6, OUTPUT); //temperature pin
sensorstring.reserve(30); //set aside some bytes for receiving data
myserial.begin(38400); //set up the soft serial to run at 38400
Serial.begin(38400); //set up the hardware serial port to run at 38400
RTC.adjust(DateTime(__DATE__, __TIME__));
setSyncProvider(syncProvider); // syncs the internal Arduino clock with the RTC
pinMode(10, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
error("Card failed, or not present");
}
Serial.println("Welcome to the Water Quality Logger.");
// create a new file
char filename[] = "LOGGER00.CSV";
for (uint8_t i = 0; i < 100; i++) {
filename[6] = i/10 + '0';
filename[7] = i%10 + '0';
if (! SD.exists(filename)) {
// only open a new file if it doesn't exist
logfile = SD.open(filename, FILE_WRITE);
break; // leave the loop!
}
}
if (! logfile) {
error("couldnt create file");
}
Serial.print("Logging to: ");
Serial.println(filename);
}
void loop() {
while(ack_channel_read==0){
Open_channel(0); //we call the sub open channel. The sub needs to pass a val to indicate what channel to open, ec is set to 0. So, we are telling the function to open channel 0
ack_channel_read=read_channel(0);
}
while(ack_channel_read==1){
Open_channel(1);
read_channel(1);
}
while(ack_channel_read==2){
Open_channel(2);
read_channel(2);
}
while(ack_channel_read==3){
Open_channel(3);
read_channel(3);
}
if(ack_channel_read==4){ack_channel_read=0;}
}
void Open_channel(short channel){
switch (channel) {
case 0: //open channel Y0
digitalWrite(4, LOW); //S0=0
digitalWrite(5, LOW); //S1=0
break;
case 1: //open channel Y1
digitalWrite(4, HIGH); //S0=1
digitalWrite(5, LOW); //S1=0
break;
case 2: //open channel Y2
digitalWrite(4, LOW); //S0=0
digitalWrite(5, HIGH); //S1=1
break;
case 3: //open channel Y3
digitalWrite(4, HIGH); //S0=1
digitalWrite(5, HIGH); //S1=1
break;
}
return;
}
short read_channel(short channel){
if(channel==0){
temp = read_temp(); //call the function “read_temp” and return the temperature in C°
myserial.print(temp); //send the temp value to the DO unit for temperature compensated DO reading
myserial.print(",0"); //finish the command to the DO unit by telling it no salinity compensation
myserial.write(13); //terminate the command string to the DO unit
delay(1100); //let 1.1 sec at a minimum pass...set to 2 now
while (myserial.available()) { //while a char is holding in the serial buffer
char inchar = (char)myserial.read(); //get the new char
dosensorstring += inchar; //add it to the sensorString
if (inchar == '\r') {sensor_stringcomplete = true;} //if the incoming character is a <CR>, set the flag
}
if (sensor_stringcomplete){ //if a string from the Atlas Scientific product has been received in its entirety
ack_channel_read=1;
DateTime now = RTC.now();
logstring = "";
logstring += "DO: ";
logstring += String(dosensorstring);
logstring += ", ";
logstring += String(now.year());
Serial.print(logstring);
logfile.print("DO: ");
logfile.print(dosensorstring); //print the data to the PC
logfile.print(", ");
logfile.print("DATETIME: ");
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.println();
Serial.print("DO: ");
Serial.print(dosensorstring); //print the data to the PC
Serial.print(", ");
Serial.print("DATETIME: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
logfile.print("Temp: ");
logfile.print(temp); //print temp data to PC
logfile.print(", ");
logfile.print("DATETIME: ");
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.println();
Serial.print("Temp: ");
Serial.print(temp); //print temp data to PC
Serial.print(", ");
Serial.print("DATETIME: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
dosensorstring = " "; //clear the sensorstring
logfile.flush();
sensor_stringcomplete = false; //set this as false so it can move onto the next channel to get data
}
return ack_channel_read;
}
if (channel==1 || channel==2 || channel==3){ //any of the other probes do not need temp compensation
DateTime now = RTC.now();
myserial.print("r"); //send command to the probe to tell it to start sending data
myserial.write(13); //terminate command to probe
delay(1100); //let 1.1 sec pass, 2 seconds
while (myserial.available()) { //while a char is holding in the serial buffer
char inchar = (char)myserial.read(); //get the new char
sensorstring += inchar; //add it to the sensorString
if (inchar == '\r') {sensor_stringcomplete = true;} //if the incoming character is a <CR>, set the flag
}
if (sensor_stringcomplete){ //if a string from the Atlas Scientific product has been received in its entirety
if(channel==1){
ack_channel_read=2;
now = RTC.now();
logfile.print("ORP: ");
logfile.print(sensorstring);
logfile.print(", ");
logfile.print("DATETIME: ");
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.println();
Serial.print("ORP: ");
Serial.print(sensorstring);
sensorstring = " ";
logfile.flush();
}
if(channel==2){
ack_channel_read=3;
now = RTC.now();
logfile.print("pH: ");
logfile.print(sensorstring);
logfile.print(", ");
logfile.print("DATETIME: ");
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.println();
Serial.print("pH: ");
Serial.print(sensorstring);
sensorstring = " ";
logfile.flush();
}
if(channel==3){
ack_channel_read=4;
now = RTC.now();
logfile.print("EC: ");
logfile.print(sensorstring);
logfile.print(", ");
logfile.print("DATETIME: ");
logfile.print(now.year(), DEC);
logfile.print('/');
logfile.print(now.month(), DEC);
logfile.print('/');
logfile.print(now.day(), DEC);
logfile.print(' ');
logfile.print(now.hour(), DEC);
logfile.print(':');
logfile.print(now.minute(), DEC);
logfile.print(':');
logfile.print(now.second(), DEC);
logfile.println();
Serial.print("EC: ");
Serial.print(sensorstring);
sensorstring = " ";
//channel three is the last channel to check. get the data and time then print to the PC as a time stamp
logfile.flush();
}
Serial.print(", ");
Serial.print("DATETIME: ");
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
sensor_stringcomplete = false;
}
return ack_channel_read;
}
}
float read_temp(void){ //this is the read temperature function provided by Atlas Scientific
float v_out; //voltage output from temp sensor
float temp; //the final temperature is stored here
digitalWrite(A0, LOW); //set pull-up on analog pin
digitalWrite(6, HIGH); //set pin 2 high, this will turn on temp sensor
delay(2); //wait 2 ms for temp to stabilize
v_out = analogRead(0); //read the input pin
digitalWrite(6, LOW); //set pin 2 low, this will turn off temp sensor
v_out*=.0048; //convert ADC points to volts (we are using .0048 because this device is running at 5 volts)
v_out*=1000; //convert volts to millivolts
temp= 0.0512 * v_out -20.5128; //the equation from millivolts to temperature
return temp; //send back the temp
}