SDI-12 for Arduino
Introduction
This is an Arduino library for SDI-12 communication with a wide variety of environmental sensors. It provides a general software solution, without requiring any additional hardware, to implement the SDI-12 communication protocol between an Arduino-based data logger and SDI-12-enabled sensors.
SDI-12 is an asynchronous, ASCII, serial communications protocol that was developed for intelligent sensory instruments that typically monitor environmental data. Advantages of SDI-12 include the ability to use a single available data channel for many sensors.
This work is motivated by the EnviroDIY community vision to create an open source hardware and software stack to deliver near real time environmental data from wireless sensor networks, such as the Arduino-compatible EnviroDIY™ Mayfly Data Logger.
Renaming Notice
Getting Started
Learn more, below, about this library's:
Try running our Example sketches with your Arduino board and SDI-12 sensor.
Full details on the library functionality can be found on github pages: https:/
Library Installation
This library is available through both the Arduino and PlatformIO library registries.
Within the Arduino IDE, you can find the library in the library registry using the library manager. The build and ingest logs for this library into the Arduino library registry are available.. The Arduino library registry should show newly available versions of this library within a few hours of a new release.
The library is also available in the PlatformIO registry page.. It can be installed using the PlatformIO command pio pkg install --library "envirodiy/SDI-12", You can also include this SDI-12 library as a dependency for a project by adding envirodiy/SDI-12 to the lib_
Origins
This library was developed from the SoftwareSerial library that is a built-in standard Arduino library. It was further modified to use a timer to improve read stability and decrease the amount of time universal interrupts are disabled using logic from NeoSWSerial. In November of 2026, the EnableInterrupt library was made a required dependency for this library for AVR boards.
Compatibility Considerations
Tested Boards
This library has been tested and verified for:
- EnviroDIY Mayfly (AtMega1284p)
- EnviroDIY Stonefly (SAMD51)
- Arduino Uno (AtMega328p)
- Adafruit Feather 32u4 (AtMega32u4, identical to Arduino Leonardo)
- Seeeduino Mega (ATmega2560)
- Adafruit Feather M0 (SAMD21G18, identical to Arduino Zero)
- Adafruit Feather M4 (SAMD51J19A)
- Adafruit Feather Huzzah (ESP12S/ESP8266)
- Adafruit Feather Huzzah32 (ESP-WROOM-32/ESP32)
Untested Boards
Other untested boards that should work:
- Arduino Mega (AtMega2560)
- Adafruit Gemma/AtTiny
- Most other AVR processors
- Other flavors of ESP8266 and ESP32
- Arduino framework boards with clock speeds over ~48MHz
Unsupported Boards
These boards are currently unsupported. If you are interested in adding support for those boards, please send pull requests.
- Arduino Due
- Arduino 101
- Teensy boards with speeds <48Mhz
Usable Pins
Due to the use of pin change interrupts, not all AVR data pins are available for use with this SDI-12 library. Pin availability depends on the micro-controller.
For AVR boards, the "Bestiary" of the EnableInterrupt library is one of the best lists of usable pins.
- AtMega328p / Arduino Uno:
- Any pin
- AtMega1284p / EnviroDIY Mayfly
- Any pin
- ATmega2560 / Arduino Mega or Mega 2560:
- 0, 11, 12, 13, 14, 15, 50, 51, 52, 53, A8 (62), A9 (63), A10 (64), A11 (65), A12 (66), A13 (67), A14 (68), A15 (69)
- AtMega32u4 / Arduino Leonardo or Adafruit Feather 32u4:
- 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI)
- SAMD21xxx / Arduino Zero:
- Any pin (except 4 on the zero)
- SAMD51xxx / EnviroDIY Stonefly:
- Any pin
- ESP8266:
- Any GPIO, except GPIO16
- ESP32:
- Any GPIO
- Particle (Boron LTE):
- Any digital GPIO
Advanced Library Configuration
This library can be configured through the SDI12Config.h header in the src folder of the library. If you are using PlatformIO, you can also configure the library through build flags In the Arduino Command Line Interface (CLI), the --build-property option of the compile command also allows you to add build flags.
AVR Interrupt Handling
By default, AVR interrupts are handed off to GreyGnome's EnableInterrupt library. The examples include EnableInterrupt.h explicitly, which is recommended when a sketch uses or configures EnableInterrupt directly. For backward compatibility, this library also supplies a link-time fallback implementation, so existing sketches that include only an SDI-12 header do not need to add #include <EnableInterrupt.h>. You can instead allow this library full control of the AVR interrupts (and avoid using EnableInterrupt at runtime) by removing the two comment slashes at the start of the line // #define SDI12_ in the SDI12Config.h header or by compiling with the build flag -D SDI12_. EnableInterrupt remains a declared dependency in library.properties and library.json even when SDI12_ is defined.
You can also allow this library to manage the interrupt handling, but restrict the pin change interrupts it can manage to a specific interrupt vector using the configuration options or defining the build flag SDI12_ and one of the build flags SDI12_, SDI12_, SDI12_, or SDI12_. Defining these flags has no effect on non-AVR boards.
You will not be able to compile this library along with any other library that manages pin change interrupt vectors on AVR boards. Some other libraries managing interrupts include SoftwareSerial, NeoSWSerial, PinChangeInt, and Servo. Within a sketch, you can manage pin change interrupts using the functions provided by the EnableInterrupt library, such as enableInterrupt() and disableInterrupt().
Response Buffer Size
The response buffer size can be modified using the SDI12_ value in SDI12Config.h or via a build flag. The default size is large enough for all standard and high volume ASCII SDI-12 commands and responses. If you are extremely space limited, you can decrease the size of the buffer. If you need high volume binary responses, you will probably need to increase the size of the buffer.
Global Interrupts During Communication
Processors running at 48MHz or faster are fast enough that a typical interrupt service routine cannot shift the bit timing past the SDI-12 tolerance, so since version 2.2.0 interrupts are left enabled while transmitting on those boards. On a board running an RTOS - an ESP32 running FreeRTOS alongside WiFi or a cellular modem, for instance - a task switch or another driver's long ISR can still stretch a bit far enough to garble a command. Defining SDI12_ restores the pre-2.2.0 behavior of holding interrupts off for the time-critical part of every character.
Timing Options
You can modify the exact length of the break and mark using the SDI12_ and SDI12_ options, respectively. The defaults should be correct for almost all uses.
The deprecated SDI12_ option is used only as the default extra wake time for the deprecated SDI12:: overloads. It is not used by SDI12Recorder.
The Fudge Factor
You can tweak the reception bit timing using the SDI12_. See the configuration file and the boards files for details.
Contribute
Open an issue to suggest and discuss potential changes/additions.
For power contributors:
- Fork it!
- Create your feature branch:
git checkout -b my-new-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin my-new-feature - Submit a pull request :D
License
The SDI12 library code is released under the GNU Lesser Public License (LGPL 2.1) – See LICENSE-examples.md file for details.
Example Arduino sketches are released under the BSD 3-Clause License – See LICENSE-examples.md file for details.
Documentation is licensed as Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA) copyright.
Credits
EnviroDIY™ is presented by the Stroud Water Research Center, with contributions from a community of enthusiasts sharing do-it-yourself ideas for environmental science and monitoring.
Kevin M. Smith was the primary developer of the SDI-12 library, with input from S. Hicks and Anthony Aufdenkampe.
Sara Damiano is now the primary maintainer, with input from many other contributors.
This project has benefited from the support from the following funding sources:
- National Science Foundation, awards EAR-0724971, EAR-1331856, ACI-1339834
- William Penn Foundation, grant 158-15
- Stroud Water Research Center endowment