SDI-12 for Arduino > Examples > b_address_change.ino

b_address_change.ino example

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

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 54 of the sketch (#define DATA_PIN 7). Change the 7 to the pin number that your sensor is attached to.

Set the pin to provide power to your sensor in line 55 (#define 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 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. Rescanning 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

; PlatformIO Project Configuration File

[platformio]
description = SDI-12 Library Example B:  Changing the SDI-12 Address of a Sensor
src_dir = .piolibdeps/Arduino-SDI-12_ID1486/examples/b_address_change

[env:mayfly]
monitor_speed = 115200
board = mayfly
platform = atmelavr
framework = arduino
lib_ldf_mode = deep+
lib_ignore = RTCZero
lib_deps =
    SDI-12

The Complete Example

/**
 * @file b_address_change.ino
 * @copyright (c) 2013-2020 Stroud Water Research Center (SWRC)
 *                          and the EnviroDIY Development Team
 *            This example is published under the BSD-3 license.
 * @author Kevin M.Smith <SDI12@ethosengineering.org>
 * @date August 2013
 *
 * @brief Example B: Changing the Address of your SDI-12 Sensor
 *
 * This is a simple demonstration of the SDI-12 library for arduino.
 * It discovers the address of the attached sensor and allows you to change it.
 */

#include <SDI12.h>

#define SERIAL_BAUD 115200 /*!< The baud rate for the output serial port */
#define DATA_PIN 7         /*!< The pin of the SDI-12 data bus */
#define POWER_PIN 22       /*!< The sensor power pin (or -1 if not switching power) */

/** Define the SDI-12 bus */
SDI12 mySDI12(DATA_PIN);

String myCommand  = "";   // empty to start
char   oldAddress = '!';  // invalid address as placeholder

// this checks for activity at a particular address
// expects a char, '0'-'9', 'a'-'z', or 'A'-'Z'
boolean checkActive(byte i) {  // this checks for activity at a particular address
  Serial.print("Checking address ");
  Serial.print((char)i);
  Serial.print("...");
  myCommand = "";
  myCommand += (char)i;  // sends basic 'acknowledge' command [address][!]
  myCommand += "!";

  for (int j = 0; j < 3; j++) {  // goes through three rapid contact attempts
    mySDI12.sendCommand(myCommand);
    delay(30);
    if (mySDI12.available()) {  // If we here anything, assume we have an active sensor
      Serial.println("Occupied");
      mySDI12.clearBuffer();
      return true;
    } else {
      Serial.println("Vacant");  // otherwise it is vacant.
      mySDI12.clearBuffer();
    }
  }
  return false;
}

void setup() {
  Serial.begin(SERIAL_BAUD);
  while (!Serial)
    ;

  Serial.println("Opening SDI-12 bus...");
  mySDI12.begin();
  delay(500);  // allow things to settle

  // Power the sensors;
  if (POWER_PIN > 0) {
    Serial.println("Powering up sensors...");
    pinMode(POWER_PIN, OUTPUT);
    digitalWrite(POWER_PIN, HIGH);
    delay(200);
  }
}

void loop() {
  boolean found = false;  // have we identified the sensor yet?

  for (byte i = '0'; i <= '9'; i++) {  // scan address space 0-9
    if (found) break;
    if (checkActive(i)) {
      found      = true;
      oldAddress = i;
    }
  }

  for (byte i = 'a'; i <= 'z'; i++) {  // scan address space a-z
    if (found) break;
    if (checkActive(i)) {
      found      = true;
      oldAddress = i;
    }
  }

  for (byte i = 'A'; i <= 'Z'; i++) {  // scan address space A-Z
    if (found) break;
    if (checkActive(i)) {
      found      = true;
      oldAddress = i;
    }
  }

  if (!found) {
    Serial.println(
      "No sensor detected. Check physical connections.");  // couldn't find a sensor.
                                                           // check connections..
  } else {
    Serial.print("Sensor active at address ");  // found a sensor!
    Serial.print(oldAddress);
    Serial.println(".");

    Serial.println("Enter new address.");  // prompt for a new address
    while (!Serial.available())
      ;
    char newAdd = Serial.read();

    // wait for valid response
    while (((newAdd < '0') || (newAdd > '9')) && ((newAdd < 'a') || (newAdd > 'z')) &&
           ((newAdd < 'A') || (newAdd > 'Z'))) {
      if (!(newAdd == '\n') || (newAdd == '\r') || (newAdd == ' ')) {
        Serial.println(
          "Not a valid address. Please enter '0'-'9', 'a'-'A', or 'z'-'Z'.");
      }
      while (!Serial.available())
        ;
      newAdd = Serial.read();
    }

    /* the syntax of the change address command is:
    [currentAddress]A[newAddress]! */

    Serial.println("Readdressing sensor.");
    myCommand = "";
    myCommand += (char)oldAddress;
    myCommand += "A";
    myCommand += (char)newAdd;
    myCommand += "!";
    mySDI12.sendCommand(myCommand);

    /* wait for the response then throw it away by
    clearing the buffer with clearBuffer()  */
    delay(300);
    mySDI12.clearBuffer();

    Serial.println("Success. Rescanning for verification.");
  }
}