diff --git a/_s_d_i12_8cpp.html b/_s_d_i12_8cpp.html index 382e38a..5d33137 100644 --- a/_s_d_i12_8cpp.html +++ b/_s_d_i12_8cpp.html @@ -2,7 +2,7 @@ - src/SDI12.cpp file | SDI-12 for Arduino2.2.0 + src/SDI12.cpp file | SDI-12 for Arduino2.2.1 - - - - - - - - - - - - - - - - - - - - -
- - -
- -
- -
- -
- -
-
-
-
- - -
-
- -
- - - - - -
- -
-
-
-
- -
-
- -
-

- TestCommands.ino example - - -

-
-
1/** -
2 * @example{lineno} TestCommands.ino -
3 * @copyright Stroud Water Research Center -
4 * @license This example is published under the BSD-3 license. -
5 * @author Sara Damiano <sdamiano@stroudcenter.org> -
6 */ -
7 -
8#include <SDI12.h> -
9 -
10#ifndef SDI12_DATA_PIN -
11#define SDI12_DATA_PIN 7 -
12#endif -
13#ifndef SDI12_POWER_PIN -
14#define SDI12_POWER_PIN 22 -
15#endif -
16 -
17/* connection information */ -
18#if F_CPU > 48000000L -
19uint32_t serialBaud = 921600; /*!< The baud rate for the output serial port */ -
20#else -
21uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */ -
22#endif -
23int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */ -
24int8_t powerPin = -
25 SDI12_POWER_PIN; /*!< The sensor power pin (or -1 if not switching power) */ -
26uint32_t wake_delay = 10; /*!< Extra time needed for the sensor to wake (0-100ms) */ -
27const int8_t firstAddress = -
28 0; /* The first address in the address space to check (0='0') */ -
29const int8_t lastAddress = -
30 6; /* The last address in the address space to check (62='z') */ -
31const int8_t commandsToTest = -
32 1; /*!< The number of measurement commands to test, between 1 and 11. */ -
33 -
34/** Define the SDI-12 bus */ -
35SDI12 mySDI12(dataPin); -
36 -
37/** Define some testing specs */ -
38const int8_t n_addresses = (lastAddress - firstAddress) + 1; -
39 -
40/** Error codes, if returned */ -
41int8_t error_result_number = 7; -
42float no_error_value = 0; -
43 -
44/// variable that alternates output type back and forth between parsed and raw -
45boolean flip = 0; -
46 -
47String commands[] = {"", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; -
48 -
49// keeps track of active addresses -
50bool isActive[n_addresses]; -
51 -
52// keeps track of the wait time for each active addresses -
53uint32_t meas_time_ms[n_addresses]; -
54 -
55// keeps track of the time each sensor was started -
56uint32_t millisStarted[n_addresses]; -
57 -
58// keeps track of the time each sensor will be ready -
59uint32_t millisReady[n_addresses]; -
60 -
61// keeps track of the number of results expected -
62uint8_t expectedResults[n_addresses]; -
63 -
64// keeps track of the number of results returned -
65uint8_t returnedResults[n_addresses]; -
66 -
67String prev_result[n_addresses]; -
68String this_result[n_addresses]; -
69uint8_t numSensors = 0; -
70 -
71struct startMeasurementResult { // Structure declaration -
72 String returned_address; -
73 uint8_t meas_time_s; -
74 int numberResults; -
75}; -
76 -
77/** -
78 * @brief converts allowable address characters ('0'-'9', 'a'-'z', 'A'-'Z') to a -
79 * decimal number between 0 and 61 (inclusive) to cover the 62 possible -
80 * addresses. -
81 */ -
82byte charToDec(char i) { -
83 if ((i >= '0') && (i <= '9')) return i - '0'; -
84 if ((i >= 'a') && (i <= 'z')) return i - 'a' + 10; -
85 if ((i >= 'A') && (i <= 'Z')) -
86 return i - 'A' + 36; -
87 else -
88 return i; -
89} -
90 -
91/** -
92 * @brief maps a decimal number between 0 and 61 (inclusive) to allowable -
93 * address characters '0'-'9', 'a'-'z', 'A'-'Z', -
94 * -
95 * THIS METHOD IS UNUSED IN THIS EXAMPLE, BUT IT MAY BE HELPFUL. -
96 */ -
97char decToChar(byte i) { -
98 if (i < 10) return i + '0'; -
99 if ((i >= 10) && (i < 36)) return i + 'a' - 10; -
100 if ((i >= 36) && (i <= 62)) -
101 return i + 'A' - 36; -
102 else -
103 return i; -
104} -
105 -
106struct getResultsResult { // Structure declaration -
107 uint8_t resultsReceived; -
108 uint8_t maxDataCommand; -
109 bool addressMatch; -
110 bool crcMatch; -
111 bool errorCode; -
112 bool success; -
113}; -
114 -
115getResultsResult getResults(char address, int resultsExpected, bool verify_crc = false, -
116 bool printCommands = true) { -
117 uint8_t resultsReceived = 0; -
118 uint8_t cmd_number = 0; -
119 // The maximum number of characters that can be returned in the <values> part of the -
120 // response to a D command is either 35 or 75. If the D command is issued to -
121 // retrieve data in response to a concurrent measurement command, or in response to -
122 // a high-volume ASCII measurement command, the maximum is 75. The maximum is also -
123 // 75 in response to a continuous measurement command. Otherwise, the maximum is 35. -
124 int max_sdi_response = 76; -
125 // max chars in a unsigned 64 bit number -
126 int max_sdi_digits = 21; -
127 -
128 String compiled_response = ""; -
129 -
130 bool success = true; -
131 -
132 // Create the return struct -
133 getResultsResult return_result; -
134 return_result.resultsReceived = 0; -
135 return_result.maxDataCommand = 0; -
136 return_result.addressMatch = true; -
137 return_result.crcMatch = true; -
138 return_result.errorCode = false; -
139 return_result.success = true; -
140 -
141 while (resultsReceived < resultsExpected && cmd_number <= 9) { -
142 String command = ""; -
143 command += address; -
144 command += "D"; -
145 command += cmd_number; -
146 command += "!"; // SDI-12 command to get data [address][D][dataOption][!] -
147 mySDI12.sendCommand(command, wake_delay); -
148 -
149 // uint32_t start = millis(); -
150 if (printCommands) { -
151 Serial.print(">>>"); -
152 Serial.println(command); -
153 } -
154 char resp_buffer[max_sdi_response] = {'\0'}; -
155 -
156 // read bytes into the char array until we get to a new line (\r\n) -
157 size_t bytes_read = mySDI12.readBytesUntil('\n', resp_buffer, max_sdi_response); -
158 // Serial.print(bytes_read); -
159 // Serial.println(" characters"); -
160 -
161 size_t data_bytes_read = bytes_read - 1; // subtract one for the /r before the /n -
162 String sdiResponse = String(resp_buffer); -
163 compiled_response += sdiResponse; -
164 sdiResponse.trim(); -
165 if (printCommands) { -
166 Serial.print("<<<"); -
167 Serial.println(sdiResponse); -
168 // Serial.println(sdiResponse.length()); -
169 // Serial.print("<<<"); -
170 // Serial.println(resp_buffer); -
171 // Serial.println(strnlen(resp_buffer, max_sdi_response)); -
172 } -
173 // read and clear anything else from the buffer -
174 int extra_chars = 0; -
175 while (mySDI12.available()) { -
176 Serial.write(mySDI12.read()); -
177 extra_chars++; -
178 } -
179 if (extra_chars > 0) { -
180 Serial.print(extra_chars); -
181 Serial.println(" additional characters received."); -
182 } -
183 mySDI12.clearBuffer(); -
184 -
185 // check the address, break if it's incorrect -
186 char returned_address = resp_buffer[0]; -
187 if (returned_address != address) { -
188 if (printCommands) { -
189 Serial.println("Wrong address returned!"); -
190 Serial.print("Expected "); -
191 Serial.print(String(address)); -
192 Serial.print(" Got "); -
193 Serial.println(String(returned_address)); -
194 Serial.println(String(resp_buffer)); -
195 } -
196 success = false; -
197 return_result.addressMatch = false; -
198 break; -
199 } -
200 -
201 // check the crc, break if it's incorrect -
202 if (verify_crc) { -
203 bool crcMatch = mySDI12.verifyCRC(sdiResponse); -
204 data_bytes_read = data_bytes_read - 3; -
205 if (crcMatch) { -
206 if (printCommands) { Serial.println("CRC valid"); } -
207 } else { -
208 if (printCommands) { Serial.println("CRC check failed!"); } -
209 return_result.crcMatch = false; -
210 success = false; -
211 break; -
212 } -
213 } -
214 -
215 bool gotResults = false; -
216 char float_buffer[max_sdi_digits] = {'\0'}; -
217 char* dec_pl = float_buffer; -
218 uint8_t fb_pos = 0; // start at start of buffer -
219 bool finished_last_number = false; -
220 // iterate through the char array and to check results -
221 // NOTE: start at 1 since we already looked at the address! -
222 for (size_t i = 1; i < data_bytes_read; i++) { -
223 // Get the character at position -
224 char c = resp_buffer[i]; -
225 // Serial.print(i); -
226 // Serial.print(" of "); -
227 // Serial.print(data_bytes_read); -
228 // Serial.print(" '"); -
229 // Serial.print(c); -
230 // Serial.println("'"); -
231 // if we didn't get something number-esque or we're at the end of the buffer, -
232 // assume the last number finished and parse it -
233 //(c != '-' && (c < '0' || c > '9') && c != '.') -
234 if (c == '-' || (c >= '0' && c <= '9') || c == '.') { -
235 // if there's a number, a decimal, or a negative sign next in the -
236 // buffer, add it to the float buffer. -
237 float_buffer[fb_pos] = c; -
238 fb_pos++; -
239 float_buffer[fb_pos] = '\0'; // null terminate the buffer -
240 finished_last_number = false; -
241 // Serial.print("Added to float buffer, currently: '"); -
242 // Serial.print(float_buffer); -
243 // Serial.println("'"); -
244 } else { -
245 // Serial.println("Non Numeric"); -
246 finished_last_number = true; -
247 } -
248 // if we've gotten to the end of a number or the end of the buffer, parse the -
249 // character -
250 if ((finished_last_number || i == data_bytes_read - 1) && -
251 strnlen(float_buffer, max_sdi_digits) > 0) { -
252 float result = atof(float_buffer); -
253 if (printCommands) { -
254 Serial.print("Result "); -
255 Serial.print(resultsReceived); -
256 Serial.print(", Raw value: "); -
257 Serial.print(float_buffer); -
258 dec_pl = strchr(float_buffer, '.'); -
259 size_t len_post_dec = 0; -
260 if (dec_pl != nullptr) { len_post_dec = strnlen(dec_pl, max_sdi_digits) - 1; } -
261 Serial.print(", Len after decimal: "); -
262 Serial.print(len_post_dec); -
263 Serial.print(", Parsed value: "); -
264 Serial.println(String(result, len_post_dec)); -
265 } -
266 // add how many results we have -
267 if (result != -9999) { -
268 gotResults = true; -
269 resultsReceived++; -
270 } -
271 // check for a failure error code at the end -
272 if (error_result_number >= 1) { -
273 if (resultsReceived == error_result_number && result != no_error_value) { -
274 success = false; -
275 return_result.errorCode = true; -
276 if (printCommands) { -
277 Serial.print("Got a failure code of "); -
278 Serial.println(String(result, strnlen(dec_pl, max_sdi_digits) - 1)); -
279 } -
280 } -
281 } -
282 -
283 // empty the buffer -
284 float_buffer[0] = '\0'; -
285 fb_pos = 0; -
286 } -
287 } -
288 -
289 if (!gotResults) { -
290 if (printCommands) { -
291 Serial.println((" No results received, will not continue requests!")); -
292 } -
293 break; -
294 } // don't do another loop if we got nothing -
295 -
296 if (printCommands) { -
297 Serial.print("Total Results Received: "); -
298 Serial.print(resultsReceived); -
299 Serial.print(", Remaining: "); -
300 Serial.println(resultsExpected - resultsReceived); -
301 } -
302 -
303 cmd_number++; -
304 } -
305 -
306 mySDI12.clearBuffer(); -
307 -
308 if (printCommands) { -
309 Serial.print("After "); -
310 Serial.print(cmd_number); -
311 Serial.print(" data commands got "); -
312 Serial.print(resultsReceived); -
313 Serial.print(" results of the expected "); -
314 Serial.print(resultsExpected); -
315 Serial.print(" expected. This is a "); -
316 Serial.println(resultsReceived == resultsExpected ? "success." : "failure."); -
317 } -
318 -
319 success &= resultsReceived == resultsExpected; -
320 this_result[charToDec(address)] = compiled_response; -
321 return_result.resultsReceived = resultsReceived; -
322 return_result.maxDataCommand = cmd_number; -
323 return_result.success = success; -
324 return return_result; -
325} -
326 -
327bool getContinuousResults(char address, int resultsExpected, -
328 bool printCommands = true) { -
329 uint8_t resultsReceived = 0; -
330 uint8_t cmd_number = 0; -
331 while (resultsReceived < resultsExpected && cmd_number <= 9) { -
332 String command = ""; -
333 command += address; -
334 command += "R"; -
335 command += cmd_number; -
336 command += "!"; // SDI-12 command to get data [address][D][dataOption][!] -
337 mySDI12.sendCommand(command, wake_delay); -
338 if (printCommands) { -
339 Serial.print(">>>"); -
340 Serial.println(command); -
341 } -
342 -
343 uint32_t start = millis(); -
344 while (mySDI12.available() < 3 && (millis() - start) < 1500) {} -
345 if (printCommands) { -
346 Serial.print("<<<"); -
347 Serial.write(mySDI12.read()); // ignore the repeated SDI12 address -
348 } -
349 -
350 while (mySDI12.available()) { -
351 char c = mySDI12.peek(); -
352 if (c == '-' || (c >= '0' && c <= '9') || c == '.') { -
353 float result = mySDI12.parseFloat(SKIP_NONE); -
354 Serial.print(String(result, 10)); -
355 if (result != -9999) { resultsReceived++; } -
356 } else if (c >= 0 && c != '\r' && c != '\n') { -
357 Serial.write(mySDI12.read()); -
358 } else { -
359 mySDI12.read(); -
360 } -
361 delay(10); // 1 character ~ 7.5ms -
362 } -
363 if (printCommands) { -
364 Serial.print("Total Results Received: "); -
365 Serial.print(resultsReceived); -
366 Serial.print(", Remaining: "); -
367 Serial.println(resultsExpected - resultsReceived); -
368 } -
369 if (!resultsReceived) { break; } // don't do another loop if we got nothing -
370 cmd_number++; -
371 } -
372 mySDI12.clearBuffer(); -
373 -
374 return resultsReceived == resultsExpected; -
375} -
376 -
377startMeasurementResult startMeasurement(char address, bool is_concurrent = false, -
378 bool request_crc = false, String meas_type = "", -
379 bool printCommands = true) { -
380 // Create the return struct -
381 startMeasurementResult return_result; -
382 return_result.returned_address = ""; -
383 return_result.meas_time_s = 0; -
384 return_result.numberResults = 0; -
385 -
386 String command = ""; -
387 command += address; // All commands start with the address -
388 command += is_concurrent ? "C" : "M"; // C for concurrent, M for standard -
389 command += request_crc ? "C" : ""; // add an additional C to request a CRC -
390 command += meas_type; // Measurement type, "" or 0-9 -
391 command += "!"; // All commands end with "!" -
392 mySDI12.sendCommand(command, wake_delay); -
393 if (printCommands) { -
394 Serial.print(">>>"); -
395 Serial.println(command); -
396 } -
397 -
398 // wait for acknowlegement with format [address][ttt (3 char, seconds)][number of -
399 // measurments available, 0-9] -
400 String sdiResponse = mySDI12.readStringUntil('\n'); -
401 sdiResponse.trim(); -
402 if (printCommands) { -
403 Serial.print("<<<"); -
404 Serial.println(sdiResponse); -
405 } -
406 mySDI12.clearBuffer(); -
407 -
408 // check the address, return if it's incorrect -
409 String returned_address = sdiResponse.substring(0, 1); -
410 char ret_addr_array[2]; -
411 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array)); -
412 return_result.returned_address = ret_addr_array[0]; -
413 if (returned_address != String(address)) { -
414 if (printCommands) { -
415 Serial.println("Wrong address returned!"); -
416 Serial.print("Expected "); -
417 Serial.print(String(address)); -
418 Serial.print(" Got "); -
419 Serial.println(returned_address); -
420 } -
421 return return_result; -
422 } -
423 -
424 // find out how long we have to wait (in seconds). -
425 uint8_t meas_time_s = sdiResponse.substring(1, 4).toInt(); -
426 return_result.meas_time_s = meas_time_s; -
427 if (printCommands) { -
428 Serial.print("expected measurement time: "); -
429 Serial.print(meas_time_s); -
430 Serial.print(" s, "); -
431 } -
432 -
433 // Set up the number of results to expect -
434 int numResults = sdiResponse.substring(4).toInt(); -
435 return_result.numberResults = numResults; -
436 if (printCommands) { -
437 Serial.print("Number Results: "); -
438 Serial.println(numResults); -
439 } -
440 -
441 return return_result; -
442} -
443 -
444// This is a separate function in this example so the wait times can all be filled into -
445// the appropriate arrays -
446int startConcurrentMeasurement(char address, bool request_crc = false, -
447 String meas_type = "", bool printCommands = true) { -
448 startMeasurementResult startResult = startMeasurement(address, true, request_crc, -
449 meas_type, printCommands); -
450 -
451 uint8_t sensorNum = -
452 charToDec(address); // e.g. convert '0' to 0, 'a' to 10, 'Z' to 61. -
453 meas_time_ms[sensorNum] = (static_cast<uint32_t>(startResult.meas_time_s)) * 1000; -
454 millisStarted[sensorNum] = millis(); -
455 if (startResult.meas_time_s == 0) { -
456 millisReady[sensorNum] = millis(); -
457 } else { -
458 // give an extra second -
459 // millisReady[sensorNum] = millis() + meas_time_ms[sensorNum] + 1000; -
460 // subtract a second to start polling early -
461 millisReady[sensorNum] = millis() + meas_time_ms[sensorNum] - 1000; -
462 } -
463 expectedResults[sensorNum] = startResult.numberResults; -
464 -
465 return startResult.numberResults; -
466} -
467 -
468uint32_t takeMeasurement(char address, bool request_crc = false, String meas_type = "", -
469 bool printCommands = true) { -
470 startMeasurementResult startResult = startMeasurement(address, false, request_crc, -
471 meas_type, printCommands); -
472 if (startResult.numberResults == 0) { return -1; } -
473 -
474 uint32_t timerStart = millis(); -
475 uint32_t measTime = -1; -
476 // wait up to 1 second longer than the specified return time -
477 while ((millis() - timerStart) < -
478 (static_cast<uint32_t>(startResult.meas_time_s) + 1) * 1000) { -
479 if (mySDI12.available()) { -
480 break; -
481 } // sensor can interrupt us to let us know it is done early -
482 } -
483 measTime = millis() - timerStart; -
484 String interrupt_response = mySDI12.readStringUntil('\n'); -
485 if (printCommands) { -
486 Serial.print("<<<"); -
487 Serial.println(interrupt_response); -
488 Serial.print("Completed after "); -
489 Serial.print(measTime); -
490 Serial.println(" ms"); -
491 } -
492 -
493 // if we got results, return the measurement time, else -1 -
494 if (getResults(address, startResult.numberResults, request_crc, printCommands) -
495 .success) { -
496 return measTime; -
497 } -
498 -
499 return -1; -
500} -
501 -
502// this checks for activity at a particular address -
503// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z' -
504bool checkActive(char address, int8_t numPings = 3, bool printCommands = true) { -
505 String command = ""; -
506 command += (char)address; // sends basic 'acknowledge' command [address][!] -
507 command += "!"; -
508 -
509 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts -
510 if (printCommands) { -
511 Serial.print(">>>"); -
512 Serial.println(command); -
513 } -
514 mySDI12.sendCommand(command, wake_delay); -
515 -
516 // the sensor should just return its address -
517 String sdiResponse = mySDI12.readStringUntil('\n'); -
518 sdiResponse.trim(); -
519 if (printCommands) { -
520 Serial.print("<<<"); -
521 Serial.println(sdiResponse); -
522 } -
523 mySDI12.clearBuffer(); -
524 -
525 // check the address, return false if it's incorrect -
526 String returned_address = sdiResponse.substring(0, 1); -
527 char ret_addr_array[2]; -
528 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array)); -
529 if (returned_address == String(address)) { return true; } -
530 } -
531 mySDI12.clearBuffer(); -
532 return false; -
533} -
534 -
535/** -
536 * @brief gets identification information from a sensor, and prints it to the serial -
537 * port -
538 * -
539 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'. -
540 * @param printCommands true to print the raw output and input from the command -
541 */ -
542bool printInfo(char i, bool printCommands = true) { -
543 String command = ""; -
544 command += (char)i; -
545 command += "I!"; -
546 mySDI12.sendCommand(command, wake_delay); -
547 if (printCommands) { -
548 Serial.print(">>>"); -
549 Serial.println(command); -
550 } -
551 delay(100); -
552 -
553 String sdiResponse = mySDI12.readStringUntil('\n'); -
554 sdiResponse.trim(); -
555 // allccccccccmmmmmmvvvxxx...xx<CR><LF> -
556 if (printCommands) { -
557 Serial.print("<<<"); -
558 Serial.println(sdiResponse); -
559 } -
560 -
561 Serial.print("Address: "); -
562 Serial.print(sdiResponse.substring(0, 1)); // address -
563 Serial.print(", SDI-12 Version: "); -
564 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number -
565 Serial.print(", Vendor ID: "); -
566 Serial.print(sdiResponse.substring(3, 11)); // vendor id -
567 Serial.print(", Sensor Model: "); -
568 Serial.print(sdiResponse.substring(11, 17)); // sensor model -
569 Serial.print(", Sensor Version: "); -
570 Serial.print(sdiResponse.substring(17, 20)); // sensor version -
571 Serial.print(", Sensor ID: "); -
572 Serial.print(sdiResponse.substring(20)); // sensor id -
573 Serial.println(); -
574 -
575 if (sdiResponse.length() < 3) { return false; }; -
576 return true; -
577} -
578 -
579void setup() { -
580 Serial.begin(serialBaud); -
581 while (!Serial) -
582 ; -
583 -
584 Serial.print("Opening SDI-12 bus on pin "); -
585 Serial.print(String(dataPin)); -
586 Serial.println("..."); -
587 mySDI12.begin(); -
588 delay(500); // allow things to settle -
589 -
590 Serial.println("Timeout value: "); -
591 Serial.println(mySDI12.TIMEOUT); -
592 -
593 // Fill arrays with 0's -
594 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
595 isActive[i] = false; -
596 meas_time_ms[i] = 0; -
597 millisStarted[i] = 0; -
598 millisReady[i] = 0; -
599 expectedResults[i] = 0; -
600 returnedResults[i] = 0; -
601 prev_result[i] = ""; -
602 this_result[i] = ""; -
603 } -
604 -
605 // Power the sensors; -
606 if (powerPin >= 0) { -
607 Serial.println("Powering up sensors with pin "); -
608 Serial.print(String(powerPin)); -
609 Serial.println(", wait 30s..."); -
610 pinMode(powerPin, OUTPUT); -
611 digitalWrite(powerPin, HIGH); -
612 delay(30000L); -
613 } else { -
614 Serial.println("Wait 5s..."); -
615 delay(5000L); -
616 } -
617 -
618 // Quickly Scan the Address Space -
619 Serial.println("Scanning all addresses, please wait..."); -
620 -
621 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
622 char addr = decToChar(i); -
623 Serial.print("i: "); -
624 Serial.print(i); -
625 Serial.print(", addr: "); -
626 Serial.print(addr); -
627 Serial.print(", reversed: "); -
628 Serial.println(charToDec(addr)); -
629 if (checkActive(addr, 5, true)) { -
630 numSensors++; -
631 isActive[i] = 1; -
632 // Serial.println(", +"); -
633 printInfo(addr, true); -
634 } else { -
635 // Serial.println(", -"); -
636 } -
637 } -
638 Serial.print("Total number of sensors found: "); -
639 Serial.println(numSensors); -
640 -
641 if (numSensors == 0) { -
642 Serial.println( -
643 "No sensors found, please check connections and restart the Arduino."); -
644 while (true) { delay(10); } // do nothing forever -
645 } -
646 -
647 Serial.println(); -
648 Serial.println("-------------------------------------------------------------------" -
649 "------------"); -
650 -
651 delay(1000); -
652} -
653 -
654void loop() { -
655 flip = !flip; // flip the switch between concurrent and not -
656 // flip = 1; -
657 // flip = 0; -
658 uint32_t start = millis(); -
659 // Serial.print("Flip: "); -
660 // Serial.println(flip); -
661 -
662 // Fill arrays with 0's -
663 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
664 meas_time_ms[i] = 0; -
665 millisStarted[i] = 0; -
666 millisReady[i] = 0; -
667 expectedResults[i] = 0; -
668 returnedResults[i] = 0; -
669 } -
670 -
671 if (flip) { -
672 // measure one at a time -
673 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
674 char addr = decToChar(i); -
675 if (isActive[i]) { -
676 for (uint8_t a = 0; a < commandsToTest; a++) { -
677 Serial.print("Command "); -
678 Serial.print(i); -
679 Serial.print("M"); -
680 Serial.print(commands[a]); -
681 Serial.println('!'); -
682 takeMeasurement(addr, true, commands[a], true); -
683 } -
684 // getContinuousResults(addr, 3); -
685 Serial.println(); -
686 } else { -
687 Serial.print("Address "); -
688 Serial.print(addr); -
689 Serial.println(" is not active"); -
690 } -
691 } -
692 Serial.print("Total Time for Individual Measurements: "); -
693 Serial.println(millis() - start); -
694 } else { -
695 for (uint8_t a = 0; a < commandsToTest; a++) { -
696 uint32_t min_wait = 60000L; -
697 uint32_t max_wait = 0; -
698 uint32_t for_start = millis(); -
699 // start all sensors measuring concurrently -
700 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
701 char addr = decToChar(i); -
702 if (isActive[i]) { -
703 Serial.print("Command "); -
704 Serial.print(i); -
705 Serial.print("C"); -
706 Serial.print(commands[a]); -
707 Serial.println('!'); -
708 startConcurrentMeasurement(addr, true, commands[a], true); -
709 if (meas_time_ms[i] < min_wait) { min_wait = meas_time_ms[i]; } -
710 if (meas_time_ms[i] > max_wait) { max_wait = meas_time_ms[i]; } -
711 } else { -
712 Serial.print("Address "); -
713 Serial.print(addr); -
714 Serial.println(" is not active"); -
715 } -
716 } -
717 // min_wait = 800; -
718 min_wait = max(static_cast<uint32_t>(10), min_wait / 2); -
719 max_wait = max(static_cast<uint32_t>(1000), -
720 max_wait + static_cast<uint32_t>(2000)); -
721 Serial.print("minimum expected wait for all sensors: "); -
722 Serial.println(min_wait); -
723 Serial.print("maximum expected wait for all sensors: "); -
724 Serial.println(max_wait); -
725 -
726#if defined(TEST_PRINT_ARRAY) -
727 Serial.print("i,\t"); -
728 Serial.print("addr,\t"); -
729 Serial.print("isActive[i],\t"); -
730 Serial.print("millis,\t"); -
731 Serial.print("timeWaited,\t"); -
732 Serial.print("millisReady[i],\t"); -
733 Serial.print("expectedResults[i],\t"); -
734 Serial.print("returnedResults[i],\t"); -
735 Serial.print("millis() > millisReady[i],\t"); -
736 Serial.print("expectedResults[i] > 0,\t"); -
737 Serial.print("returnedResults[i] < expectedResults[i],\t"); -
738 Serial.print("numSensors,\t"); -
739 Serial.print("numReadingsRecorded,\t"); -
740 Serial.print("maxDataCommand,\t"); -
741 Serial.print("resultsReceived,\t"); -
742 Serial.print("errorCode,\t"); -
743 Serial.print("crcMatch,\t"); -
744 Serial.print("gotGoodResults,\t"); -
745 Serial.print("numReadingsRecorded"); -
746 Serial.println(); -
747#endif -
748 -
749 uint8_t numReadingsRecorded = 0; -
750 delay(min_wait); -
751 -
752 do { -
753 // get all readings -
754 for (int8_t i = firstAddress; i <= lastAddress; i++) { -
755 uint32_t timeWaited = 0; -
756 if (millisStarted[i] != 0) { timeWaited = millis() - millisStarted[i]; } -
757 if (this_result[i] != "") { prev_result[i] = this_result[i]; } -
758 -
759 char addr = decToChar(i); -
760 -
761#if defined(TEST_PRINT_ARRAY) -
762 Serial.print(i); -
763 Serial.print(",\t\""); -
764 Serial.print(decToChar(i)); -
765 Serial.print("\",\t"); -
766 Serial.print(isActive[i]); -
767 Serial.print(",\t"); -
768 Serial.print(millis()); -
769 Serial.print(",\t"); -
770 Serial.print(timeWaited); -
771 Serial.print(",\t"); -
772 Serial.print(millisReady[i]); -
773 Serial.print(",\t"); -
774 Serial.print(expectedResults[i]); -
775 Serial.print(",\t"); -
776 Serial.print(returnedResults[i]); -
777 Serial.print(",\t"); -
778 Serial.print(millis() > millisReady[i]); -
779 Serial.print(",\t"); -
780 Serial.print(expectedResults[i] > 0); -
781 Serial.print(",\t"); -
782 Serial.print(returnedResults[i] < expectedResults[i]); -
783 Serial.print(",\t"); -
784 Serial.print(numSensors); -
785 Serial.print(",\t"); -
786 Serial.print(numReadingsRecorded); -
787#endif -
788 -
789 if (isActive[i] && (millis() > millisReady[i]) && (expectedResults[i] > 0) && -
790 (returnedResults[i] < expectedResults[i])) { -
791#ifndef TEST_PRINT_ARRAY -
792 Serial.print("timeWaited: "); -
793 Serial.println(timeWaited); -
794#endif -
795 getResultsResult cResult = getResults(addr, expectedResults[i], true); -
796 returnedResults[i] = cResult.resultsReceived; -
797 bool gotGoodResults = cResult.success; -
798 if (gotGoodResults) { -
799 numReadingsRecorded++; -
800#ifndef TEST_PRINT_ARRAY -
801 Serial.print("Got results from "); -
802 Serial.print(numReadingsRecorded); -
803 Serial.print(" of "); -
804 Serial.print(numSensors); -
805 Serial.print(" sensors"); -
806#endif -
807 } -
808#if defined(TEST_PRINT_ARRAY) -
809 Serial.print(",\t"); -
810 Serial.print(cResult.maxDataCommand); -
811 Serial.print(",\t"); -
812 Serial.print(cResult.resultsReceived); -
813 Serial.print(",\t"); -
814 Serial.print(cResult.errorCode); -
815 Serial.print(",\t"); -
816 Serial.print(cResult.crcMatch); -
817 Serial.print(",\t"); -
818 Serial.print(gotGoodResults); -
819#endif -
820 } -
821 Serial.println(); -
822 } -
823 -
824 } while (millis() - for_start < max_wait && numReadingsRecorded < numSensors); -
825 } -
826 Serial.print("Total Time for Concurrent Measurements: "); -
827 Serial.println(millis() - start); -
828 } -
829 -
830 Serial.println("-------------------------------------------------------------------" -
831 "------------"); -
832} -
- -
-
- -
-
-
-
- - - - - -
- -
-
- - - diff --git a/_test_commands_8ino-example.json b/_test_commands_8ino-example.json deleted file mode 100644 index a1026df..0000000 --- a/_test_commands_8ino-example.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": "1.12.0", - "compound": { - "kind": "example", - "id": "_test_commands_8ino-example", - "name": "TestCommands.ino", - "url_base": "_test_commands_8ino-example", - "url": "_test_commands_8ino-example.html", - "include": null, - "has_template_details": false, - "templates": null, - "brief": "", - "description": "
1/**\n
2 * @example{lineno} TestCommands.ino\n
3 * @copyright Stroud Water Research Center\n
4 * @license This example is published under the BSD-3 license.\n
5 * @author Sara Damiano <sdamiano@stroudcenter.org>\n
6 */\n
7\n
8#include <SDI12.h>\n
9\n
10#ifndef SDI12_DATA_PIN\n
11#define SDI12_DATA_PIN 7\n
12#endif\n
13#ifndef SDI12_POWER_PIN\n
14#define SDI12_POWER_PIN 22\n
15#endif\n
16\n
17/* connection information */\n
18#if F_CPU > 48000000L\n
19uint32_t serialBaud = 921600; /*!< The baud rate for the output serial port */\n
20#else\n
21uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */\n
22#endif\n
23int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */\n
24int8_t powerPin =\n
25 SDI12_POWER_PIN; /*!< The sensor power pin (or -1 if not switching power) */\n
26uint32_t wake_delay = 10; /*!< Extra time needed for the sensor to wake (0-100ms) */\n
27const int8_t firstAddress =\n
28 0; /* The first address in the address space to check (0='0') */\n
29const int8_t lastAddress =\n
30 6; /* The last address in the address space to check (62='z') */\n
31const int8_t commandsToTest =\n
32 1; /*!< The number of measurement commands to test, between 1 and 11. */\n
33\n
34/** Define the SDI-12 bus */\n
35SDI12 mySDI12(dataPin);\n
36\n
37/** Define some testing specs */\n
38const int8_t n_addresses = (lastAddress - firstAddress) + 1;\n
39\n
40/** Error codes, if returned */\n
41int8_t error_result_number = 7;\n
42float no_error_value = 0;\n
43\n
44/// variable that alternates output type back and forth between parsed and raw\n
45boolean flip = 0;\n
46\n
47String commands[] = {"", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};\n
48\n
49// keeps track of active addresses\n
50bool isActive[n_addresses];\n
51\n
52// keeps track of the wait time for each active addresses\n
53uint32_t meas_time_ms[n_addresses];\n
54\n
55// keeps track of the time each sensor was started\n
56uint32_t millisStarted[n_addresses];\n
57\n
58// keeps track of the time each sensor will be ready\n
59uint32_t millisReady[n_addresses];\n
60\n
61// keeps track of the number of results expected\n
62uint8_t expectedResults[n_addresses];\n
63\n
64// keeps track of the number of results returned\n
65uint8_t returnedResults[n_addresses];\n
66\n
67String prev_result[n_addresses];\n
68String this_result[n_addresses];\n
69uint8_t numSensors = 0;\n
70\n
71struct startMeasurementResult { // Structure declaration\n
72 String returned_address;\n
73 uint8_t meas_time_s;\n
74 int numberResults;\n
75};\n
76\n
77/**\n
78 * @brief converts allowable address characters ('0'-'9', 'a'-'z', 'A'-'Z') to a\n
79 * decimal number between 0 and 61 (inclusive) to cover the 62 possible\n
80 * addresses.\n
81 */\n
82byte charToDec(char i) {\n
83 if ((i >= '0') && (i <= '9')) return i - '0';\n
84 if ((i >= 'a') && (i <= 'z')) return i - 'a' + 10;\n
85 if ((i >= 'A') && (i <= 'Z'))\n
86 return i - 'A' + 36;\n
87 else\n
88 return i;\n
89}\n
90\n
91/**\n
92 * @brief maps a decimal number between 0 and 61 (inclusive) to allowable\n
93 * address characters '0'-'9', 'a'-'z', 'A'-'Z',\n
94 *\n
95 * THIS METHOD IS UNUSED IN THIS EXAMPLE, BUT IT MAY BE HELPFUL.\n
96 */\n
97char decToChar(byte i) {\n
98 if (i < 10) return i + '0';\n
99 if ((i >= 10) && (i < 36)) return i + 'a' - 10;\n
100 if ((i >= 36) && (i <= 62))\n
101 return i + 'A' - 36;\n
102 else\n
103 return i;\n
104}\n
105\n
106struct getResultsResult { // Structure declaration\n
107 uint8_t resultsReceived;\n
108 uint8_t maxDataCommand;\n
109 bool addressMatch;\n
110 bool crcMatch;\n
111 bool errorCode;\n
112 bool success;\n
113};\n
114\n
115getResultsResult getResults(char address, int resultsExpected, bool verify_crc = false,\n
116 bool printCommands = true) {\n
117 uint8_t resultsReceived = 0;\n
118 uint8_t cmd_number = 0;\n
119 // The maximum number of characters that can be returned in the <values> part of the\n
120 // response to a D command is either 35 or 75. If the D command is issued to\n
121 // retrieve data in response to a concurrent measurement command, or in response to\n
122 // a high-volume ASCII measurement command, the maximum is 75. The maximum is also\n
123 // 75 in response to a continuous measurement command. Otherwise, the maximum is 35.\n
124 int max_sdi_response = 76;\n
125 // max chars in a unsigned 64 bit number\n
126 int max_sdi_digits = 21;\n
127\n
128 String compiled_response = "";\n
129\n
130 bool success = true;\n
131\n
132 // Create the return struct\n
133 getResultsResult return_result;\n
134 return_result.resultsReceived = 0;\n
135 return_result.maxDataCommand = 0;\n
136 return_result.addressMatch = true;\n
137 return_result.crcMatch = true;\n
138 return_result.errorCode = false;\n
139 return_result.success = true;\n
140\n
141 while (resultsReceived < resultsExpected && cmd_number <= 9) {\n
142 String command = "";\n
143 command += address;\n
144 command += "D";\n
145 command += cmd_number;\n
146 command += "!"; // SDI-12 command to get data [address][D][dataOption][!]\n
147 mySDI12.sendCommand(command, wake_delay);\n
148\n
149 // uint32_t start = millis();\n
150 if (printCommands) {\n
151 Serial.print(">>>");\n
152 Serial.println(command);\n
153 }\n
154 char resp_buffer[max_sdi_response] = {'\\0'};\n
155\n
156 // read bytes into the char array until we get to a new line (\\r\\n)\n
157 size_t bytes_read = mySDI12.readBytesUntil('\\n', resp_buffer, max_sdi_response);\n
158 // Serial.print(bytes_read);\n
159 // Serial.println(" characters");\n
160\n
161 size_t data_bytes_read = bytes_read - 1; // subtract one for the /r before the /n\n
162 String sdiResponse = String(resp_buffer);\n
163 compiled_response += sdiResponse;\n
164 sdiResponse.trim();\n
165 if (printCommands) {\n
166 Serial.print("<<<");\n
167 Serial.println(sdiResponse);\n
168 // Serial.println(sdiResponse.length());\n
169 // Serial.print("<<<");\n
170 // Serial.println(resp_buffer);\n
171 // Serial.println(strnlen(resp_buffer, max_sdi_response));\n
172 }\n
173 // read and clear anything else from the buffer\n
174 int extra_chars = 0;\n
175 while (mySDI12.available()) {\n
176 Serial.write(mySDI12.read());\n
177 extra_chars++;\n
178 }\n
179 if (extra_chars > 0) {\n
180 Serial.print(extra_chars);\n
181 Serial.println(" additional characters received.");\n
182 }\n
183 mySDI12.clearBuffer();\n
184\n
185 // check the address, break if it's incorrect\n
186 char returned_address = resp_buffer[0];\n
187 if (returned_address != address) {\n
188 if (printCommands) {\n
189 Serial.println("Wrong address returned!");\n
190 Serial.print("Expected ");\n
191 Serial.print(String(address));\n
192 Serial.print(" Got ");\n
193 Serial.println(String(returned_address));\n
194 Serial.println(String(resp_buffer));\n
195 }\n
196 success = false;\n
197 return_result.addressMatch = false;\n
198 break;\n
199 }\n
200\n
201 // check the crc, break if it's incorrect\n
202 if (verify_crc) {\n
203 bool crcMatch = mySDI12.verifyCRC(sdiResponse);\n
204 data_bytes_read = data_bytes_read - 3;\n
205 if (crcMatch) {\n
206 if (printCommands) { Serial.println("CRC valid"); }\n
207 } else {\n
208 if (printCommands) { Serial.println("CRC check failed!"); }\n
209 return_result.crcMatch = false;\n
210 success = false;\n
211 break;\n
212 }\n
213 }\n
214\n
215 bool gotResults = false;\n
216 char float_buffer[max_sdi_digits] = {'\\0'};\n
217 char* dec_pl = float_buffer;\n
218 uint8_t fb_pos = 0; // start at start of buffer\n
219 bool finished_last_number = false;\n
220 // iterate through the char array and to check results\n
221 // NOTE: start at 1 since we already looked at the address!\n
222 for (size_t i = 1; i < data_bytes_read; i++) {\n
223 // Get the character at position\n
224 char c = resp_buffer[i];\n
225 // Serial.print(i);\n
226 // Serial.print(" of ");\n
227 // Serial.print(data_bytes_read);\n
228 // Serial.print(" '");\n
229 // Serial.print(c);\n
230 // Serial.println("'");\n
231 // if we didn't get something number-esque or we're at the end of the buffer,\n
232 // assume the last number finished and parse it\n
233 //(c != '-' && (c < '0' || c > '9') && c != '.')\n
234 if (c == '-' || (c >= '0' && c <= '9') || c == '.') {\n
235 // if there's a number, a decimal, or a negative sign next in the\n
236 // buffer, add it to the float buffer.\n
237 float_buffer[fb_pos] = c;\n
238 fb_pos++;\n
239 float_buffer[fb_pos] = '\\0'; // null terminate the buffer\n
240 finished_last_number = false;\n
241 // Serial.print("Added to float buffer, currently: '");\n
242 // Serial.print(float_buffer);\n
243 // Serial.println("'");\n
244 } else {\n
245 // Serial.println("Non Numeric");\n
246 finished_last_number = true;\n
247 }\n
248 // if we've gotten to the end of a number or the end of the buffer, parse the\n
249 // character\n
250 if ((finished_last_number || i == data_bytes_read - 1) &&\n
251 strnlen(float_buffer, max_sdi_digits) > 0) {\n
252 float result = atof(float_buffer);\n
253 if (printCommands) {\n
254 Serial.print("Result ");\n
255 Serial.print(resultsReceived);\n
256 Serial.print(", Raw value: ");\n
257 Serial.print(float_buffer);\n
258 dec_pl = strchr(float_buffer, '.');\n
259 size_t len_post_dec = 0;\n
260 if (dec_pl != nullptr) { len_post_dec = strnlen(dec_pl, max_sdi_digits) - 1; }\n
261 Serial.print(", Len after decimal: ");\n
262 Serial.print(len_post_dec);\n
263 Serial.print(", Parsed value: ");\n
264 Serial.println(String(result, len_post_dec));\n
265 }\n
266 // add how many results we have\n
267 if (result != -9999) {\n
268 gotResults = true;\n
269 resultsReceived++;\n
270 }\n
271 // check for a failure error code at the end\n
272 if (error_result_number >= 1) {\n
273 if (resultsReceived == error_result_number && result != no_error_value) {\n
274 success = false;\n
275 return_result.errorCode = true;\n
276 if (printCommands) {\n
277 Serial.print("Got a failure code of ");\n
278 Serial.println(String(result, strnlen(dec_pl, max_sdi_digits) - 1));\n
279 }\n
280 }\n
281 }\n
282\n
283 // empty the buffer\n
284 float_buffer[0] = '\\0';\n
285 fb_pos = 0;\n
286 }\n
287 }\n
288\n
289 if (!gotResults) {\n
290 if (printCommands) {\n
291 Serial.println((" No results received, will not continue requests!"));\n
292 }\n
293 break;\n
294 } // don't do another loop if we got nothing\n
295\n
296 if (printCommands) {\n
297 Serial.print("Total Results Received: ");\n
298 Serial.print(resultsReceived);\n
299 Serial.print(", Remaining: ");\n
300 Serial.println(resultsExpected - resultsReceived);\n
301 }\n
302\n
303 cmd_number++;\n
304 }\n
305\n
306 mySDI12.clearBuffer();\n
307\n
308 if (printCommands) {\n
309 Serial.print("After ");\n
310 Serial.print(cmd_number);\n
311 Serial.print(" data commands got ");\n
312 Serial.print(resultsReceived);\n
313 Serial.print(" results of the expected ");\n
314 Serial.print(resultsExpected);\n
315 Serial.print(" expected. This is a ");\n
316 Serial.println(resultsReceived == resultsExpected ? "success." : "failure.");\n
317 }\n
318\n
319 success &= resultsReceived == resultsExpected;\n
320 this_result[charToDec(address)] = compiled_response;\n
321 return_result.resultsReceived = resultsReceived;\n
322 return_result.maxDataCommand = cmd_number;\n
323 return_result.success = success;\n
324 return return_result;\n
325}\n
326\n
327bool getContinuousResults(char address, int resultsExpected,\n
328 bool printCommands = true) {\n
329 uint8_t resultsReceived = 0;\n
330 uint8_t cmd_number = 0;\n
331 while (resultsReceived < resultsExpected && cmd_number <= 9) {\n
332 String command = "";\n
333 command += address;\n
334 command += "R";\n
335 command += cmd_number;\n
336 command += "!"; // SDI-12 command to get data [address][D][dataOption][!]\n
337 mySDI12.sendCommand(command, wake_delay);\n
338 if (printCommands) {\n
339 Serial.print(">>>");\n
340 Serial.println(command);\n
341 }\n
342\n
343 uint32_t start = millis();\n
344 while (mySDI12.available() < 3 && (millis() - start) < 1500) {}\n
345 if (printCommands) {\n
346 Serial.print("<<<");\n
347 Serial.write(mySDI12.read()); // ignore the repeated SDI12 address\n
348 }\n
349\n
350 while (mySDI12.available()) {\n
351 char c = mySDI12.peek();\n
352 if (c == '-' || (c >= '0' && c <= '9') || c == '.') {\n
353 float result = mySDI12.parseFloat(SKIP_NONE);\n
354 Serial.print(String(result, 10));\n
355 if (result != -9999) { resultsReceived++; }\n
356 } else if (c >= 0 && c != '\\r' && c != '\\n') {\n
357 Serial.write(mySDI12.read());\n
358 } else {\n
359 mySDI12.read();\n
360 }\n
361 delay(10); // 1 character ~ 7.5ms\n
362 }\n
363 if (printCommands) {\n
364 Serial.print("Total Results Received: ");\n
365 Serial.print(resultsReceived);\n
366 Serial.print(", Remaining: ");\n
367 Serial.println(resultsExpected - resultsReceived);\n
368 }\n
369 if (!resultsReceived) { break; } // don't do another loop if we got nothing\n
370 cmd_number++;\n
371 }\n
372 mySDI12.clearBuffer();\n
373\n
374 return resultsReceived == resultsExpected;\n
375}\n
376\n
377startMeasurementResult startMeasurement(char address, bool is_concurrent = false,\n
378 bool request_crc = false, String meas_type = "",\n
379 bool printCommands = true) {\n
380 // Create the return struct\n
381 startMeasurementResult return_result;\n
382 return_result.returned_address = "";\n
383 return_result.meas_time_s = 0;\n
384 return_result.numberResults = 0;\n
385\n
386 String command = "";\n
387 command += address; // All commands start with the address\n
388 command += is_concurrent ? "C" : "M"; // C for concurrent, M for standard\n
389 command += request_crc ? "C" : ""; // add an additional C to request a CRC\n
390 command += meas_type; // Measurement type, "" or 0-9\n
391 command += "!"; // All commands end with "!"\n
392 mySDI12.sendCommand(command, wake_delay);\n
393 if (printCommands) {\n
394 Serial.print(">>>");\n
395 Serial.println(command);\n
396 }\n
397\n
398 // wait for acknowlegement with format [address][ttt (3 char, seconds)][number of\n
399 // measurments available, 0-9]\n
400 String sdiResponse = mySDI12.readStringUntil('\\n');\n
401 sdiResponse.trim();\n
402 if (printCommands) {\n
403 Serial.print("<<<");\n
404 Serial.println(sdiResponse);\n
405 }\n
406 mySDI12.clearBuffer();\n
407\n
408 // check the address, return if it's incorrect\n
409 String returned_address = sdiResponse.substring(0, 1);\n
410 char ret_addr_array[2];\n
411 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array));\n
412 return_result.returned_address = ret_addr_array[0];\n
413 if (returned_address != String(address)) {\n
414 if (printCommands) {\n
415 Serial.println("Wrong address returned!");\n
416 Serial.print("Expected ");\n
417 Serial.print(String(address));\n
418 Serial.print(" Got ");\n
419 Serial.println(returned_address);\n
420 }\n
421 return return_result;\n
422 }\n
423\n
424 // find out how long we have to wait (in seconds).\n
425 uint8_t meas_time_s = sdiResponse.substring(1, 4).toInt();\n
426 return_result.meas_time_s = meas_time_s;\n
427 if (printCommands) {\n
428 Serial.print("expected measurement time: ");\n
429 Serial.print(meas_time_s);\n
430 Serial.print(" s, ");\n
431 }\n
432\n
433 // Set up the number of results to expect\n
434 int numResults = sdiResponse.substring(4).toInt();\n
435 return_result.numberResults = numResults;\n
436 if (printCommands) {\n
437 Serial.print("Number Results: ");\n
438 Serial.println(numResults);\n
439 }\n
440\n
441 return return_result;\n
442}\n
443\n
444// This is a separate function in this example so the wait times can all be filled into\n
445// the appropriate arrays\n
446int startConcurrentMeasurement(char address, bool request_crc = false,\n
447 String meas_type = "", bool printCommands = true) {\n
448 startMeasurementResult startResult = startMeasurement(address, true, request_crc,\n
449 meas_type, printCommands);\n
450\n
451 uint8_t sensorNum =\n
452 charToDec(address); // e.g. convert '0' to 0, 'a' to 10, 'Z' to 61.\n
453 meas_time_ms[sensorNum] = (static_cast<uint32_t>(startResult.meas_time_s)) * 1000;\n
454 millisStarted[sensorNum] = millis();\n
455 if (startResult.meas_time_s == 0) {\n
456 millisReady[sensorNum] = millis();\n
457 } else {\n
458 // give an extra second\n
459 // millisReady[sensorNum] = millis() + meas_time_ms[sensorNum] + 1000;\n
460 // subtract a second to start polling early\n
461 millisReady[sensorNum] = millis() + meas_time_ms[sensorNum] - 1000;\n
462 }\n
463 expectedResults[sensorNum] = startResult.numberResults;\n
464\n
465 return startResult.numberResults;\n
466}\n
467\n
468uint32_t takeMeasurement(char address, bool request_crc = false, String meas_type = "",\n
469 bool printCommands = true) {\n
470 startMeasurementResult startResult = startMeasurement(address, false, request_crc,\n
471 meas_type, printCommands);\n
472 if (startResult.numberResults == 0) { return -1; }\n
473\n
474 uint32_t timerStart = millis();\n
475 uint32_t measTime = -1;\n
476 // wait up to 1 second longer than the specified return time\n
477 while ((millis() - timerStart) <\n
478 (static_cast<uint32_t>(startResult.meas_time_s) + 1) * 1000) {\n
479 if (mySDI12.available()) {\n
480 break;\n
481 } // sensor can interrupt us to let us know it is done early\n
482 }\n
483 measTime = millis() - timerStart;\n
484 String interrupt_response = mySDI12.readStringUntil('\\n');\n
485 if (printCommands) {\n
486 Serial.print("<<<");\n
487 Serial.println(interrupt_response);\n
488 Serial.print("Completed after ");\n
489 Serial.print(measTime);\n
490 Serial.println(" ms");\n
491 }\n
492\n
493 // if we got results, return the measurement time, else -1\n
494 if (getResults(address, startResult.numberResults, request_crc, printCommands)\n
495 .success) {\n
496 return measTime;\n
497 }\n
498\n
499 return -1;\n
500}\n
501\n
502// this checks for activity at a particular address\n
503// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z'\n
504bool checkActive(char address, int8_t numPings = 3, bool printCommands = true) {\n
505 String command = "";\n
506 command += (char)address; // sends basic 'acknowledge' command [address][!]\n
507 command += "!";\n
508\n
509 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts\n
510 if (printCommands) {\n
511 Serial.print(">>>");\n
512 Serial.println(command);\n
513 }\n
514 mySDI12.sendCommand(command, wake_delay);\n
515\n
516 // the sensor should just return its address\n
517 String sdiResponse = mySDI12.readStringUntil('\\n');\n
518 sdiResponse.trim();\n
519 if (printCommands) {\n
520 Serial.print("<<<");\n
521 Serial.println(sdiResponse);\n
522 }\n
523 mySDI12.clearBuffer();\n
524\n
525 // check the address, return false if it's incorrect\n
526 String returned_address = sdiResponse.substring(0, 1);\n
527 char ret_addr_array[2];\n
528 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array));\n
529 if (returned_address == String(address)) { return true; }\n
530 }\n
531 mySDI12.clearBuffer();\n
532 return false;\n
533}\n
534\n
535/**\n
536 * @brief gets identification information from a sensor, and prints it to the serial\n
537 * port\n
538 *\n
539 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'.\n
540 * @param printCommands true to print the raw output and input from the command\n
541 */\n
542bool printInfo(char i, bool printCommands = true) {\n
543 String command = "";\n
544 command += (char)i;\n
545 command += "I!";\n
546 mySDI12.sendCommand(command, wake_delay);\n
547 if (printCommands) {\n
548 Serial.print(">>>");\n
549 Serial.println(command);\n
550 }\n
551 delay(100);\n
552\n
553 String sdiResponse = mySDI12.readStringUntil('\\n');\n
554 sdiResponse.trim();\n
555 // allccccccccmmmmmmvvvxxx...xx<CR><LF>\n
556 if (printCommands) {\n
557 Serial.print("<<<");\n
558 Serial.println(sdiResponse);\n
559 }\n
560\n
561 Serial.print("Address: ");\n
562 Serial.print(sdiResponse.substring(0, 1)); // address\n
563 Serial.print(", SDI-12 Version: ");\n
564 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number\n
565 Serial.print(", Vendor ID: ");\n
566 Serial.print(sdiResponse.substring(3, 11)); // vendor id\n
567 Serial.print(", Sensor Model: ");\n
568 Serial.print(sdiResponse.substring(11, 17)); // sensor model\n
569 Serial.print(", Sensor Version: ");\n
570 Serial.print(sdiResponse.substring(17, 20)); // sensor version\n
571 Serial.print(", Sensor ID: ");\n
572 Serial.print(sdiResponse.substring(20)); // sensor id\n
573 Serial.println();\n
574\n
575 if (sdiResponse.length() < 3) { return false; };\n
576 return true;\n
577}\n
578\n
579void setup() {\n
580 Serial.begin(serialBaud);\n
581 while (!Serial)\n
582 ;\n
583\n
584 Serial.print("Opening SDI-12 bus on pin ");\n
585 Serial.print(String(dataPin));\n
586 Serial.println("...");\n
587 mySDI12.begin();\n
588 delay(500); // allow things to settle\n
589\n
590 Serial.println("Timeout value: ");\n
591 Serial.println(mySDI12.TIMEOUT);\n
592\n
593 // Fill arrays with 0's\n
594 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
595 isActive[i] = false;\n
596 meas_time_ms[i] = 0;\n
597 millisStarted[i] = 0;\n
598 millisReady[i] = 0;\n
599 expectedResults[i] = 0;\n
600 returnedResults[i] = 0;\n
601 prev_result[i] = "";\n
602 this_result[i] = "";\n
603 }\n
604\n
605 // Power the sensors;\n
606 if (powerPin >= 0) {\n
607 Serial.println("Powering up sensors with pin ");\n
608 Serial.print(String(powerPin));\n
609 Serial.println(", wait 30s...");\n
610 pinMode(powerPin, OUTPUT);\n
611 digitalWrite(powerPin, HIGH);\n
612 delay(30000L);\n
613 } else {\n
614 Serial.println("Wait 5s...");\n
615 delay(5000L);\n
616 }\n
617\n
618 // Quickly Scan the Address Space\n
619 Serial.println("Scanning all addresses, please wait...");\n
620\n
621 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
622 char addr = decToChar(i);\n
623 Serial.print("i: ");\n
624 Serial.print(i);\n
625 Serial.print(", addr: ");\n
626 Serial.print(addr);\n
627 Serial.print(", reversed: ");\n
628 Serial.println(charToDec(addr));\n
629 if (checkActive(addr, 5, true)) {\n
630 numSensors++;\n
631 isActive[i] = 1;\n
632 // Serial.println(", +");\n
633 printInfo(addr, true);\n
634 } else {\n
635 // Serial.println(", -");\n
636 }\n
637 }\n
638 Serial.print("Total number of sensors found: ");\n
639 Serial.println(numSensors);\n
640\n
641 if (numSensors == 0) {\n
642 Serial.println(\n
643 "No sensors found, please check connections and restart the Arduino.");\n
644 while (true) { delay(10); } // do nothing forever\n
645 }\n
646\n
647 Serial.println();\n
648 Serial.println("-------------------------------------------------------------------"\n
649 "------------");\n
650\n
651 delay(1000);\n
652}\n
653\n
654void loop() {\n
655 flip = !flip; // flip the switch between concurrent and not\n
656 // flip = 1;\n
657 // flip = 0;\n
658 uint32_t start = millis();\n
659 // Serial.print("Flip: ");\n
660 // Serial.println(flip);\n
661\n
662 // Fill arrays with 0's\n
663 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
664 meas_time_ms[i] = 0;\n
665 millisStarted[i] = 0;\n
666 millisReady[i] = 0;\n
667 expectedResults[i] = 0;\n
668 returnedResults[i] = 0;\n
669 }\n
670\n
671 if (flip) {\n
672 // measure one at a time\n
673 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
674 char addr = decToChar(i);\n
675 if (isActive[i]) {\n
676 for (uint8_t a = 0; a < commandsToTest; a++) {\n
677 Serial.print("Command ");\n
678 Serial.print(i);\n
679 Serial.print("M");\n
680 Serial.print(commands[a]);\n
681 Serial.println('!');\n
682 takeMeasurement(addr, true, commands[a], true);\n
683 }\n
684 // getContinuousResults(addr, 3);\n
685 Serial.println();\n
686 } else {\n
687 Serial.print("Address ");\n
688 Serial.print(addr);\n
689 Serial.println(" is not active");\n
690 }\n
691 }\n
692 Serial.print("Total Time for Individual Measurements: ");\n
693 Serial.println(millis() - start);\n
694 } else {\n
695 for (uint8_t a = 0; a < commandsToTest; a++) {\n
696 uint32_t min_wait = 60000L;\n
697 uint32_t max_wait = 0;\n
698 uint32_t for_start = millis();\n
699 // start all sensors measuring concurrently\n
700 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
701 char addr = decToChar(i);\n
702 if (isActive[i]) {\n
703 Serial.print("Command ");\n
704 Serial.print(i);\n
705 Serial.print("C");\n
706 Serial.print(commands[a]);\n
707 Serial.println('!');\n
708 startConcurrentMeasurement(addr, true, commands[a], true);\n
709 if (meas_time_ms[i] < min_wait) { min_wait = meas_time_ms[i]; }\n
710 if (meas_time_ms[i] > max_wait) { max_wait = meas_time_ms[i]; }\n
711 } else {\n
712 Serial.print("Address ");\n
713 Serial.print(addr);\n
714 Serial.println(" is not active");\n
715 }\n
716 }\n
717 // min_wait = 800;\n
718 min_wait = max(static_cast<uint32_t>(10), min_wait / 2);\n
719 max_wait = max(static_cast<uint32_t>(1000),\n
720 max_wait + static_cast<uint32_t>(2000));\n
721 Serial.print("minimum expected wait for all sensors: ");\n
722 Serial.println(min_wait);\n
723 Serial.print("maximum expected wait for all sensors: ");\n
724 Serial.println(max_wait);\n
725\n
726#if defined(TEST_PRINT_ARRAY)\n
727 Serial.print("i,\\t");\n
728 Serial.print("addr,\\t");\n
729 Serial.print("isActive[i],\\t");\n
730 Serial.print("millis,\\t");\n
731 Serial.print("timeWaited,\\t");\n
732 Serial.print("millisReady[i],\\t");\n
733 Serial.print("expectedResults[i],\\t");\n
734 Serial.print("returnedResults[i],\\t");\n
735 Serial.print("millis() > millisReady[i],\\t");\n
736 Serial.print("expectedResults[i] > 0,\\t");\n
737 Serial.print("returnedResults[i] < expectedResults[i],\\t");\n
738 Serial.print("numSensors,\\t");\n
739 Serial.print("numReadingsRecorded,\\t");\n
740 Serial.print("maxDataCommand,\\t");\n
741 Serial.print("resultsReceived,\\t");\n
742 Serial.print("errorCode,\\t");\n
743 Serial.print("crcMatch,\\t");\n
744 Serial.print("gotGoodResults,\\t");\n
745 Serial.print("numReadingsRecorded");\n
746 Serial.println();\n
747#endif\n
748\n
749 uint8_t numReadingsRecorded = 0;\n
750 delay(min_wait);\n
751\n
752 do {\n
753 // get all readings\n
754 for (int8_t i = firstAddress; i <= lastAddress; i++) {\n
755 uint32_t timeWaited = 0;\n
756 if (millisStarted[i] != 0) { timeWaited = millis() - millisStarted[i]; }\n
757 if (this_result[i] != "") { prev_result[i] = this_result[i]; }\n
758\n
759 char addr = decToChar(i);\n
760\n
761#if defined(TEST_PRINT_ARRAY)\n
762 Serial.print(i);\n
763 Serial.print(",\\t\\"");\n
764 Serial.print(decToChar(i));\n
765 Serial.print("\\",\\t");\n
766 Serial.print(isActive[i]);\n
767 Serial.print(",\\t");\n
768 Serial.print(millis());\n
769 Serial.print(",\\t");\n
770 Serial.print(timeWaited);\n
771 Serial.print(",\\t");\n
772 Serial.print(millisReady[i]);\n
773 Serial.print(",\\t");\n
774 Serial.print(expectedResults[i]);\n
775 Serial.print(",\\t");\n
776 Serial.print(returnedResults[i]);\n
777 Serial.print(",\\t");\n
778 Serial.print(millis() > millisReady[i]);\n
779 Serial.print(",\\t");\n
780 Serial.print(expectedResults[i] > 0);\n
781 Serial.print(",\\t");\n
782 Serial.print(returnedResults[i] < expectedResults[i]);\n
783 Serial.print(",\\t");\n
784 Serial.print(numSensors);\n
785 Serial.print(",\\t");\n
786 Serial.print(numReadingsRecorded);\n
787#endif\n
788\n
789 if (isActive[i] && (millis() > millisReady[i]) && (expectedResults[i] > 0) &&\n
790 (returnedResults[i] < expectedResults[i])) {\n
791#ifndef TEST_PRINT_ARRAY\n
792 Serial.print("timeWaited: ");\n
793 Serial.println(timeWaited);\n
794#endif\n
795 getResultsResult cResult = getResults(addr, expectedResults[i], true);\n
796 returnedResults[i] = cResult.resultsReceived;\n
797 bool gotGoodResults = cResult.success;\n
798 if (gotGoodResults) {\n
799 numReadingsRecorded++;\n
800#ifndef TEST_PRINT_ARRAY\n
801 Serial.print("Got results from ");\n
802 Serial.print(numReadingsRecorded);\n
803 Serial.print(" of ");\n
804 Serial.print(numSensors);\n
805 Serial.print(" sensors");\n
806#endif\n
807 }\n
808#if defined(TEST_PRINT_ARRAY)\n
809 Serial.print(",\\t");\n
810 Serial.print(cResult.maxDataCommand);\n
811 Serial.print(",\\t");\n
812 Serial.print(cResult.resultsReceived);\n
813 Serial.print(",\\t");\n
814 Serial.print(cResult.errorCode);\n
815 Serial.print(",\\t");\n
816 Serial.print(cResult.crcMatch);\n
817 Serial.print(",\\t");\n
818 Serial.print(gotGoodResults);\n
819#endif\n
820 }\n
821 Serial.println();\n
822 }\n
823\n
824 } while (millis() - for_start < max_wait && numReadingsRecorded < numSensors);\n
825 }\n
826 Serial.print("Total Time for Concurrent Measurements: ");\n
827 Serial.println(millis() - start);\n
828 }\n
829\n
830 Serial.println("-------------------------------------------------------------------"\n
831 "------------");\n
832}\n
", - "sections": "", - "deprecated": null, - "since": null, - "example_navigation": null, - "footer_navigation": [ - [ - "a_wild_card_8ino-example.html", - "a_wild_card.ino" - ], - [ - "examples_page.html", - "Examples using the SDI-12 Library" - ], - [ - "_test_sensor_timing_8ino-example.html", - "TestSensorTiming.ino" - ] - ], - "modules": [], - "dirs": [], - "files": [], - "namespaces": [], - "classes": [], - "base_classes": [], - "derived_classes": [], - "enums": [], - "typedefs": [], - "funcs": [], - "vars": [], - "defines": [], - "public_types": [], - "public_static_funcs": [], - "typeless_funcs": [], - "public_funcs": [], - "signals": [], - "public_slots": [], - "public_static_vars": [], - "public_vars": [], - "protected_types": [], - "protected_static_funcs": [], - "protected_funcs": [], - "protected_slots": [], - "protected_static_vars": [], - "protected_vars": [], - "private_funcs": [], - "private_slots": [], - "related": [], - "friend_funcs": [], - "groups": [], - "has_enum_details": false, - "has_typedef_details": false, - "has_func_details": false, - "has_var_details": false, - "has_define_details": false, - "breadcrumb": [ - [ - "Examples using the SDI-12 Library", - "examples_page.html" - ], - [ - "TestCommands.ino", - "_test_commands_8ino-example.html" - ] - ] - } -} \ No newline at end of file diff --git a/_test_sensor_timing_8ino-example.html b/_test_sensor_timing_8ino-example.html deleted file mode 100644 index 6b7106f..0000000 --- a/_test_sensor_timing_8ino-example.html +++ /dev/null @@ -1,2145 +0,0 @@ - - - - - Examples using the SDI-12 Library » TestSensorTiming.ino example | SDI-12 for Arduino2.2.0 - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
- -
- -
- -
-
-
-
- - -
-
- -
- - - - - -
- -
-
-
-
- -
-
- -
-

