This is a simple demonstration of the SDI-12 library for Arduino.
It discovers the address of all sensors active on a single bus and takes continuous measurements from them.
Each call to SDI12Recorder::requestContinuousData() requests one independent R0 through R9 response. The example can instead request RC0 through RC9 and validate the returned CRC by setting useCRC to true.
Every SDI-12 device is different in the time it takes to take a measurement, and the amount of data it returns. This sketch will not serve every sensor type, but it will likely be helpful in getting you started.
Each sensor should have a unique address already - if not, multiple sensors may respond simultaneously to the same request and the output will not be readable by the Arduino.
To address a sensor, please see Example B: b_address_change.ino
PlatformIO Configuration
1; PlatformIO Project Configuration File
4description = SDI-12 Library Example D: Getting Data from All Attached Sensors
5src_dir = .piolibdeps/Arduino-SDI-12_ID1486/examples/d_simple_logger
The Complete Example
2 * @example{lineno} e_continuous_measurement.ino
3 * @copyright Stroud Water Research Center
4 * @license This example is published under the BSD-3 license.
5 * @author Kevin M.Smith <SDI12@ethosengineering.org>
8 * @brief Example E: Check all Addresses for Active Sensors and Request Continuous Data
10 * This is a simple demonstration of the SDI-12 library for Arduino.
12 * It discovers the address of all sensors active on a single bus and periodically
13 * requests their current continuous data without initiating a measurement.
16#include <SDI12Config.h>
17#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && !defined(SDI12_INTERNAL_PCINT)
18#include <EnableInterrupt.h>
21#include <SDI12Recorder.h>
24#define SDI12_DATA_PIN 7
26#ifndef SDI12_POWER_PIN
27#define SDI12_POWER_PIN 22
29#ifndef SDI12_TERMINAL_BAUD
30#define SDI12_TERMINAL_BAUD 115200
33/* connection information */
34uint32_t serialBaud = SDI12_TERMINAL_BAUD; /*!< The baud rate for the serial port */
35int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */
36int8_t powerPin = SDI12_POWER_PIN; /*!< The sensor power pin (or -1) */
37bool useCRC = false; /*!< Whether to use CRC checking */
38int8_t firstAddress = 0; /* The first address in the address space to check (0='0') */
39int8_t lastAddress = 61; /* The last address in the address space to check (61='z') */
41/** Define the SDI-12 bus */
42SDI12 mySDI12(dataPin);
43SDI12Recorder mySDI12Recorder(mySDI12);
45// keeps track of active addresses
48uint8_t numSensors = 0;
50// A continuous response can contain at most 75 value characters. At the minimum
51// two characters per value (a sign and one digit), no more than 37 values can fit.
52float continuousResults[37];
54bool printInfo(char address) {
55 SDI12Recorder::Identification sensorInfo;
56 if (mySDI12Recorder.identify(address, sensorInfo)) {
57 mySDI12Recorder.printSensorInfo(sensorInfo, Serial);
60 Serial.print(F("Identification failed for address "));
61 Serial.print(address);
62 Serial.print(F(": "));
63 mySDI12Recorder.printRecorderResult(Serial);
69bool getContinuousResults(char address, uint8_t dataOption = 0U) {
70 const size_t resultsReceived = mySDI12Recorder.requestContinuousData(
71 address, continuousResults,
72 sizeof(continuousResults) / sizeof(continuousResults[0]), dataOption, useCRC);
73 if (mySDI12Recorder.result() != SDI12Recorder::RESULT_SUCCESS) {
74 mySDI12Recorder.printRecorderResult(Serial);
78 if (resultsReceived == 0U) {
79 Serial.print(F("No continuous results available"));
83 for (size_t i = 0U; i < resultsReceived; ++i) {
84 if (i > 0U) { Serial.print(F(", ")); }
85 Serial.print(continuousResults[i], 7);
91 Serial.begin(serialBaud);
92 while (!Serial && millis() < 10000L);
93 char tbuf[3] = {'\0'};
95 Serial.print(F("Opening SDI-12 bus on pin "));
96 Serial.print(dataPin);
97 Serial.print(F(" ("));
98 Serial.print(itoa(dataPin, tbuf, 10));
100 Serial.println(F("..."));
102 delay(500); // allow things to settle
104 Serial.println(F("Timeout value: "));
105 Serial.println(mySDI12.TIMEOUT);
107 // Power the sensors;
109 Serial.print(F("Powering up sensors with pin "));
110 Serial.print(String(powerPin));
111 Serial.println(F(", wait 10s..."));
112 pinMode(powerPin, OUTPUT);
113 digitalWrite(powerPin, HIGH);
116 Serial.println(F("Wait 5s..."));
120 // Quickly scan the address space
121 Serial.println(F("\n\nScanning all addresses, please wait..."));
123 for (int8_t i = firstAddress; i <= lastAddress; i++) {
124 char addr = SDI12Address::fromIndex(i);
125 if (mySDI12Recorder.requestAcknowledgement(addr)) {
131 Serial.print(F("Total number of sensors found: "));
132 Serial.println(numSensors);
134 if (numSensors == 0) {
136 "No sensors found, please check connections and restart the Arduino.");
137 while (true); // do nothing forever
142 "Time Elapsed (ms), Sensor Address, Measurement 1, Measurement 2, ... etc.");
144 "-------------------------------------------------------------------------------");
148 // measure one at a time
149 for (int8_t i = firstAddress; i <= lastAddress; i++) {
150 char addr = SDI12Address::fromIndex(i);
152 Serial.print(millis());
153 Serial.print(F(", "));
155 Serial.print(F(", "));
156 getContinuousResults(addr);
161 delay(10000L); // wait ten seconds between measurement attempts.