Communication with an SDI-12 sensor depends on its 1-character alphanumeric address (1-9, A-Z, a-z). A sensor can also be programmed with an address of 0, but that address cannot always be used to get measurements from the sensor. This sketch enables you to find and change the address of your sensor.
First, physically connect your SDI-12 sensor to your device. Some helpful hits for connecting it can be found here: https://envirodiy.org/topic/logging-mayfly-with-decagon-sdi-12-sensor/#post-2129.
Once your sensor is physically connected to your board, download this library and open this sketch.
Scroll to line 25 of the sketch (int8_t dataPin = SDI12_DATA_PIN;). 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 25 (int8_t powerPin = SDI12_POWER_PIN;). If your sensor is continuously powered, set the power pin to -1.
Upload the sketch to your board. After the upload finishes, open up the serial port monitor at a baud rate of 115200 on line 53.
In the serial monitor you will see it begin scanning through all possible SDI-12 addresses. Once it has found an occupied address, it will stop and ask you to enter a new address. Send your desired address to the serial port. On the screen you should see "Readdressing Sensor." followed by "Success.  Re-scanning for verification." The scan will begin again, stopping at your new address. If you are now happy with the address you've selected, smile and close the serial port monitor.
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 
 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 
The Complete Example
  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> 
  8 * @brief Example B: Changing the Address of your SDI-12 Sensor 
 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. 
 17#define SDI12_DATA_PIN 7 
 19#ifndef SDI12_POWER_PIN 
 20#define SDI12_POWER_PIN 22 
 23uint32_t serialBaud = 57600;           /*!< The baud rate for the output serial port */ 
 24int8_t   dataPin    = SDI12_DATA_PIN;  /*!< The pin of the SDI-12 data bus */ 
 25int8_t   powerPin   = SDI12_POWER_PIN; /*!< The sensor power pin (or -1) */ 
 26uint32_t wake_delay = 0; /*!< Extra time needed for the sensor to wake (0-100ms) */ 
 28/** Define the SDI-12 bus */ 
 29SDI12 mySDI12(dataPin); 
 31String myCommand  = "";   // empty to start 
 32char   oldAddress = '!';  // invalid address as placeholder 
 35 * @brief gets identification information from a sensor, and prints it to the serial 
 38 * @param i a character between '0'-'9', 'a'-'z', or 'A'-'Z'. 
 40void printInfo(char i) { 
 44  mySDI12.sendCommand(command, wake_delay); 
 47  String sdiResponse = mySDI12.readStringUntil('\n'); 
 49  // allccccccccmmmmmmvvvxxx...xx<CR><LF> 
 50  Serial.print(sdiResponse.substring(0, 1));  // address 
 52  Serial.print(sdiResponse.substring(1, 3).toFloat() / 10);  // SDI-12 version number 
 54  Serial.print(sdiResponse.substring(3, 11));  // vendor id 
 56  Serial.print(sdiResponse.substring(11, 17));  // sensor model 
 58  Serial.print(sdiResponse.substring(17, 20));  // sensor version 
 60  Serial.print(sdiResponse.substring(20));  // sensor id 
 64// this checks for activity at a particular address 
 65// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z' 
 66bool checkActive(byte i) {  // this checks for activity at a particular address 
 67  Serial.print("Checking address "); 
 68  Serial.print((char)i); 
 71  myCommand += (char)i;  // sends basic 'acknowledge' command [address][!] 
 74  for (int j = 0; j < 3; j++) {  // goes through three rapid contact attempts 
 75    mySDI12.sendCommand(myCommand, wake_delay); 
 77    if (mySDI12.available()) {  // If we hear anything, assume we have an active sensor 
 78      Serial.println("Occupied"); 
 79      mySDI12.clearBuffer(); 
 82      Serial.println("Vacant");  // otherwise it is vacant. 
 83      mySDI12.clearBuffer(); 
 90  Serial.begin(serialBaud); 
 91  while (!Serial && millis() < 10000L); 
 93  Serial.println("Opening SDI-12 bus..."); 
 95  delay(500);  // allow things to settle 
 97  Serial.println("Timeout value: "); 
 98  Serial.println(mySDI12.TIMEOUT); 
100  // Power the sensors; 
102    Serial.println("Powering up sensors, wait 30s..."); 
103    pinMode(powerPin, OUTPUT); 
104    digitalWrite(powerPin, HIGH); 
110  boolean found = false;  // have we identified the sensor yet? 
112  for (byte i = '0'; i <= '9'; i++) {  // scan address space 0-9 
114    if (checkActive(i)) { 
121  for (byte i = 'a'; i <= 'z'; i++) {  // scan address space a-z 
123    if (checkActive(i)) { 
130  for (byte i = 'A'; i <= 'Z'; i++) {  // scan address space A-Z 
132    if (checkActive(i)) { 
141      "No sensor detected. Check physical connections.");  // couldn't find a sensor. 
142                                                           // check connections.. 
146    Serial.print("Sensor active at address ");  // found a sensor! 
147    Serial.print(oldAddress); 
150    Serial.println("Enter new address.");  // prompt for a new address 
151    while (!Serial.available()); 
152    char newAdd = Serial.read(); 
154    // wait for valid response 
155    while (((newAdd < '0') || (newAdd > '9')) && ((newAdd < 'a') || (newAdd > 'z')) && 
156           ((newAdd < 'A') || (newAdd > 'Z'))) { 
157      if (!(newAdd == '\n') || (newAdd == '\r') || (newAdd == ' ')) { 
159          "Not a valid address. Please enter '0'-'9', 'a'-'A', or 'z'-'Z'."); 
161      while (!Serial.available()); 
162      newAdd = Serial.read(); 
165    /* the syntax of the change address command is: 
166    [currentAddress]A[newAddress]! */ 
168    Serial.println("Readdressing sensor."); 
170    myCommand += (char)oldAddress; 
172    myCommand += (char)newAdd; 
174    mySDI12.sendCommand(myCommand); 
176    /* wait for the response then throw it away by 
177    clearing the buffer with clearBuffer()  */ 
179    mySDI12.clearBuffer(); 
181    Serial.println("Success. Re-scanning for verification.");