- TestSensorTiming.ino example - - -

-
-
1/** -
2 * @example{lineno} TestSensorTiming.ino -
3 * @copyright Stroud Water Research Center -
4 * @license This example is published under the BSD-3 license. -
5 * @author Sara Damiano <sdamiano@stroudcenter.org> -
6 * @date March 2024 -
7 */ -
8 -
9#include <SDI12.h> -
10 -
11#ifndef SDI12_DATA_PIN -
12#define SDI12_DATA_PIN 7 -
13#endif -
14#ifndef SDI12_POWER_PIN -
15#define SDI12_POWER_PIN 22 -
16#endif -
17 -
18/* connection information */ -
19uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */ -
20int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */ -
21int8_t powerPin = -
22 SDI12_POWER_PIN; /*!< The sensor power pin (or -1 if not switching power) */ -
23uint32_t wake_delay = 0; /*!< Extra time needed for the sensor to wake (0-100ms) */ -
24char sensorAddress = '0'; /*!< The address of the SDI-12 sensor */ -
25 -
26/** Define the SDI-12 bus */ -
27SDI12 mySDI12(dataPin); -
28 -
29/** Define some testing specs */ -
30 -
31/** Error codes, if returned */ -
32int8_t error_result_number = 7; -
33float no_error_value = 0; -
34 -
35/** Testing turning off power */ -
36bool testPowerOff = false; -
37int32_t min_power_delay = 100L; /*!< The min time to test wake after power on. */ -
38int32_t max_power_delay = 180000L; /*!< The max time to test wake after power on. */ -
39int32_t increment_power_delay = 100L; /*!< The time to lengthen waits between reps. */ -
40int32_t power_off_time = 60000L; /*!< The time to power off between tests. */ -
41/** NOTE: set the power off time to be something similar to what you will be using the -
42 * the real world! Some sensors take longer to warm up if they've been off for a while. -
43 */ -
44 -
45/** Testing the length of the break */ -
46bool testBreak = true; -
47int32_t min_wake_delay = 0; /*!< The min time to test wake after a line break. */ -
48int32_t max_wake_delay = 100; /*!< The max time to test wake (should be <=100). */ -
49int32_t increment_wake = 5; /*!< The time to lengthen waits between reps. */ -
50 -
51/** set some initial values */ -
52int32_t power_delay = min_power_delay; -
53int32_t wake_delay = min_wake_delay; -
54 -
55int32_t total_meas_time = 0; -
56int32_t total_meas_made = 0; -
57uint32_t max_meas_time = 0; -
58 -
59struct startMeasurementResult { // Structure declaration -
60 String returned_address; -
61 uint8_t meas_time_s; -
62 int numberResults; -
63}; -
64 -
65struct getResultsResult { // Structure declaration -
66 uint8_t resultsReceived; -
67 uint8_t maxDataCommand; -
68 bool addressMatch; -
69 bool crcMatch; -
70 bool errorCode; -
71 bool success; -
72}; -
73 -
74getResultsResult getResults(char address, int resultsExpected, bool verify_crc = false, -
75 bool printCommands = true) { -
76 uint8_t resultsReceived = 0; -
77 uint8_t cmd_number = 0; -
78 // The maximum number of characters that can be returned in the <values> part of the -
79 // response to a D command is either 35 or 75. If the D command is issued to -
80 // retrieve data in response to a concurrent measurement command, or in response to -
81 // a high-volume ASCII measurement command, the maximum is 75. The maximum is also -
82 // 75 in response to a continuous measurement command. Otherwise, the maximum is 35. -
83 int max_sdi_response = 76; -
84 // max chars in a unsigned 64 bit number -
85 int max_sdi_digits = 21; -
86 -
87 String compiled_response = ""; -
88 -
89 bool success = true; -
90 -
91 // Create the return struct -
92 getResultsResult return_result; -
93 return_result.resultsReceived = 0; -
94 return_result.maxDataCommand = 0; -
95 return_result.addressMatch = true; -
96 return_result.crcMatch = true; -
97 return_result.errorCode = false; -
98 return_result.success = true; -
99 -
100 while (resultsReceived < resultsExpected && cmd_number <= 9) { -
101 String command = ""; -
102 command += address; -
103 command += "D"; -
104 command += cmd_number; -
105 command += "!"; // SDI-12 command to get data [address][D][dataOption][!] -
106 mySDI12.sendCommand(command, wake_delay); -
107 -
108 // uint32_t start = millis(); -
109 if (printCommands) { -
110 Serial.print(">>>"); -
111 Serial.println(command); -
112 } -
113 char resp_buffer[max_sdi_response] = {'\0'}; -
114 -
115 // read bytes into the char array until we get to a new line (\r\n) -
116 size_t bytes_read = mySDI12.readBytesUntil('\n', resp_buffer, max_sdi_response); -
117 // Serial.print(bytes_read); -
118 // Serial.println(" characters"); -
119 -
120 size_t data_bytes_read = bytes_read - 1; // subtract one for the /r before the /n -
121 String sdiResponse = String(resp_buffer); -
122 compiled_response += sdiResponse; -
123 sdiResponse.trim(); -
124 if (printCommands) { -
125 Serial.print("<<<"); -
126 Serial.println(sdiResponse); -
127 // Serial.println(sdiResponse.length()); -
128 // Serial.print("<<<"); -
129 // Serial.println(resp_buffer); -
130 // Serial.println(strnlen(resp_buffer, max_sdi_response)); -
131 } -
132 // read and clear anything else from the buffer -
133 int extra_chars = 0; -
134 while (mySDI12.available()) { -
135 Serial.write(mySDI12.read()); -
136 extra_chars++; -
137 } -
138 if (extra_chars > 0) { -
139 Serial.print(extra_chars); -
140 Serial.println(" additional characters received."); -
141 } -
142 mySDI12.clearBuffer(); -
143 -
144 // check the address, break if it's incorrect -
145 char returned_address = resp_buffer[0]; -
146 if (returned_address != address) { -
147 if (printCommands) { -
148 Serial.println("Wrong address returned!"); -
149 Serial.print("Expected "); -
150 Serial.print(String(address)); -
151 Serial.print(" Got "); -
152 Serial.println(String(returned_address)); -
153 Serial.println(String(resp_buffer)); -
154 } -
155 success = false; -
156 return_result.addressMatch = false; -
157 break; -
158 } -
159 -
160 // check the crc, break if it's incorrect -
161 if (verify_crc) { -
162 bool crcMatch = mySDI12.verifyCRC(sdiResponse); -
163 data_bytes_read = data_bytes_read - 3; -
164 if (crcMatch) { -
165 if (printCommands) { Serial.println("CRC valid"); } -
166 } else { -
167 if (printCommands) { Serial.println("CRC check failed!"); } -
168 return_result.crcMatch = false; -
169 success = false; -
170 break; -
171 } -
172 } -
173 -
174 bool gotResults = false; -
175 char float_buffer[max_sdi_digits] = {'\0'}; -
176 char* dec_pl = float_buffer; -
177 uint8_t fb_pos = 0; // start at start of buffer -
178 bool finished_last_number = false; -
179 // iterate through the char array and to check results -
180 // NOTE: start at 1 since we already looked at the address! -
181 for (size_t i = 1; i < data_bytes_read; i++) { -
182 // Get the character at position -
183 char c = resp_buffer[i]; -
184 // Serial.print(i); -
185 // Serial.print(" of "); -
186 // Serial.print(data_bytes_read); -
187 // Serial.print(" '"); -
188 // Serial.print(c); -
189 // Serial.println("'"); -
190 // if we didn't get something number-esque or we're at the end of the buffer, -
191 // assume the last number finished and parse it -
192 //(c != '-' && (c < '0' || c > '9') && c != '.') -
193 if (c == '-' || (c >= '0' && c <= '9') || c == '.') { -
194 // if there's a number, a decimal, or a negative sign next in the -
195 // buffer, add it to the float buffer. -
196 float_buffer[fb_pos] = c; -
197 fb_pos++; -
198 float_buffer[fb_pos] = '\0'; // null terminate the buffer -
199 finished_last_number = false; -
200 // Serial.print("Added to float buffer, currently: '"); -
201 // Serial.print(float_buffer); -
202 // Serial.println("'"); -
203 } else { -
204 // Serial.println("Non Numeric"); -
205 finished_last_number = true; -
206 } -
207 // if we've gotten to the end of a number or the end of the buffer, parse the -
208 // character -
209 if ((finished_last_number || i == data_bytes_read - 1) && -
210 strnlen(float_buffer, max_sdi_digits) > 0) { -
211 float result = atof(float_buffer); -
212 if (printCommands) { -
213 Serial.print("Result "); -
214 Serial.print(resultsReceived); -
215 Serial.print(", Raw value: "); -
216 Serial.print(float_buffer); -
217 dec_pl = strchr(float_buffer, '.'); -
218 size_t len_post_dec = 0; -
219 if (dec_pl != nullptr) { len_post_dec = strnlen(dec_pl, max_sdi_digits) - 1; } -
220 Serial.print(", Len after decimal: "); -
221 Serial.print(len_post_dec); -
222 Serial.print(", Parsed value: "); -
223 Serial.println(String(result, len_post_dec)); -
224 } -
225 // add how many results we have -
226 if (result != -9999) { -
227 gotResults = true; -
228 resultsReceived++; -
229 } -
230 // check for a failure error code at the end -
231 if (error_result_number >= 1) { -
232 if (resultsReceived == error_result_number && result != no_error_value) { -
233 success = false; -
234 return_result.errorCode = true; -
235 if (printCommands) { -
236 Serial.print("Got a failure code of "); -
237 Serial.println(String(result, strnlen(dec_pl, max_sdi_digits) - 1)); -
238 } -
239 } -
240 } -
241 -
242 // empty the buffer -
243 float_buffer[0] = '\0'; -
244 fb_pos = 0; -
245 } -
246 } -
247 -
248 if (!gotResults) { -
249 if (printCommands) { -
250 Serial.println((" No results received, will not continue requests!")); -
251 } -
252 break; -
253 } // don't do another loop if we got nothing -
254 -
255 if (printCommands) { -
256 Serial.print("Total Results Received: "); -
257 Serial.print(resultsReceived); -
258 Serial.print(", Remaining: "); -
259 Serial.println(resultsExpected - resultsReceived); -
260 } -
261 -
262 cmd_number++; -
263 } -
264 -
265 mySDI12.clearBuffer(); -
266 -
267 if (printCommands) { -
268 Serial.print("After "); -
269 Serial.print(cmd_number); -
270 Serial.print(" data commands got "); -
271 Serial.print(resultsReceived); -
272 Serial.print(" results of the expected "); -
273 Serial.print(resultsExpected); -
274 Serial.print(" expected. This is a "); -
275 Serial.println(resultsReceived == resultsExpected ? "success." : "failure."); -
276 } -
277 -
278 success &= resultsReceived == resultsExpected; -
279 return_result.resultsReceived = resultsReceived; -
280 return_result.maxDataCommand = cmd_number; -
281 return_result.success = success; -
282 return return_result; -
283} -
284 -
285startMeasurementResult startMeasurement(char address, bool is_concurrent = false, -
286 bool request_crc = false, String meas_type = "", -
287 bool printCommands = true) { -
288 // Create the return struct -
289 startMeasurementResult return_result; -
290 return_result.returned_address = ""; -
291 return_result.meas_time_s = 0; -
292 return_result.numberResults = 0; -
293 -
294 String command = ""; -
295 command += address; // All commands start with the address -
296 command += is_concurrent ? "C" : "M"; // C for concurrent, M for standard -
297 command += request_crc ? "C" : ""; // add an additional C to request a CRC -
298 command += meas_type; // Measurement type, "" or 0-9 -
299 command += "!"; // All commands end with "!" -
300 mySDI12.sendCommand(command, wake_delay); -
301 if (printCommands) { -
302 Serial.print(">>>"); -
303 Serial.println(command); -
304 } -
305 -
306 // wait for acknowlegement with format [address][ttt (3 char, seconds)][number of -
307 // measurments available, 0-9] -
308 String sdiResponse = mySDI12.readStringUntil('\n'); -
309 sdiResponse.trim(); -
310 if (printCommands) { -
311 Serial.print("<<<"); -
312 Serial.println(sdiResponse); -
313 } -
314 mySDI12.clearBuffer(); -
315 -
316 // check the address, return if it's incorrect -
317 String returned_address = sdiResponse.substring(0, 1); -
318 char ret_addr_array[2]; -
319 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array)); -
320 return_result.returned_address = ret_addr_array[0]; -
321 if (returned_address != String(address)) { -
322 if (printCommands) { -
323 Serial.println("Wrong address returned!"); -
324 Serial.print("Expected "); -
325 Serial.print(String(address)); -
326 Serial.print(" Got "); -
327 Serial.println(returned_address); -
328 } -
329 return return_result; -
330 } -
331 -
332 // find out how long we have to wait (in seconds). -
333 uint8_t meas_time_s = sdiResponse.substring(1, 4).toInt(); -
334 return_result.meas_time_s = meas_time_s; -
335 if (printCommands) { -
336 Serial.print("expected measurement time: "); -
337 Serial.print(meas_time_s); -
338 Serial.print(" s, "); -
339 } -
340 -
341 // Set up the number of results to expect -
342 int numResults = sdiResponse.substring(4).toInt(); -
343 return_result.numberResults = numResults; -
344 if (printCommands) { -
345 Serial.print("Number Results: "); -
346 Serial.println(numResults); -
347 } -
348 -
349 return return_result; -
350} -
351 -
352uint32_t takeMeasurement(char address, bool request_crc = false, String meas_type = "", -
353 bool printCommands = true) { -
354 startMeasurementResult startResult = startMeasurement(address, false, request_crc, -
355 meas_type, printCommands); -
356 if (startResult.numberResults == 0) { return -1; } -
357 -
358 uint32_t timerStart = millis(); -
359 uint32_t measTime = -1; -
360 // wait up to 1 second longer than the specified return time -
361 while ((millis() - timerStart) < -
362 (static_cast<uint32_t>(startResult.meas_time_s) + 1) * 1000) { -
363 if (mySDI12.available()) { -
364 break; -
365 } // sensor can interrupt us to let us know it is done early -
366 } -
367 measTime = millis() - timerStart; -
368 String interrupt_response = mySDI12.readStringUntil('\n'); -
369 if (printCommands) { -
370 Serial.print("<<<"); -
371 Serial.println(interrupt_response); -
372 Serial.print("Completed after "); -
373 Serial.print(measTime); -
374 Serial.println(" ms"); -
375 } -
376 -
377 // if we got results, return the measurement time, else -1 -
378 if (getResults(address, startResult.numberResults, request_crc, printCommands) -
379 .success) { -
380 return measTime; -
381 } -
382 -
383 return -1; -
384} -
385 -
386// this checks for activity at a particular address -
387// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z' -
388bool checkActive(char address, int8_t numPings = 3, bool printCommands = true) { -
389 String command = ""; -
390 command += (char)address; // sends basic 'acknowledge' command [address][!] -
391 command += "!"; -
392 -
393 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts -
394 if (printCommands) { -
395 Serial.print(">>>"); -
396 Serial.println(command); -
397 } -
398 mySDI12.sendCommand(command, wake_delay); -
399 -
400 // the sensor should just return its address -
401 String sdiResponse = mySDI12.readStringUntil('\n'); -
402 sdiResponse.trim(); -
403 if (printCommands) { -
404 Serial.print("<<<"); -
405 Serial.println(sdiResponse); -
406 } -
407 mySDI12.clearBuffer(); -
408 -
409 // check the address, return false if it's incorrect -
410 String returned_address = sdiResponse.substring(0, 1); -
411 char ret_addr_array[2]; -
412 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array)); -
413 if (returned_address == String(address)) { return true; } -
414 } -
415 mySDI12.clearBuffer(); -
416 return false; -
417} -
418 -
419/** -
420 * @brief gets identification information from a sensor, and prints it to the serial -
421 * port -
422 * -
423 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'. -
424 * @param printCommands true to print the raw output and input from the command -
425 */ -
426bool printInfo(char i, bool printCommands = true) { -
427 String command = ""; -
428 command += (char)i; -
429 command += "I!"; -
430 mySDI12.sendCommand(command, wake_delay); -
431 if (printCommands) { -
432 Serial.print(">>>"); -
433 Serial.println(command); -
434 } -
435 delay(100); -
436 -
437 String sdiResponse = mySDI12.readStringUntil('\n'); -
438 sdiResponse.trim(); -
439 // allccccccccmmmmmmvvvxxx...xx<CR><LF> -
440 if (printCommands) { -
441 Serial.print("<<<"); -
442 Serial.println(sdiResponse); -
443 } -
444 -
445 Serial.print("Address: "); -
446 Serial.print(sdiResponse.substring(0, 1)); // address -
447 Serial.print(", SDI-12 Version: "); -
448 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number -
449 Serial.print(", Vendor ID: "); -
450 Serial.print(sdiResponse.substring(3, 11)); // vendor id -
451 Serial.print(", Sensor Model: "); -
452 Serial.print(sdiResponse.substring(11, 17)); // sensor model -
453 Serial.print(", Sensor Version: "); -
454 Serial.print(sdiResponse.substring(17, 20)); // sensor version -
455 Serial.print(", Sensor ID: "); -
456 Serial.print(sdiResponse.substring(20)); // sensor id -
457 Serial.println(); -
458 -
459 if (sdiResponse.length() < 3) { return false; }; -
460 return true; -
461} -
462 -
463void setup() { -
464 Serial.begin(serialBaud); -
465 while (!Serial) -
466 ; -
467 -
468 Serial.print("Opening SDI-12 bus on pin "); -
469 Serial.print(String(dataPin)); -
470 Serial.println("..."); -
471 mySDI12.begin(); -
472 delay(500); // allow things to settle -
473 -
474 Serial.println("Timeout value: "); -
475 Serial.println(mySDI12.TIMEOUT); -
476 -
477 // Power the sensors; -
478 if (powerPin >= 0 && !testPowerOff) { -
479 Serial.println("Powering up sensors with pin "); -
480 Serial.print(String(powerPin)); -
481 Serial.println(", wait 30s..."); -
482 pinMode(powerPin, OUTPUT); -
483 digitalWrite(powerPin, HIGH); -
484 delay(30000L); -
485 } else { -
486 Serial.println("Wait 5s..."); -
487 delay(5000L); -
488 } -
489} -
490 -
491void loop() { -
492 bool got_good_results = true; -
493 int checks_at_time = 0; -
494 while (got_good_results && checks_at_time < 25) { -
495 Serial.print("Repeat attempt "); -
496 Serial.print(checks_at_time); -
497 Serial.print(" with power on warm-up time of "); -
498 Serial.println(power_delay); -
499 -
500 // Power down the sensors; -
501 if (powerPin >= 0 && testPowerOff) { -
502 Serial.print("Powering down sensors, wait "); -
503 Serial.print(power_off_time); -
504 Serial.println(" ms"); -
505 pinMode(powerPin, OUTPUT); -
506 digitalWrite(powerPin, LOW); -
507 delay(power_off_time); -
508 } -
509 -
510 // Power up the sensors; -
511 if (powerPin >= 0 && testPowerOff) { -
512 Serial.print("Powering up sensors, wait "); -
513 Serial.print(power_delay); -
514 Serial.println(" ms"); -
515 pinMode(powerPin, OUTPUT); -
516 digitalWrite(powerPin, HIGH); -
517 delay(power_delay); -
518 mySDI12.clearBuffer(); -
519 } -
520 -
521 // checkActive(sensorAddress, true); -
522 -
523 uint32_t this_meas_time = takeMeasurement(sensorAddress, true, "", true); -
524 bool this_result_good = this_meas_time != static_cast<uint32_t>(-1); -
525 -
526 if (this_result_good) { -
527 total_meas_time += this_meas_time; -
528 total_meas_made++; -
529 if (this_meas_time > max_meas_time) { max_meas_time = this_meas_time; } -
530 Serial.print("Warm-up Time: "); -
531 Serial.print(power_delay); -
532 Serial.print(", This measurement time: "); -
533 Serial.print(this_meas_time); -
534 Serial.print(", Mean measurement time: "); -
535 Serial.print(total_meas_time / total_meas_made); -
536 Serial.print(", Max measurement time: "); -
537 Serial.println(max_meas_time); -
538 } -
539 -
540 got_good_results &= this_result_good; -
541 checks_at_time++; -
542 -
543 if (!got_good_results) { -
544 Serial.print("Time check failed after "); -
545 Serial.print(checks_at_time); -
546 Serial.println(" reps"); -
547 total_meas_time = 0; -
548 total_meas_made = 0; -
549 max_meas_time = 0; -
550 } -
551 } -
552 -
553 // if we got a good result 25x at this warm-up, keep testing how long the -
554 // measurements take -
555 while (got_good_results) { -
556 uint32_t this_meas_time = takeMeasurement(sensorAddress, true, "", false); -
557 if (this_meas_time != static_cast<uint32_t>(-1)) { -
558 total_meas_time += this_meas_time; -
559 total_meas_made++; -
560 if (this_meas_time > max_meas_time) { max_meas_time = this_meas_time; } -
561 Serial.print("Warm-up Time: "); -
562 Serial.print(power_delay); -
563 Serial.print(", This measurement time: "); -
564 Serial.print(this_meas_time); -
565 Serial.print(", Mean measurement time: "); -
566 Serial.print(total_meas_time / total_meas_made); -
567 Serial.print(", Max measurement time: "); -
568 Serial.println(max_meas_time); -
569 } -
570 } -
571 -
572 -
573 Serial.println("-------------------------------------------------------------------" -
574 "------------"); -
575 if (power_delay > max_power_delay) { -
576 power_delay = min_power_delay; -
577 } else { -
578 power_delay = power_delay + increment_power_delay; -
579 } -
580} -
- -
-
- -
-
-
-
- - - - - -
- -
-
- - - diff --git a/_test_sensor_timing_8ino-example.json b/_test_sensor_timing_8ino-example.json deleted file mode 100644 index 8314f7e..0000000 --- a/_test_sensor_timing_8ino-example.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "version": "1.12.0", - "compound": { - "kind": "example", - "id": "_test_sensor_timing_8ino-example", - "name": "TestSensorTiming.ino", - "url_base": "_test_sensor_timing_8ino-example", - "url": "_test_sensor_timing_8ino-example.html", - "include": null, - "has_template_details": false, - "templates": null, - "brief": "", - "description": "
1/**\n
2 * @example{lineno} TestSensorTiming.ino\n
3 * @copyright Stroud Water Research Center\n
4 * @license This example is published under the BSD-3 license.\n
5 * @author Sara Damiano <sdamiano@stroudcenter.org>\n
6 * @date March 2024\n
7 */\n
8\n
9#include <SDI12.h>\n
10\n
11#ifndef SDI12_DATA_PIN\n
12#define SDI12_DATA_PIN 7\n
13#endif\n
14#ifndef SDI12_POWER_PIN\n
15#define SDI12_POWER_PIN 22\n
16#endif\n
17\n
18/* connection information */\n
19uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */\n
20int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */\n
21int8_t powerPin =\n
22 SDI12_POWER_PIN; /*!< The sensor power pin (or -1 if not switching power) */\n
23uint32_t wake_delay = 0; /*!< Extra time needed for the sensor to wake (0-100ms) */\n
24char sensorAddress = '0'; /*!< The address of the SDI-12 sensor */\n
25\n
26/** Define the SDI-12 bus */\n
27SDI12 mySDI12(dataPin);\n
28\n
29/** Define some testing specs */\n
30\n
31/** Error codes, if returned */\n
32int8_t error_result_number = 7;\n
33float no_error_value = 0;\n
34\n
35/** Testing turning off power */\n
36bool testPowerOff = false;\n
37int32_t min_power_delay = 100L; /*!< The min time to test wake after power on. */\n
38int32_t max_power_delay = 180000L; /*!< The max time to test wake after power on. */\n
39int32_t increment_power_delay = 100L; /*!< The time to lengthen waits between reps. */\n
40int32_t power_off_time = 60000L; /*!< The time to power off between tests. */\n
41/** NOTE: set the power off time to be something similar to what you will be using the\n
42 * the real world! Some sensors take longer to warm up if they've been off for a while.\n
43 */\n
44\n
45/** Testing the length of the break */\n
46bool testBreak = true;\n
47int32_t min_wake_delay = 0; /*!< The min time to test wake after a line break. */\n
48int32_t max_wake_delay = 100; /*!< The max time to test wake (should be <=100). */\n
49int32_t increment_wake = 5; /*!< The time to lengthen waits between reps. */\n
50\n
51/** set some initial values */\n
52int32_t power_delay = min_power_delay;\n
53int32_t wake_delay = min_wake_delay;\n
54\n
55int32_t total_meas_time = 0;\n
56int32_t total_meas_made = 0;\n
57uint32_t max_meas_time = 0;\n
58\n
59struct startMeasurementResult { // Structure declaration\n
60 String returned_address;\n
61 uint8_t meas_time_s;\n
62 int numberResults;\n
63};\n
64\n
65struct getResultsResult { // Structure declaration\n
66 uint8_t resultsReceived;\n
67 uint8_t maxDataCommand;\n
68 bool addressMatch;\n
69 bool crcMatch;\n
70 bool errorCode;\n
71 bool success;\n
72};\n
73\n
74getResultsResult getResults(char address, int resultsExpected, bool verify_crc = false,\n
75 bool printCommands = true) {\n
76 uint8_t resultsReceived = 0;\n
77 uint8_t cmd_number = 0;\n
78 // The maximum number of characters that can be returned in the <values> part of the\n
79 // response to a D command is either 35 or 75. If the D command is issued to\n
80 // retrieve data in response to a concurrent measurement command, or in response to\n
81 // a high-volume ASCII measurement command, the maximum is 75. The maximum is also\n
82 // 75 in response to a continuous measurement command. Otherwise, the maximum is 35.\n
83 int max_sdi_response = 76;\n
84 // max chars in a unsigned 64 bit number\n
85 int max_sdi_digits = 21;\n
86\n
87 String compiled_response = "";\n
88\n
89 bool success = true;\n
90\n
91 // Create the return struct\n
92 getResultsResult return_result;\n
93 return_result.resultsReceived = 0;\n
94 return_result.maxDataCommand = 0;\n
95 return_result.addressMatch = true;\n
96 return_result.crcMatch = true;\n
97 return_result.errorCode = false;\n
98 return_result.success = true;\n
99\n
100 while (resultsReceived < resultsExpected && cmd_number <= 9) {\n
101 String command = "";\n
102 command += address;\n
103 command += "D";\n
104 command += cmd_number;\n
105 command += "!"; // SDI-12 command to get data [address][D][dataOption][!]\n
106 mySDI12.sendCommand(command, wake_delay);\n
107\n
108 // uint32_t start = millis();\n
109 if (printCommands) {\n
110 Serial.print(">>>");\n
111 Serial.println(command);\n
112 }\n
113 char resp_buffer[max_sdi_response] = {'\\0'};\n
114\n
115 // read bytes into the char array until we get to a new line (\\r\\n)\n
116 size_t bytes_read = mySDI12.readBytesUntil('\\n', resp_buffer, max_sdi_response);\n
117 // Serial.print(bytes_read);\n
118 // Serial.println(" characters");\n
119\n
120 size_t data_bytes_read = bytes_read - 1; // subtract one for the /r before the /n\n
121 String sdiResponse = String(resp_buffer);\n
122 compiled_response += sdiResponse;\n
123 sdiResponse.trim();\n
124 if (printCommands) {\n
125 Serial.print("<<<");\n
126 Serial.println(sdiResponse);\n
127 // Serial.println(sdiResponse.length());\n
128 // Serial.print("<<<");\n
129 // Serial.println(resp_buffer);\n
130 // Serial.println(strnlen(resp_buffer, max_sdi_response));\n
131 }\n
132 // read and clear anything else from the buffer\n
133 int extra_chars = 0;\n
134 while (mySDI12.available()) {\n
135 Serial.write(mySDI12.read());\n
136 extra_chars++;\n
137 }\n
138 if (extra_chars > 0) {\n
139 Serial.print(extra_chars);\n
140 Serial.println(" additional characters received.");\n
141 }\n
142 mySDI12.clearBuffer();\n
143\n
144 // check the address, break if it's incorrect\n
145 char returned_address = resp_buffer[0];\n
146 if (returned_address != address) {\n
147 if (printCommands) {\n
148 Serial.println("Wrong address returned!");\n
149 Serial.print("Expected ");\n
150 Serial.print(String(address));\n
151 Serial.print(" Got ");\n
152 Serial.println(String(returned_address));\n
153 Serial.println(String(resp_buffer));\n
154 }\n
155 success = false;\n
156 return_result.addressMatch = false;\n
157 break;\n
158 }\n
159\n
160 // check the crc, break if it's incorrect\n
161 if (verify_crc) {\n
162 bool crcMatch = mySDI12.verifyCRC(sdiResponse);\n
163 data_bytes_read = data_bytes_read - 3;\n
164 if (crcMatch) {\n
165 if (printCommands) { Serial.println("CRC valid"); }\n
166 } else {\n
167 if (printCommands) { Serial.println("CRC check failed!"); }\n
168 return_result.crcMatch = false;\n
169 success = false;\n
170 break;\n
171 }\n
172 }\n
173\n
174 bool gotResults = false;\n
175 char float_buffer[max_sdi_digits] = {'\\0'};\n
176 char* dec_pl = float_buffer;\n
177 uint8_t fb_pos = 0; // start at start of buffer\n
178 bool finished_last_number = false;\n
179 // iterate through the char array and to check results\n
180 // NOTE: start at 1 since we already looked at the address!\n
181 for (size_t i = 1; i < data_bytes_read; i++) {\n
182 // Get the character at position\n
183 char c = resp_buffer[i];\n
184 // Serial.print(i);\n
185 // Serial.print(" of ");\n
186 // Serial.print(data_bytes_read);\n
187 // Serial.print(" '");\n
188 // Serial.print(c);\n
189 // Serial.println("'");\n
190 // if we didn't get something number-esque or we're at the end of the buffer,\n
191 // assume the last number finished and parse it\n
192 //(c != '-' && (c < '0' || c > '9') && c != '.')\n
193 if (c == '-' || (c >= '0' && c <= '9') || c == '.') {\n
194 // if there's a number, a decimal, or a negative sign next in the\n
195 // buffer, add it to the float buffer.\n
196 float_buffer[fb_pos] = c;\n
197 fb_pos++;\n
198 float_buffer[fb_pos] = '\\0'; // null terminate the buffer\n
199 finished_last_number = false;\n
200 // Serial.print("Added to float buffer, currently: '");\n
201 // Serial.print(float_buffer);\n
202 // Serial.println("'");\n
203 } else {\n
204 // Serial.println("Non Numeric");\n
205 finished_last_number = true;\n
206 }\n
207 // if we've gotten to the end of a number or the end of the buffer, parse the\n
208 // character\n
209 if ((finished_last_number || i == data_bytes_read - 1) &&\n
210 strnlen(float_buffer, max_sdi_digits) > 0) {\n
211 float result = atof(float_buffer);\n
212 if (printCommands) {\n
213 Serial.print("Result ");\n
214 Serial.print(resultsReceived);\n
215 Serial.print(", Raw value: ");\n
216 Serial.print(float_buffer);\n
217 dec_pl = strchr(float_buffer, '.');\n
218 size_t len_post_dec = 0;\n
219 if (dec_pl != nullptr) { len_post_dec = strnlen(dec_pl, max_sdi_digits) - 1; }\n
220 Serial.print(", Len after decimal: ");\n
221 Serial.print(len_post_dec);\n
222 Serial.print(", Parsed value: ");\n
223 Serial.println(String(result, len_post_dec));\n
224 }\n
225 // add how many results we have\n
226 if (result != -9999) {\n
227 gotResults = true;\n
228 resultsReceived++;\n
229 }\n
230 // check for a failure error code at the end\n
231 if (error_result_number >= 1) {\n
232 if (resultsReceived == error_result_number && result != no_error_value) {\n
233 success = false;\n
234 return_result.errorCode = true;\n
235 if (printCommands) {\n
236 Serial.print("Got a failure code of ");\n
237 Serial.println(String(result, strnlen(dec_pl, max_sdi_digits) - 1));\n
238 }\n
239 }\n
240 }\n
241\n
242 // empty the buffer\n
243 float_buffer[0] = '\\0';\n
244 fb_pos = 0;\n
245 }\n
246 }\n
247\n
248 if (!gotResults) {\n
249 if (printCommands) {\n
250 Serial.println((" No results received, will not continue requests!"));\n
251 }\n
252 break;\n
253 } // don't do another loop if we got nothing\n
254\n
255 if (printCommands) {\n
256 Serial.print("Total Results Received: ");\n
257 Serial.print(resultsReceived);\n
258 Serial.print(", Remaining: ");\n
259 Serial.println(resultsExpected - resultsReceived);\n
260 }\n
261\n
262 cmd_number++;\n
263 }\n
264\n
265 mySDI12.clearBuffer();\n
266\n
267 if (printCommands) {\n
268 Serial.print("After ");\n
269 Serial.print(cmd_number);\n
270 Serial.print(" data commands got ");\n
271 Serial.print(resultsReceived);\n
272 Serial.print(" results of the expected ");\n
273 Serial.print(resultsExpected);\n
274 Serial.print(" expected. This is a ");\n
275 Serial.println(resultsReceived == resultsExpected ? "success." : "failure.");\n
276 }\n
277\n
278 success &= resultsReceived == resultsExpected;\n
279 return_result.resultsReceived = resultsReceived;\n
280 return_result.maxDataCommand = cmd_number;\n
281 return_result.success = success;\n
282 return return_result;\n
283}\n
284\n
285startMeasurementResult startMeasurement(char address, bool is_concurrent = false,\n
286 bool request_crc = false, String meas_type = "",\n
287 bool printCommands = true) {\n
288 // Create the return struct\n
289 startMeasurementResult return_result;\n
290 return_result.returned_address = "";\n
291 return_result.meas_time_s = 0;\n
292 return_result.numberResults = 0;\n
293\n
294 String command = "";\n
295 command += address; // All commands start with the address\n
296 command += is_concurrent ? "C" : "M"; // C for concurrent, M for standard\n
297 command += request_crc ? "C" : ""; // add an additional C to request a CRC\n
298 command += meas_type; // Measurement type, "" or 0-9\n
299 command += "!"; // All commands end with "!"\n
300 mySDI12.sendCommand(command, wake_delay);\n
301 if (printCommands) {\n
302 Serial.print(">>>");\n
303 Serial.println(command);\n
304 }\n
305\n
306 // wait for acknowlegement with format [address][ttt (3 char, seconds)][number of\n
307 // measurments available, 0-9]\n
308 String sdiResponse = mySDI12.readStringUntil('\\n');\n
309 sdiResponse.trim();\n
310 if (printCommands) {\n
311 Serial.print("<<<");\n
312 Serial.println(sdiResponse);\n
313 }\n
314 mySDI12.clearBuffer();\n
315\n
316 // check the address, return if it's incorrect\n
317 String returned_address = sdiResponse.substring(0, 1);\n
318 char ret_addr_array[2];\n
319 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array));\n
320 return_result.returned_address = ret_addr_array[0];\n
321 if (returned_address != String(address)) {\n
322 if (printCommands) {\n
323 Serial.println("Wrong address returned!");\n
324 Serial.print("Expected ");\n
325 Serial.print(String(address));\n
326 Serial.print(" Got ");\n
327 Serial.println(returned_address);\n
328 }\n
329 return return_result;\n
330 }\n
331\n
332 // find out how long we have to wait (in seconds).\n
333 uint8_t meas_time_s = sdiResponse.substring(1, 4).toInt();\n
334 return_result.meas_time_s = meas_time_s;\n
335 if (printCommands) {\n
336 Serial.print("expected measurement time: ");\n
337 Serial.print(meas_time_s);\n
338 Serial.print(" s, ");\n
339 }\n
340\n
341 // Set up the number of results to expect\n
342 int numResults = sdiResponse.substring(4).toInt();\n
343 return_result.numberResults = numResults;\n
344 if (printCommands) {\n
345 Serial.print("Number Results: ");\n
346 Serial.println(numResults);\n
347 }\n
348\n
349 return return_result;\n
350}\n
351\n
352uint32_t takeMeasurement(char address, bool request_crc = false, String meas_type = "",\n
353 bool printCommands = true) {\n
354 startMeasurementResult startResult = startMeasurement(address, false, request_crc,\n
355 meas_type, printCommands);\n
356 if (startResult.numberResults == 0) { return -1; }\n
357\n
358 uint32_t timerStart = millis();\n
359 uint32_t measTime = -1;\n
360 // wait up to 1 second longer than the specified return time\n
361 while ((millis() - timerStart) <\n
362 (static_cast<uint32_t>(startResult.meas_time_s) + 1) * 1000) {\n
363 if (mySDI12.available()) {\n
364 break;\n
365 } // sensor can interrupt us to let us know it is done early\n
366 }\n
367 measTime = millis() - timerStart;\n
368 String interrupt_response = mySDI12.readStringUntil('\\n');\n
369 if (printCommands) {\n
370 Serial.print("<<<");\n
371 Serial.println(interrupt_response);\n
372 Serial.print("Completed after ");\n
373 Serial.print(measTime);\n
374 Serial.println(" ms");\n
375 }\n
376\n
377 // if we got results, return the measurement time, else -1\n
378 if (getResults(address, startResult.numberResults, request_crc, printCommands)\n
379 .success) {\n
380 return measTime;\n
381 }\n
382\n
383 return -1;\n
384}\n
385\n
386// this checks for activity at a particular address\n
387// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z'\n
388bool checkActive(char address, int8_t numPings = 3, bool printCommands = true) {\n
389 String command = "";\n
390 command += (char)address; // sends basic 'acknowledge' command [address][!]\n
391 command += "!";\n
392\n
393 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts\n
394 if (printCommands) {\n
395 Serial.print(">>>");\n
396 Serial.println(command);\n
397 }\n
398 mySDI12.sendCommand(command, wake_delay);\n
399\n
400 // the sensor should just return its address\n
401 String sdiResponse = mySDI12.readStringUntil('\\n');\n
402 sdiResponse.trim();\n
403 if (printCommands) {\n
404 Serial.print("<<<");\n
405 Serial.println(sdiResponse);\n
406 }\n
407 mySDI12.clearBuffer();\n
408\n
409 // check the address, return false if it's incorrect\n
410 String returned_address = sdiResponse.substring(0, 1);\n
411 char ret_addr_array[2];\n
412 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array));\n
413 if (returned_address == String(address)) { return true; }\n
414 }\n
415 mySDI12.clearBuffer();\n
416 return false;\n
417}\n
418\n
419/**\n
420 * @brief gets identification information from a sensor, and prints it to the serial\n
421 * port\n
422 *\n
423 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'.\n
424 * @param printCommands true to print the raw output and input from the command\n
425 */\n
426bool printInfo(char i, bool printCommands = true) {\n
427 String command = "";\n
428 command += (char)i;\n
429 command += "I!";\n
430 mySDI12.sendCommand(command, wake_delay);\n
431 if (printCommands) {\n
432 Serial.print(">>>");\n
433 Serial.println(command);\n
434 }\n
435 delay(100);\n
436\n
437 String sdiResponse = mySDI12.readStringUntil('\\n');\n
438 sdiResponse.trim();\n
439 // allccccccccmmmmmmvvvxxx...xx<CR><LF>\n
440 if (printCommands) {\n
441 Serial.print("<<<");\n
442 Serial.println(sdiResponse);\n
443 }\n
444\n
445 Serial.print("Address: ");\n
446 Serial.print(sdiResponse.substring(0, 1)); // address\n
447 Serial.print(", SDI-12 Version: ");\n
448 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number\n
449 Serial.print(", Vendor ID: ");\n
450 Serial.print(sdiResponse.substring(3, 11)); // vendor id\n
451 Serial.print(", Sensor Model: ");\n
452 Serial.print(sdiResponse.substring(11, 17)); // sensor model\n
453 Serial.print(", Sensor Version: ");\n
454 Serial.print(sdiResponse.substring(17, 20)); // sensor version\n
455 Serial.print(", Sensor ID: ");\n
456 Serial.print(sdiResponse.substring(20)); // sensor id\n
457 Serial.println();\n
458\n
459 if (sdiResponse.length() < 3) { return false; };\n
460 return true;\n
461}\n
462\n
463void setup() {\n
464 Serial.begin(serialBaud);\n
465 while (!Serial)\n
466 ;\n
467\n
468 Serial.print("Opening SDI-12 bus on pin ");\n
469 Serial.print(String(dataPin));\n
470 Serial.println("...");\n
471 mySDI12.begin();\n
472 delay(500); // allow things to settle\n
473\n
474 Serial.println("Timeout value: ");\n
475 Serial.println(mySDI12.TIMEOUT);\n
476\n
477 // Power the sensors;\n
478 if (powerPin >= 0 && !testPowerOff) {\n
479 Serial.println("Powering up sensors with pin ");\n
480 Serial.print(String(powerPin));\n
481 Serial.println(", wait 30s...");\n
482 pinMode(powerPin, OUTPUT);\n
483 digitalWrite(powerPin, HIGH);\n
484 delay(30000L);\n
485 } else {\n
486 Serial.println("Wait 5s...");\n
487 delay(5000L);\n
488 }\n
489}\n
490\n
491void loop() {\n
492 bool got_good_results = true;\n
493 int checks_at_time = 0;\n
494 while (got_good_results && checks_at_time < 25) {\n
495 Serial.print("Repeat attempt ");\n
496 Serial.print(checks_at_time);\n
497 Serial.print(" with power on warm-up time of ");\n
498 Serial.println(power_delay);\n
499\n
500 // Power down the sensors;\n
501 if (powerPin >= 0 && testPowerOff) {\n
502 Serial.print("Powering down sensors, wait ");\n
503 Serial.print(power_off_time);\n
504 Serial.println(" ms");\n
505 pinMode(powerPin, OUTPUT);\n
506 digitalWrite(powerPin, LOW);\n
507 delay(power_off_time);\n
508 }\n
509\n
510 // Power up the sensors;\n
511 if (powerPin >= 0 && testPowerOff) {\n
512 Serial.print("Powering up sensors, wait ");\n
513 Serial.print(power_delay);\n
514 Serial.println(" ms");\n
515 pinMode(powerPin, OUTPUT);\n
516 digitalWrite(powerPin, HIGH);\n
517 delay(power_delay);\n
518 mySDI12.clearBuffer();\n
519 }\n
520\n
521 // checkActive(sensorAddress, true);\n
522\n
523 uint32_t this_meas_time = takeMeasurement(sensorAddress, true, "", true);\n
524 bool this_result_good = this_meas_time != static_cast<uint32_t>(-1);\n
525\n
526 if (this_result_good) {\n
527 total_meas_time += this_meas_time;\n
528 total_meas_made++;\n
529 if (this_meas_time > max_meas_time) { max_meas_time = this_meas_time; }\n
530 Serial.print("Warm-up Time: ");\n
531 Serial.print(power_delay);\n
532 Serial.print(", This measurement time: ");\n
533 Serial.print(this_meas_time);\n
534 Serial.print(", Mean measurement time: ");\n
535 Serial.print(total_meas_time / total_meas_made);\n
536 Serial.print(", Max measurement time: ");\n
537 Serial.println(max_meas_time);\n
538 }\n
539\n
540 got_good_results &= this_result_good;\n
541 checks_at_time++;\n
542\n
543 if (!got_good_results) {\n
544 Serial.print("Time check failed after ");\n
545 Serial.print(checks_at_time);\n
546 Serial.println(" reps");\n
547 total_meas_time = 0;\n
548 total_meas_made = 0;\n
549 max_meas_time = 0;\n
550 }\n
551 }\n
552\n
553 // if we got a good result 25x at this warm-up, keep testing how long the\n
554 // measurements take\n
555 while (got_good_results) {\n
556 uint32_t this_meas_time = takeMeasurement(sensorAddress, true, "", false);\n
557 if (this_meas_time != static_cast<uint32_t>(-1)) {\n
558 total_meas_time += this_meas_time;\n
559 total_meas_made++;\n
560 if (this_meas_time > max_meas_time) { max_meas_time = this_meas_time; }\n
561 Serial.print("Warm-up Time: ");\n
562 Serial.print(power_delay);\n
563 Serial.print(", This measurement time: ");\n
564 Serial.print(this_meas_time);\n
565 Serial.print(", Mean measurement time: ");\n
566 Serial.print(total_meas_time / total_meas_made);\n
567 Serial.print(", Max measurement time: ");\n
568 Serial.println(max_meas_time);\n
569 }\n
570 }\n
571\n
572\n
573 Serial.println("-------------------------------------------------------------------"\n
574 "------------");\n
575 if (power_delay > max_power_delay) {\n
576 power_delay = min_power_delay;\n
577 } else {\n
578 power_delay = power_delay + increment_power_delay;\n
579 }\n
580}\n
", - "sections": "", - "deprecated": null, - "since": null, - "example_navigation": null, - "footer_navigation": [ - [ - "_test_commands_8ino-example.html", - "TestCommands.ino" - ], - [ - "examples_page.html", - "Examples using the SDI-12 Library" - ], - [ - "_test_warm_up_8ino-example.html", - "TestWarmUp.ino" - ] - ], - "modules": [], - "dirs": [], - "files": [], - "namespaces": [], - "classes": [], - "base_classes": [], - "derived_classes": [], - "enums": [], - "typedefs": [], - "funcs": [], - "vars": [], - "defines": [], - "public_types": [], - "public_static_funcs": [], - "typeless_funcs": [], - "public_funcs": [], - "signals": [], - "public_slots": [], - "public_static_vars": [], - "public_vars": [], - "protected_types": [], - "protected_static_funcs": [], - "protected_funcs": [], - "protected_slots": [], - "protected_static_vars": [], - "protected_vars": [], - "private_funcs": [], - "private_slots": [], - "related": [], - "friend_funcs": [], - "groups": [], - "has_enum_details": false, - "has_typedef_details": false, - "has_func_details": false, - "has_var_details": false, - "has_define_details": false, - "breadcrumb": [ - [ - "Examples using the SDI-12 Library", - "examples_page.html" - ], - [ - "TestSensorTiming.ino", - "_test_sensor_timing_8ino-example.html" - ] - ] - } -} \ No newline at end of file diff --git a/_test_warm_up_8ino-example.html b/_test_warm_up_8ino-example.html deleted file mode 100644 index ad6122d..0000000 --- a/_test_warm_up_8ino-example.html +++ /dev/null @@ -1,1741 +0,0 @@ - - - - - Examples using the SDI-12 Library » TestWarmUp.ino example | SDI-12 for Arduino2.2.0 - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -
- -
- -
- -
-
-
-
- - -
-
- -
- - - - - -
- -
-
-
-
- -
-
- -
-

