Example B: Changing the Address of your SDI-12 Sensor

Communication with an SDI-12 sensor depends on its one-character alphanumeric address (0-9, a-z, or A-Z). This sketch uses the blocking SDI12Recorder API to find a sensor, print its identification information, and change its address with a validated acknowledgement.

First, physically connect your SDI-12 sensor to your device. Some helpful hints are available in this EnviroDIY forum discussion.

Once your sensor is physically connected to your board, download this library and open this sketch.

Scroll to line 17 of the sketch (#define SDI12_DATA_PIN 7). Change the 7 to the pin number that your sensor is attached to. You could also define the data pin in your platformio.ini: (-D SDI12_DATA_PIN=##)

Set the pin to provide power to your sensor in line 20 (#define SDI12_POWER_PIN 22). If your sensor is continuously powered, set the power pin to -1.

Upload the sketch to your board. After the upload finishes, open the serial port monitor at 115200 baud, or at the baud rate configured by SDI12_TERMINAL_BAUD.

The sketch assumes exactly one sensor is attached. It queries that sensor's current address and asks you to enter a new address. Send your desired address to the serial port. After the sensor acknowledges the change, the sketch queries the bus again to verify the new address.

If you are using a Meter Group Hydros 21 CTD sensor, change the channel to 1 in the serial monitor where prompted.

PlatformIO Configuration

1; PlatformIO Project Configuration File
2
3[platformio]
4description = SDI-12 Library Example B: Changing the SDI-12 Address of a Sensor
5src_dir = .piolibdeps/Arduino-SDI-12_ID1486/examples/b_address_change
6
7[env:mayfly]
8monitor_speed = 115200
9board = mayfly
10platform = atmelavr
11framework = arduino
12lib_ldf_mode = deep+
13lib_ignore = RTCZero
14lib_deps =
15 SDI-12

The Complete Example

1/**
2 * @example{lineno} b_address_change.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>
6 * @date August 2013
7 *
8 * @brief Example B: Changing the Address of your SDI-12 Sensor
9 *
10 * This is a simple demonstration of the SDI-12 library for arduino.
11 * It discovers the address of the attached sensor and allows you to change it.
12 */
13
14#include <SDI12Config.h>
15#if (defined(__AVR__) || defined(ARDUINO_ARCH_AVR)) && !defined(SDI12_INTERNAL_PCINT)
16#include <EnableInterrupt.h>
17#endif
18
19#include <SDI12Recorder.h>
20
21#ifndef SDI12_DATA_PIN
22#define SDI12_DATA_PIN 7
23#endif
24#ifndef SDI12_POWER_PIN
25#define SDI12_POWER_PIN 22
26#endif
27#ifndef SDI12_TERMINAL_BAUD
28#define SDI12_TERMINAL_BAUD 115200
29#endif
30/* connection information */
31uint32_t serialBaud = SDI12_TERMINAL_BAUD; /*!< The baud rate for the serial port */
32int8_t dataPin = SDI12_DATA_PIN; /*!< The pin of the SDI-12 data bus */
33int8_t powerPin = SDI12_POWER_PIN; /*!< The sensor power pin (or -1) */
34
35/** Define the SDI-12 bus and recorder */
36SDI12 mySDI12(dataPin);
37SDI12Recorder mySDI12Recorder(mySDI12);
38
39char oldAddress = '!'; // invalid address as placeholder
40
41bool printInfo(char address) {
42 SDI12Recorder::Identification sensorInfo;
43 if (mySDI12Recorder.identify(address, sensorInfo)) {
44 mySDI12Recorder.printSensorInfo(sensorInfo, Serial);
45 return true;
46 } else {
47 Serial.print(F("Identification failed for address "));
48 Serial.print(address);
49 Serial.print(F(": "));
50 mySDI12Recorder.printRecorderResult(Serial);
51 Serial.println();
52 }
53 return false;
54}
55
56void setup() {
57 Serial.begin(serialBaud);
58 while (!Serial && millis() < 10000L);
59 char tbuf[3] = {'\0'};
60
61 Serial.print(F("Opening SDI-12 bus on pin "));
62 Serial.print(dataPin);
63 Serial.print(F(" ("));
64 Serial.print(itoa(dataPin, tbuf, 10));
65 Serial.print(')');
66 Serial.println(F("..."));
67 mySDI12.begin();
68 delay(500); // allow things to settle
69
70 Serial.println(F("Timeout value: "));
71 Serial.println(mySDI12.TIMEOUT);
72
73 // Power the sensors;
74 if (powerPin >= 0) {
75 Serial.print(F("Powering up sensors with pin "));
76 Serial.print(String(powerPin));
77 Serial.println(F(", wait 10s..."));
78 pinMode(powerPin, OUTPUT);
79 digitalWrite(powerPin, HIGH);
80 delay(10000L);
81 }
82}
83
84void loop() {
85 // The wildcard query works only when exactly one sensor is attached to the bus.
86 oldAddress = mySDI12Recorder.queryAddress();
87 if (oldAddress == '\0') {
88 Serial.print(F("No sensor detected: "));
89 mySDI12Recorder.printRecorderResult(Serial);
90 Serial.println();
91 Serial.println(F("Check physical connections and restart the Arduino."));
92 while (true);
93 }
94
95 Serial.print(F("Sensor active at address "));
96 Serial.print(oldAddress);
97 Serial.println('.');
98 printInfo(oldAddress);
99
100 Serial.println(F("Enter new address.")); // prompt for a new address
101 while (!Serial.available());
102 char newAdd = Serial.read();
103
104 // wait for valid response
105 while (!SDI12Address::isValid(newAdd)) {
106 if (newAdd != '\n' && newAdd != '\r' && newAdd != ' ') {
107 Serial.println(
108 F("Not a valid address. Please enter '0'-'9', 'a'-'z', or 'A'-'Z'."));
109 }
110 while (!Serial.available());
111 newAdd = Serial.read();
112 }
113
114 Serial.println(F("Readdressing sensor."));
115 if (mySDI12Recorder.changeAddress(oldAddress, newAdd)) {
116 Serial.println(F("Success. Querying the sensor again for verification."));
117 } else {
118 Serial.print(F("Address change failed: "));
119 mySDI12Recorder.printRecorderResult(Serial);
120 Serial.println();
121 Serial.println(F("Querying the bus again."));
122 }
123}