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 measurements from them.
The sketch uses the beginner-facing blocking SDI12Recorder::measure() workflow. That one call requests a normal measurement and retrieves the complete advertised result across D0 through the necessary final data block. Set the sketch's useCRC value to request the MC command family and validate response CRCs.
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} d_simple_logger.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 D: Check all Addresses for Active Sensors and Log 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 takes measurements
15 * Every SDI-12 device is different in the time it takes to take a
16 * measurement, and the amount of data it returns. This sketch will not serve every
17 * sensor type, but it will likely be helpful in getting you started.
19 * Each sensor should have a unique address already - if not, multiple sensors may
20 * respond simultaneously to the same request and the output will not be readable by the
23 * To address a sensor, please see Example B: b_address_change.ino
26#include <SDI12Config.h>
27#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && !defined(SDI12_INTERNAL_PCINT)
28#include <EnableInterrupt.h>
31#include <SDI12Recorder.h>
34#define SDI12_DATA_PIN 7
36#ifndef SDI12_POWER_PIN
37#define SDI12_POWER_PIN 22
39#ifndef SDI12_TERMINAL_BAUD
40#define SDI12_TERMINAL_BAUD 115200
43/* connection information */
44uint32_t serialBaud = SDI12_TERMINAL_BAUD; /*!< The baud rate for the serial port */
45int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */
46int8_t powerPin = SDI12_POWER_PIN; /*!< The sensor power pin (or -1) */
47bool useCRC = false; /*!< Whether to use CRC checking */
48int8_t firstAddress = 0; /* The first address in the address space to check (0='0') */
49int8_t lastAddress = 61; /* The last address in the address space to check (61='z') */
51/** Define the SDI-12 bus */
52SDI12 mySDI12(dataPin);
53SDI12Recorder mySDI12Recorder(mySDI12);
55// keeps track of active addresses
58uint8_t numSensors = 0;
60bool printInfo(char address) {
61 SDI12Recorder::Identification sensorInfo;
62 if (mySDI12Recorder.identify(address, sensorInfo)) {
63 mySDI12Recorder.printSensorInfo(sensorInfo, Serial);
66 Serial.print(F("Identification failed for address "));
67 Serial.print(address);
68 Serial.print(F(": "));
69 mySDI12Recorder.printRecorderResult(Serial);
75bool takeMeasurement(char i, uint8_t measurementNumber = 0U) {
77 size_t valueCount = mySDI12Recorder.measure(i, values, 9U, measurementNumber, useCRC);
78 if (mySDI12Recorder.result() != SDI12Recorder::RESULT_SUCCESS) {
79 mySDI12Recorder.printRecorderResult(Serial);
83 for (size_t valueNumber = 0U; valueNumber < valueCount; ++valueNumber) {
84 Serial.print(String(values[valueNumber], 7));
85 Serial.print(F(", "));
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
141 Serial.println(F("Time Elapsed (ms), Sensor Address, Measurement Number, Result 1, "
142 "Result 2, ... etc."));
144 "------------------------------------------------------------------------------"));
148 for (uint8_t measurementNumber = 0U; measurementNumber < 1U; ++measurementNumber) {
149 // measure one at a time
150 for (int8_t i = firstAddress; i <= lastAddress; i++) {
151 char addr = SDI12Address::fromIndex(i);
153 Serial.print(millis());
154 Serial.print(F(", "));
156 Serial.print(F(", "));
157 Serial.print(measurementNumber);
158 Serial.print(F(", "));
159 takeMeasurement(addr, measurementNumber);
165 delay(10000L); // wait ten seconds between measurement attempts.