- TestWarmUp.ino example - - -

-
-
1/** -
2 * @example{lineno} TestWarmUp.ino -
3 * @copyright Stroud Water Research Center -
4 * @license This example is published under the BSD-3 license. -
5 * @author Sara Damiano <sdamiano@stroudcenter.org> -
6 * @date March 2021 -
7 */ -
8 -
9#include <SDI12.h> -
10 -
11/* connection information */ -
12uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */ -
13int8_t dataPin = 7; /*!< The pin of the SDI-12 data bus */ -
14char sensorAddress = '0'; /*!< The address of the SDI-12 sensor */ -
15int8_t powerPin = 22; /*!< The sensor power pin (or -1 if not switching power) */ -
16 -
17/** Define the SDI-12 bus */ -
18SDI12 mySDI12(dataPin); -
19 -
20/** Define some testing specs */ -
21 -
22/** Error codes, if returned */ -
23int8_t error_result_number = 7; -
24float no_error_value = 0; -
25 -
26/** Testing turning off power */ -
27int32_t min_power_delay = 100L; /*!< The min time to test wake after power on. */ -
28int32_t max_power_delay = 10000L; /*!< The max time to test wake after power on. */ -
29int32_t increment_power = 100; /*!< The time to lengthen waits between reps. */ -
30 -
31/** Testing the length of the break */ -
32int32_t min_wake_delay = 0; /*!< The min time to test wake after a line break. */ -
33int32_t max_wake_delay = 100; /*!< The max time to test wake (should be <=100). */ -
34int32_t increment_wake = 5; /*!< The time to lengthen waits between reps. */ -
35 -
36/** set some initial values */ -
37int32_t power_delay = min_power_delay; -
38int32_t wake_delay = min_wake_delay; -
39 -
40// this checks for activity at a particular address -
41// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z' -
42bool checkActive(char address, int8_t numPings = 3, bool printCommands = false) { -
43 String command = ""; -
44 command += (char)address; // sends basic 'acknowledge' command [address][!] -
45 command += "!"; -
46 -
47 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts -
48 if (printCommands) { -
49 Serial.print(">>>"); -
50 Serial.println(command); -
51 } -
52 mySDI12.sendCommand(command, wake_delay); -
53 -
54 // the sensor should just return its address -
55 String sdiResponse = mySDI12.readStringUntil('\n'); -
56 sdiResponse.trim(); -
57 if (printCommands) { -
58 Serial.print("<<<"); -
59 Serial.println(sdiResponse); -
60 } -
61 mySDI12.clearBuffer(); -
62 -
63 // check the address, return false if it's incorrect -
64 String returned_address = sdiResponse.substring(0, 1); -
65 char ret_addr_array[2]; -
66 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array)); -
67 if (returned_address == String(address)) { return true; } -
68 } -
69 mySDI12.clearBuffer(); -
70 return false; -
71} -
72 -
73/** -
74 * @brief gets identification information from a sensor, and prints it to the serial -
75 * port -
76 * -
77 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'. -
78 */ -
79bool printInfo(char i, bool printCommands = true) { -
80 String command = ""; -
81 command += (char)i; -
82 command += "I!"; -
83 mySDI12.sendCommand(command, wake_delay); -
84 if (printCommands) { -
85 Serial.print(">>>"); -
86 Serial.println(command); -
87 } -
88 delay(100); -
89 -
90 String sdiResponse = mySDI12.readStringUntil('\n'); -
91 sdiResponse.trim(); -
92 // allccccccccmmmmmmvvvxxx...xx<CR><LF> -
93 if (printCommands) { -
94 Serial.print("<<<"); -
95 Serial.println(sdiResponse); -
96 } -
97 -
98 Serial.print("Address: "); -
99 Serial.print(sdiResponse.substring(0, 1)); // address -
100 Serial.print(", SDI-12 Version: "); -
101 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number -
102 Serial.print(", Vendor ID: "); -
103 Serial.print(sdiResponse.substring(3, 11)); // vendor id -
104 Serial.print(", Sensor Model: "); -
105 Serial.print(sdiResponse.substring(11, 17)); // sensor model -
106 Serial.print(", Sensor Version: "); -
107 Serial.print(sdiResponse.substring(17, 20)); // sensor version -
108 Serial.print(", Sensor ID: "); -
109 Serial.print(sdiResponse.substring(20)); // sensor id -
110 Serial.println(); -
111 -
112 if (sdiResponse.length() < 3) { return false; }; -
113 return true; -
114} -
115 -
116void setup() { -
117 Serial.begin(serialBaud); -
118 while (!Serial) -
119 ; -
120 -
121 Serial.println("Opening SDI-12 bus..."); -
122 mySDI12.begin(); -
123 delay(500); // allow things to settle -
124 -
125 Serial.println("Timeout value: "); -
126 Serial.println(mySDI12.TIMEOUT); -
127} -
128 -
129void loop() { -
130 while (wake_delay <= max_wake_delay) { -
131 // Power the sensors; -
132 if (powerPin >= 0) { -
133 Serial.println("Powering down sensors..."); -
134 pinMode(powerPin, OUTPUT); -
135 digitalWrite(powerPin, LOW); -
136 delay(300000L); -
137 } -
138 -
139 // Power the sensors; -
140 if (powerPin >= 0) { -
141 Serial.println("Powering up sensors..."); -
142 pinMode(powerPin, OUTPUT); -
143 digitalWrite(powerPin, HIGH); -
144 delay(power_delay); -
145 mySDI12.clearBuffer(); -
146 } -
147 -
148 if (checkActive(sensorAddress, 1, true)) { -
149 Serial.print("Got some response after "); -
150 Serial.print(power_delay); -
151 Serial.print("ms after power with "); -
152 Serial.print(wake_delay); -
153 Serial.println("ms with wake delay"); -
154 if (printInfo(sensorAddress, true)) { -
155 // if we got sensor info, stop -
156 Serial.println("Looks good. Stopping."); -
157 while (1) -
158 ; -
159 } else { -
160 Serial.println("Sensor info not valid!"); -
161 } -
162 } else { -
163 Serial.print("No response after "); -
164 Serial.print(power_delay); -
165 Serial.print("ms after power with "); -
166 Serial.print(wake_delay); -
167 Serial.println("ms with wake delay"); -
168 } -
169 Serial.println("-------------------------------------------------------------------" -
170 "------------"); -
171 } -
172 power_delay = power_delay + increment_power; -
173 if (power_delay > max_power_delay) { -
174 Serial.println("FINISHED!!"); -
175 while (1) {} -
176 } -
177} -
- -
-
- -
-
-
-
- - - - - -
- -
-
- - - diff --git a/_test_warm_up_8ino-example.json b/_test_warm_up_8ino-example.json deleted file mode 100644 index 5751040..0000000 --- a/_test_warm_up_8ino-example.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "version": "1.12.0", - "compound": { - "kind": "example", - "id": "_test_warm_up_8ino-example", - "name": "TestWarmUp.ino", - "url_base": "_test_warm_up_8ino-example", - "url": "_test_warm_up_8ino-example.html", - "include": null, - "has_template_details": false, - "templates": null, - "brief": "", - "description": "
1/**\n
2 * @example{lineno} TestWarmUp.ino\n
3 * @copyright Stroud Water Research Center\n
4 * @license This example is published under the BSD-3 license.\n
5 * @author Sara Damiano <sdamiano@stroudcenter.org>\n
6 * @date March 2021\n
7 */\n
8\n
9#include <SDI12.h>\n
10\n
11/* connection information */\n
12uint32_t serialBaud = 115200; /*!< The baud rate for the output serial port */\n
13int8_t dataPin = 7; /*!< The pin of the SDI-12 data bus */\n
14char sensorAddress = '0'; /*!< The address of the SDI-12 sensor */\n
15int8_t powerPin = 22; /*!< The sensor power pin (or -1 if not switching power) */\n
16\n
17/** Define the SDI-12 bus */\n
18SDI12 mySDI12(dataPin);\n
19\n
20/** Define some testing specs */\n
21\n
22/** Error codes, if returned */\n
23int8_t error_result_number = 7;\n
24float no_error_value = 0;\n
25\n
26/** Testing turning off power */\n
27int32_t min_power_delay = 100L; /*!< The min time to test wake after power on. */\n
28int32_t max_power_delay = 10000L; /*!< The max time to test wake after power on. */\n
29int32_t increment_power = 100; /*!< The time to lengthen waits between reps. */\n
30\n
31/** Testing the length of the break */\n
32int32_t min_wake_delay = 0; /*!< The min time to test wake after a line break. */\n
33int32_t max_wake_delay = 100; /*!< The max time to test wake (should be <=100). */\n
34int32_t increment_wake = 5; /*!< The time to lengthen waits between reps. */\n
35\n
36/** set some initial values */\n
37int32_t power_delay = min_power_delay;\n
38int32_t wake_delay = min_wake_delay;\n
39\n
40// this checks for activity at a particular address\n
41// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z'\n
42bool checkActive(char address, int8_t numPings = 3, bool printCommands = false) {\n
43 String command = "";\n
44 command += (char)address; // sends basic 'acknowledge' command [address][!]\n
45 command += "!";\n
46\n
47 for (int j = 0; j < numPings; j++) { // goes through three rapid contact attempts\n
48 if (printCommands) {\n
49 Serial.print(">>>");\n
50 Serial.println(command);\n
51 }\n
52 mySDI12.sendCommand(command, wake_delay);\n
53\n
54 // the sensor should just return its address\n
55 String sdiResponse = mySDI12.readStringUntil('\\n');\n
56 sdiResponse.trim();\n
57 if (printCommands) {\n
58 Serial.print("<<<");\n
59 Serial.println(sdiResponse);\n
60 }\n
61 mySDI12.clearBuffer();\n
62\n
63 // check the address, return false if it's incorrect\n
64 String returned_address = sdiResponse.substring(0, 1);\n
65 char ret_addr_array[2];\n
66 returned_address.toCharArray(ret_addr_array, sizeof(ret_addr_array));\n
67 if (returned_address == String(address)) { return true; }\n
68 }\n
69 mySDI12.clearBuffer();\n
70 return false;\n
71}\n
72\n
73/**\n
74 * @brief gets identification information from a sensor, and prints it to the serial\n
75 * port\n
76 *\n
77 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'.\n
78 */\n
79bool printInfo(char i, bool printCommands = true) {\n
80 String command = "";\n
81 command += (char)i;\n
82 command += "I!";\n
83 mySDI12.sendCommand(command, wake_delay);\n
84 if (printCommands) {\n
85 Serial.print(">>>");\n
86 Serial.println(command);\n
87 }\n
88 delay(100);\n
89\n
90 String sdiResponse = mySDI12.readStringUntil('\\n');\n
91 sdiResponse.trim();\n
92 // allccccccccmmmmmmvvvxxx...xx<CR><LF>\n
93 if (printCommands) {\n
94 Serial.print("<<<");\n
95 Serial.println(sdiResponse);\n
96 }\n
97\n
98 Serial.print("Address: ");\n
99 Serial.print(sdiResponse.substring(0, 1)); // address\n
100 Serial.print(", SDI-12 Version: ");\n
101 Serial.print(sdiResponse.substring(1, 3).toFloat() / 10); // SDI-12 version number\n
102 Serial.print(", Vendor ID: ");\n
103 Serial.print(sdiResponse.substring(3, 11)); // vendor id\n
104 Serial.print(", Sensor Model: ");\n
105 Serial.print(sdiResponse.substring(11, 17)); // sensor model\n
106 Serial.print(", Sensor Version: ");\n
107 Serial.print(sdiResponse.substring(17, 20)); // sensor version\n
108 Serial.print(", Sensor ID: ");\n
109 Serial.print(sdiResponse.substring(20)); // sensor id\n
110 Serial.println();\n
111\n
112 if (sdiResponse.length() < 3) { return false; };\n
113 return true;\n
114}\n
115\n
116void setup() {\n
117 Serial.begin(serialBaud);\n
118 while (!Serial)\n
119 ;\n
120\n
121 Serial.println("Opening SDI-12 bus...");\n
122 mySDI12.begin();\n
123 delay(500); // allow things to settle\n
124\n
125 Serial.println("Timeout value: ");\n
126 Serial.println(mySDI12.TIMEOUT);\n
127}\n
128\n
129void loop() {\n
130 while (wake_delay <= max_wake_delay) {\n
131 // Power the sensors;\n
132 if (powerPin >= 0) {\n
133 Serial.println("Powering down sensors...");\n
134 pinMode(powerPin, OUTPUT);\n
135 digitalWrite(powerPin, LOW);\n
136 delay(300000L);\n
137 }\n
138\n
139 // Power the sensors;\n
140 if (powerPin >= 0) {\n
141 Serial.println("Powering up sensors...");\n
142 pinMode(powerPin, OUTPUT);\n
143 digitalWrite(powerPin, HIGH);\n
144 delay(power_delay);\n
145 mySDI12.clearBuffer();\n
146 }\n
147\n
148 if (checkActive(sensorAddress, 1, true)) {\n
149 Serial.print("Got some response after ");\n
150 Serial.print(power_delay);\n
151 Serial.print("ms after power with ");\n
152 Serial.print(wake_delay);\n
153 Serial.println("ms with wake delay");\n
154 if (printInfo(sensorAddress, true)) {\n
155 // if we got sensor info, stop\n
156 Serial.println("Looks good. Stopping.");\n
157 while (1)\n
158 ;\n
159 } else {\n
160 Serial.println("Sensor info not valid!");\n
161 }\n
162 } else {\n
163 Serial.print("No response after ");\n
164 Serial.print(power_delay);\n
165 Serial.print("ms after power with ");\n
166 Serial.print(wake_delay);\n
167 Serial.println("ms with wake delay");\n
168 }\n
169 Serial.println("-------------------------------------------------------------------"\n
170 "------------");\n
171 }\n
172 power_delay = power_delay + increment_power;\n
173 if (power_delay > max_power_delay) {\n
174 Serial.println("FINISHED!!");\n
175 while (1) {}\n
176 }\n
177}\n
", - "sections": "", - "deprecated": null, - "since": null, - "example_navigation": null, - "footer_navigation": [ - [ - "_test_sensor_timing_8ino-example.html", - "TestSensorTiming.ino" - ], - [ - "examples_page.html", - "Examples using the SDI-12 Library" - ], - null - ], - "modules": [], - "dirs": [], - "files": [], - "namespaces": [], - "classes": [], - "base_classes": [], - "derived_classes": [], - "enums": [], - "typedefs": [], - "funcs": [], - "vars": [], - "defines": [], - "public_types": [], - "public_static_funcs": [], - "typeless_funcs": [], - "public_funcs": [], - "signals": [], - "public_slots": [], - "public_static_vars": [], - "public_vars": [], - "protected_types": [], - "protected_static_funcs": [], - "protected_funcs": [], - "protected_slots": [], - "protected_static_vars": [], - "protected_vars": [], - "private_funcs": [], - "private_slots": [], - "related": [], - "friend_funcs": [], - "groups": [], - "has_enum_details": false, - "has_typedef_details": false, - "has_func_details": false, - "has_var_details": false, - "has_define_details": false, - "breadcrumb": [ - [ - "Examples using the SDI-12 Library", - "examples_page.html" - ], - [ - "TestWarmUp.ino", - "_test_warm_up_8ino-example.html" - ] - ] - } -} \ No newline at end of file diff --git a/a_wild_card_8ino-example.html b/a_wild_card_8ino-example.html index 8002bc1..0333e9b 100644 --- a/a_wild_card_8ino-example.html +++ b/a_wild_card_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » a_wild_card.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » a_wild_card.ino example | SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
-
« h_SDI-12_slave_implementation.ino | Examples using the SDI-12 Library | TestCommands.ino »
+
« e_continuous_measurement.ino | Examples using the SDI-12 Library | d_simple_logger.ino »
diff --git a/a_wild_card_8ino-example.json b/a_wild_card_8ino-example.json index a12191b..d8638db 100644 --- a/a_wild_card_8ino-example.json +++ b/a_wild_card_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "h__s_d_i-12_slave_implementation_8ino-example.html", - "h_SDI-12_slave_implementation.ino" + "e_continuous_measurement_8ino-example.html", + "e_continuous_measurement.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "_test_commands_8ino-example.html", - "TestCommands.ino" + "d_simple_logger_8ino-example.html", + "d_simple_logger.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/annotated.html b/annotated.html index 2d41f17..a8f0e73 100644 --- a/annotated.html +++ b/annotated.html @@ -2,7 +2,7 @@ - SDI-12 for Arduino2.2.0 + SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/b_address_change_8ino-example.json b/b_address_change_8ino-example.json index 6cbacf0..aed93c4 100644 --- a/b_address_change_8ino-example.json +++ b/b_address_change_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "e_continuous_measurement_8ino-example.html", - "e_continuous_measurement.ino" + "h__s_d_i-12_slave_implementation_8ino-example.html", + "h_SDI-12_slave_implementation.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "d_simple_logger_8ino-example.html", - "d_simple_logger.ino" + "j_external_pcint_library_8ino-example.html", + "j_external_pcint_library.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/c_check_all_addresses_8ino-example.html b/c_check_all_addresses_8ino-example.html index 135ba30..2ccbba1 100644 --- a/c_check_all_addresses_8ino-example.html +++ b/c_check_all_addresses_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » c_check_all_addresses.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » c_check_all_addresses.ino example | SDI-12 for Arduino2.2.1 - - + @@ -1283,24 +1282,24 @@
- + diff --git a/c_check_all_addresses_8ino-example.json b/c_check_all_addresses_8ino-example.json index ccf8245..5d2137c 100644 --- a/c_check_all_addresses_8ino-example.json +++ b/c_check_all_addresses_8ino-example.json @@ -17,19 +17,16 @@ "example_navigation": null, "footer_navigation": [ [ - "i__s_d_i-12_interface_8ino-example.html", - "i_SDI-12_interface.ino" + "d_simple_logger_8ino-example.html", + "d_simple_logger.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], - [ - "f_basic_data_request_8ino-example.html", - "f_basic_data_request.ino" - ] + null ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/change_log.html b/change_log.html index 0ff65bc..3cc64ca 100644 --- a/change_log.html +++ b/change_log.html @@ -2,7 +2,7 @@ - ChangeLog | SDI-12 for Arduino2.2.0 + ChangeLog | SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/d_simple_logger_8ino-example.json b/d_simple_logger_8ino-example.json index 7ba153f..9f2c263 100644 --- a/d_simple_logger_8ino-example.json +++ b/d_simple_logger_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "b_address_change_8ino-example.html", - "b_address_change.ino" + "a_wild_card_8ino-example.html", + "a_wild_card.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "j_external_pcint_library_8ino-example.html", - "j_external_pcint_library.ino" + "c_check_all_addresses_8ino-example.html", + "c_check_all_addresses.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/dir_68267d1309a1af8e8297ef4c3efbcdba.html b/dir_68267d1309a1af8e8297ef4c3efbcdba.html index 5d1f9fb..b165331 100644 --- a/dir_68267d1309a1af8e8297ef4c3efbcdba.html +++ b/dir_68267d1309a1af8e8297ef4c3efbcdba.html @@ -2,7 +2,7 @@ - src/ directory | SDI-12 for Arduino2.2.0 + src/ directory | SDI-12 for Arduino2.2.1 - + @@ -1283,24 +1283,24 @@
- + diff --git a/e_continuous_measurement_8ino-example.json b/e_continuous_measurement_8ino-example.json index dfbab26..9fa6237 100644 --- a/e_continuous_measurement_8ino-example.json +++ b/e_continuous_measurement_8ino-example.json @@ -25,11 +25,11 @@ "Examples using the SDI-12 Library" ], [ - "b_address_change_8ino-example.html", - "b_address_change.ino" + "a_wild_card_8ino-example.html", + "a_wild_card.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/example_a_page.html b/example_a_page.html index 6a18996..66fee6b 100644 --- a/example_a_page.html +++ b/example_a_page.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » Example A: Using the Wildcard - Getting Single Sensor Information | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » Example A: Using the Wildcard - Getting Single Sensor Information | SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/f_basic_data_request_8ino-example.json b/f_basic_data_request_8ino-example.json index 79a7ffd..cbc7599 100644 --- a/f_basic_data_request_8ino-example.json +++ b/f_basic_data_request_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "c_check_all_addresses_8ino-example.html", - "c_check_all_addresses.ino" + "j_external_pcint_library_8ino-example.html", + "j_external_pcint_library.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "h__s_d_i-12_slave_implementation_8ino-example.html", - "h_SDI-12_slave_implementation.ino" + "g_terminal_window_8ino-example.html", + "g_terminal_window.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/files.html b/files.html index e6feb1b..adca162 100644 --- a/files.html +++ b/files.html @@ -2,7 +2,7 @@ - SDI-12 for Arduino2.2.0 + SDI-12 for Arduino2.2.1 - + @@ -1283,24 +1283,24 @@
- + diff --git a/g_terminal_window_8ino-example.json b/g_terminal_window_8ino-example.json index f870ba1..cef7273 100644 --- a/g_terminal_window_8ino-example.json +++ b/g_terminal_window_8ino-example.json @@ -17,8 +17,8 @@ "example_navigation": null, "footer_navigation": [ [ - "l_verify_crc_8ino-example.html", - "l_verify_crc.ino" + "f_basic_data_request_8ino-example.html", + "f_basic_data_request.ino" ], [ "examples_page.html", @@ -29,7 +29,7 @@ "e_continuous_measurement.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/gp-desktop-logo.png b/gp-desktop-logo.png index 87486c2..2cea63c 100644 Binary files a/gp-desktop-logo.png and b/gp-desktop-logo.png differ diff --git a/gp-mobile-logo.png b/gp-mobile-logo.png index 5e0d23f..dcbe2f5 100644 Binary files a/gp-mobile-logo.png and b/gp-mobile-logo.png differ diff --git a/gp-scrolling-logo.png b/gp-scrolling-logo.png index 211f2b7..27d9864 100644 Binary files a/gp-scrolling-logo.png and b/gp-scrolling-logo.png differ diff --git a/h__s_d_i-12_slave_implementation_8ino-example.html b/h__s_d_i-12_slave_implementation_8ino-example.html index 7d6b45f..17e4430 100644 --- a/h__s_d_i-12_slave_implementation_8ino-example.html +++ b/h__s_d_i-12_slave_implementation_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » h_SDI-12_slave_implementation.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » h_SDI-12_slave_implementation.ino example | SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/h__s_d_i-12_slave_implementation_8ino-example.json b/h__s_d_i-12_slave_implementation_8ino-example.json index ed1dc60..082b092 100644 --- a/h__s_d_i-12_slave_implementation_8ino-example.json +++ b/h__s_d_i-12_slave_implementation_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "f_basic_data_request_8ino-example.html", - "f_basic_data_request.ino" + "i__s_d_i-12_interface_8ino-example.html", + "i_SDI-12_interface.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "a_wild_card_8ino-example.html", - "a_wild_card.ino" + "b_address_change_8ino-example.html", + "b_address_change.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/i__s_d_i-12_interface_8ino-example.html b/i__s_d_i-12_interface_8ino-example.html index 09c9a2f..06664a0 100644 --- a/i__s_d_i-12_interface_8ino-example.html +++ b/i__s_d_i-12_interface_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » i_SDI-12_interface.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » i_SDI-12_interface.ino example | SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/i__s_d_i-12_interface_8ino-example.json b/i__s_d_i-12_interface_8ino-example.json index 1a65728..201b44a 100644 --- a/i__s_d_i-12_interface_8ino-example.json +++ b/i__s_d_i-12_interface_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "j_external_pcint_library_8ino-example.html", - "j_external_pcint_library.ino" + "k_concurrent_logger_8ino-example.html", + "k_concurrent_logger.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "c_check_all_addresses_8ino-example.html", - "c_check_all_addresses.ino" + "h__s_d_i-12_slave_implementation_8ino-example.html", + "h_SDI-12_slave_implementation.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/index.html b/index.html index 783c45e..90b318f 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ - SDI-12 for Arduino2.2.0 + SDI-12 for Arduino2.2.1 - - + + @@ -1283,24 +1283,24 @@
- + diff --git a/j_external_pcint_library_8ino-example.json b/j_external_pcint_library_8ino-example.json index 8da8d68..0b191e8 100644 --- a/j_external_pcint_library_8ino-example.json +++ b/j_external_pcint_library_8ino-example.json @@ -17,19 +17,19 @@ "example_navigation": null, "footer_navigation": [ [ - "d_simple_logger_8ino-example.html", - "d_simple_logger.ino" + "b_address_change_8ino-example.html", + "b_address_change.ino" ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "i__s_d_i-12_interface_8ino-example.html", - "i_SDI-12_interface.ino" + "f_basic_data_request_8ino-example.html", + "f_basic_data_request.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/k_concurrent_logger_8ino-example.html b/k_concurrent_logger_8ino-example.html index 7f5cc65..a895a5f 100644 --- a/k_concurrent_logger_8ino-example.html +++ b/k_concurrent_logger_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » k_concurrent_logger.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » k_concurrent_logger.ino example | SDI-12 for Arduino2.2.1 - + + @@ -1282,24 +1283,24 @@
- + diff --git a/k_concurrent_logger_8ino-example.json b/k_concurrent_logger_8ino-example.json index 510519a..e052c9e 100644 --- a/k_concurrent_logger_8ino-example.json +++ b/k_concurrent_logger_8ino-example.json @@ -16,17 +16,20 @@ "since": null, "example_navigation": null, "footer_navigation": [ - null, + [ + "l_verify_crc_8ino-example.html", + "l_verify_crc.ino" + ], [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "l_verify_crc_8ino-example.html", - "l_verify_crc.ino" + "i__s_d_i-12_interface_8ino-example.html", + "i_SDI-12_interface.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/l_verify_crc_8ino-example.html b/l_verify_crc_8ino-example.html index 76a2ef4..87c3a18 100644 --- a/l_verify_crc_8ino-example.html +++ b/l_verify_crc_8ino-example.html @@ -2,7 +2,7 @@ - Examples using the SDI-12 Library » l_verify_crc.ino example | SDI-12 for Arduino2.2.0 + Examples using the SDI-12 Library » l_verify_crc.ino example | SDI-12 for Arduino2.2.1 - - + @@ -1283,24 +1282,24 @@
- + diff --git a/l_verify_crc_8ino-example.json b/l_verify_crc_8ino-example.json index 491cd6c..27107cb 100644 --- a/l_verify_crc_8ino-example.json +++ b/l_verify_crc_8ino-example.json @@ -16,20 +16,17 @@ "since": null, "example_navigation": null, "footer_navigation": [ - [ - "k_concurrent_logger_8ino-example.html", - "k_concurrent_logger.ino" - ], + null, [ "examples_page.html", "Examples using the SDI-12 Library" ], [ - "g_terminal_window_8ino-example.html", - "g_terminal_window.ino" + "k_concurrent_logger_8ino-example.html", + "k_concurrent_logger.ino" ] ], - "modules": [], + "topics": [], "dirs": [], "files": [], "namespaces": [], diff --git a/license.html b/license.html index 4e4dad3..4329004 100644 --- a/license.html +++ b/license.html @@ -2,7 +2,7 @@ - LICENSE | SDI-12 for Arduino2.2.0 + LICENSE | SDI-12 for Arduino2.2.1