SDI-12 Sensors USB Aadapter User Manual
SDI-12 Sensors USB Aadapter User Manual
SDI-12 Sensors USB Aadapter User Manual
2019-06-18
1
1. Introduction .......................................................................................................................................... 3
2. SDI-12 sensors tested............................................................................................................................ 7
3. Analog sensors tested (SDI-12 + Analog USB adapter) ......................................................................... 8
4. SDI-12 USB adapter ............................................................................................................................. 13
5. SDI-12 + Analog adapter ..................................................................................................................... 16
6. SDI-12 + GPS adapter .......................................................................................................................... 21
7. Installing Python, Pyserial, and cURL .................................................................................................. 23
8. Data logging using Python Scripts ....................................................................................................... 26
9. Plotting and automatic plot update .................................................................................................... 29
10. Logging Data to the Internet ............................................................................................................... 34
11. Advanced topics on data logging ........................................................................................................ 36
12. Updating Adapter Firmware ............................................................................................................... 39
13. Need Help with Your Project? ............................................................................................................. 41
14. SDI-12 sensor general guide ............................................................................................................... 42
15. Trouble shooting (windows) ............................................................................................................... 44
16. Frequently Asked Questions (FAQs) ................................................................................................... 47
17. Known issues (windows) ..................................................................................................................... 48
Appendix I. Preparing Raspberry Pi for Data Logging............................................................................ 49
Appendix II. Installing Python and Pyserial on Linux or Rapsberry Pi .................................................... 51
Appendix III. Powering SDI-12 sensor with external power source ........................................................ 52
Appendix IV. Connecting Decagon sensors with stereo plugs ................................................................. 53
Appendix V. Tera Term (windows) data logging ..................................................................................... 54
Appendix VI. Updating Adapter Firmware (Windows) ............................................................................ 59
Appendix VII. References .......................................................................................................................... 59
2
1. Introduction
SDI-12 sensors are widely used in environmental monitoring including soil, streams, solar radiation, rain
fall, plants etc. Typical name-brand data loggers designed for SDI-12 sensors are usually expensive and
proprietary, making it harder to do your projects on a budget. I felt that we need a cheaper alternative to
interface with SDI-12 sensors. I have built numerous data loggers in the past decade and know the benefits
of having SDI-12 sensors. In 2015, I designed an SDI-12 USB adapters to make it possible to interface with
SDI-12 sensors and analog sensors without an expensive logger. This adapter has since grown into a family
of adapters with basic adapters and specialized adapters carrying GPS, hi-res analog inputs and custom
sensors. Besides hardware, I have written many free open-source Python scripts ranging from the most
basic for beginners to rather sophisticated routines that log multiple measurements on multiple sensors
on multiple SDI-12 adapters with telemetry and compatible with PC/Mac/Linux/Raspberry pi/BBB.
My design makes it very easy to use. All you need is the adapter and a PC/Mac/Linux for testing. When
you are ready to deploy your loggers, replace your PC with a $5-to-$35 Raspberry Pi (RPI) single-board
computer [1] or a Beagle Bone Black [2] (BBB). I provide free and open-source data logging programs
(Python script) that works across different operating systems seamlessly. A section on SDI-12 sensors will
guide you through initial setup and later logging data. An RPI Zero ($5), a regular RPI ($35), or BBB is all it
takes to make a data logger for deployment in the field. The adapter has been designed for long-term data
logging for runs months at a time. You can further protect the adapter with a water-proof enclosure, some
silicone packets or conformal coating [3] against moisture. The data logging software is robust and runs
without problems for months and has advanced features to automatically detect all sensors on the
adapter and run preconfigured logging settings. The following plots include 124 days of soil dielectric
constant and temperature (Celsius) obtained in 2018 with an SDI-12 USB adapter, a raspberry pi zero, and
a Decagon 5TM sensor in my back yard.
Fig. 124 days of soil dielectric constant and temperature data from 2018 with raspberry pi
3
Each high spike in dielectric constant corresponds to a heavy rain. Each oscillation in temperature
corresponds with a daily (diurnal) temperature variation. The data clearly shows larger diurnal
temperature variation in the summer (high average temperature) and lower temperature variation in the
fall (low temperature). The data were logged on raspberry pi's sd card and uploaded to a thingspeak.com
server. I was able to water my lawn only when I have to. I constructed an internet-connected sprinkler
controller that summer.
This stream is only active during summer and fall, which is relatively short in Minnesota:
https://thingspeak.com/channels/462583
Family of adapters
Currently there are three standard models of the adapters.
I can also customize the basic SDI-12 USB adapter to include specific on-board sensors you want.
Common features:
All adapters have these features:
Every key component comes from reputable vendors such as Digikey, Mouser, or Newark. Every adapter
is assembled and tested by myself with an actual SDI-12 sensor (also an analog or resistive sensor).
The following two pages are information sheets about the adapters and options on the basic adapter.
4
SDI-12 USB adapter
Features (common features in blue):
✓ SDI-12 sensor connectors (4)
✓ Mini-USB port (or TTL serial port)
✓ USB fuse
✓ USB Serial IC (FT232RL)
✓ External power connector
✓ External power/USB 5V selection jumper
✓ 50mm*50mm dimension
✓ ATMEGA328P processor
✓ Extender port (for custom addons)
✓ Analog and digital input port (option)
✓ UART port (for TTL UART serial interface)
6
2. SDI-12 sensors tested
In theory, all SDI-12 sensors should work with my adapter. In practice, not all sensors were made equal.
So far, I have been able to test the following sensors with the adapter, with some help from users like you.
There has not been reports of any SDI-12 sensors that are incompatible. The following list keeps expanding.
If you tested sensors that are not on the list, please inform me ([email protected]) so I can add to the list.
Acclima:
✓ TDR-310H and 310S: Rounded Form Factor Time Domain Reflectometer for soil permittivity and
water content
✓ TDR-315: Time Domain Reflectometer for soil permittivity and water content
✓ TDR-315L: Low Power Time Domain Reflectometer for soil permittivity and water content
Apogee:
✓ SI-411 (standard field of view infrared radiometer sensor)
Aquacheck:
✓ CKC 6 sensor probe
Campbell Scientific:
✓ CS215 Air Temperature and Relative Humidity Sensors (Thanks Lee!)
✓ CS320 Digital Thermopile Pyranometer (Thanks Michelle!)
✓ CS650 30cm Soil Volumetric Water Content Probe (Thanks Stan!)
✓ CS655 12cm Soil Volumetric Water Content Probe (Thanks Nick!)
FTS inc.
✓ DigiTemp Water Temperature Sensor (Thanks Chris!)
Gill Instruments:
✓ WindSonic Ultrasonic Wind Sensor (Thanks MG!)
Greenshield:
✓ Capacitive Soil probe
7
Hongyuv:
✓ HY-WDC6SE Mini Weather Station Sensor * (see comment 1) (Thanks EG!)
HSTI:
✓ HydraSCOUT multi-sensor soil moisture and temperature probe (Thanks Bertrand!)
Ponsel:
✓ Digital turbidity sensor
Sentek:
✓ TriSCAN (12 moisture salinity temperature sensor probes)
Sutron:
✓ Accubar SDI-12 Barometric Pressure Sensor, Model 5600-0120-3 (Thanks Meidad!)
Unidata:
✓ Starflow QSD Ultrasonic Doppler Velocity And Depth sensor (Thanks Yiren!)
Comments:
1. If you purchased an adapter before June 2019 and can’t get data from it, you can download a
new firmware (version 1.5.0 or higher) and follow firmware update procedure to update your
adapter. Please pay attention to the model of your adapter when downloading firmware.
Voltage sensors:
✓ Any sensors producing up to 6V of DC voltage can be measured with SDI-12 + Analog USB
adapter
✓ Apogee SP-110 Self-Powered Pyranometer (Decagon sells them under PYR part number)
8
✓ Apogee SQ-500 Self-Powered full spectrum quantum sensor
✓ METER group ECH2O EC-5 (Decagon EC-5) (Soil volumetric water content sensor)
Tools needed:
1. 0.04" or 1mm blade width precision screw driver such as this one:
https://www.mcmaster.com/#7026a12/=1apsptn
2. USB-mini cable (can be purchased with adapter)
3. Computer (Win/Mac/Linux/Raspberry Pi/Beagle Bone Black)
4. SDI-12 sensor, only connect one sensor to the adapter
5. Optionally, get M3 standoffs and nuts to prop the board up or mount it
Terminal blocks
The screw terminal blocks are of the "rising cage" type. You loosen the screw with a precision screwdriver
(don't use a larger screwdriver) and the cage lowers to reveal an opening for wire leads. Make sure your
sensor's wire lead is about ¼" or 6mm long and tinned. Trim excess wire lead so they don't short circuit.
Insert the wire lead into the open cage and tighten the screw. The cage rises to hold to the wire. DO NOT
tighten the wire lead by loosening the screw, i.e. pushing the wire lead downwards. It would appear that
the wire lead was held tight but only one side of the cage is holding the wire lead with a metal surface,
resulting poor contact and higher likelihood of becoming loose.
As of June of 2019, the sizes of the terminals have 2.54mm spacing can easily accommodate up to 18AWG
(American wire gauge) wires. Another version with 3.5mm spacing can accommodate up to 16AWG wires.
Almost all sensor wires I’ve seen are 20AWG (thinner than 16 or 18) so either version works.
4 connections don’t limit SDI-12 sensors to 4. You can wire any number of sensors to the same connection.
More connectors just mean more convenience when building your logger or swapping sensors in the field.
If you do wish separate SDI-12 bus for each sensor, which can improve speed by simultaneously reading
all adapters, you may get more adapters. Adding sensors to an existing adapter adds the overall length of
cable so you may want to use a second adapter besides the convenience rationale.
9
Figure. SDI-12 USB adapter SDI-12 sensor wiring with USB 5V supplied to SDI-12 sensors
To supply external power, follow the wiring and jumper setting diagram below. Make sure you check the
polarity of your external power before connecting to the board. DC power ONLY!
For wiring external power to the old 5cm*2.5cm green color adapter, please read the appendix.
Figure. Connecting external power and setting jumper to supply external power to SDI-12 sensors
http://www.ftdichip.com/Drivers/VCP.htm
10
3. Once the driver installation completes, the adapter appears as a serial port. On a Windows PC, it
may be COM4 or whichever port that disappears from the Device Manager under "Ports
(COM&LPT)" after you unplug the adapter. On a Linux PC/Raspberry Pi/Beagle Bone Black, this
may be /dev/ttyUSB0 or /dev/ttyUSB1. On a MAC computer, it may show up as /dev/tty.usbserial-
A103RU9T, where A103RU9T is a part of the unique USB device ID so every adapter WILL have a
different one. Use "ls /dev/tty*" command in nix/Mac to list all tty devices before and after
plugging in your adapter to determine its exact name. My data logger script will list all serial ports
for you to pick. Remembering the serial port number is only needed if you are only using the
adapter with a serial monitor.
4. You may use any serial terminal program to talk with your SDI-12 sensor. On a windows PC, I
recommend Tera Term, MobaXterm, Terminal by Bray++, and termite. Once you connect the
sensor to the adapter and have proper driver, open serial port at 9600 baud rate, 8-bit data, 1-
bit stop, no parity.
5. I like Tera Term for its superior scripting capabilities. I literally developed a data logging program
using Tera Term scripts. I also use Terminal by Bray++ when I am testing and configuring sensors.
It not only separates “send” and “receive” in two text boxes, but also has buttons to send custom
strings such as “1M!”. You can also log all communications on the port to a text file for future
reference.
To test the sensor on MAC, Linux, Raspberry Pi, or Beagle Bone Black, install "screen" if it is not already
installed. To install screen, do the following:
Once installed, do "screen port" to communicate with the sensor. Replace port with the actual port name
you discovered in step 3. To quit the program, press ctrl-a, then press k and confirm with y.
6. Before you can have access to the serial port, your linux user needs to be in the "dialout" group.
If you already installed programs such as Arduino IDE, chances are you are already added to the
group. You can first check:
sudo groups [your_user_name]
You will see a list of groups your user belongs to. If it doesn't belong to the "dialout" group, you
need super user password to add yourself to the group:
Log out and log back in for the command to take effect.
7. Remember that SDI-12 commands DONNOT end with a new line or a press of Enter or Return key.
They end with ‘!’. On the other hand, SDI-12 sensor responses always end with ‘\0D\0A’. This is
going to cause your terminal program to print new lines. All my future sample responses will
ignore these characters for clarity. Once you are connected to the adapter and the sensor with
11
your serial port program, issue '?!' command (without quotation or any new line). The sensor
should respond with its 1-character address, such as '0' if the sensor has an address of 0. We will
need to change its address with the next command '0A1'. This changes sensor at address '0' to
address '1'. The sensor will respond with its new 1-character address '1'. Make sure the new
address is not already used by another sensor. I always use addresses above '0' because some
sensors, when left at address '0', will attempt to communicate using their own protocol at power-
on, such as Decagon sensors. This could confuse the adapter or other sensors on the bus.
8. Now that we have properly set the sensor address to '1', we will do a measurement by issuing this
command '1M!'. The sensor will respond with something like '10012'. This means that sensor '1'
needs '001' seconds to produce '2' measured values. For example, Decagon 5TM soil sensor
measures dielectric constant and temperature (°𝐶) and returns values within 1 second. It would
return '10012' to indicate what you should expect. Now you wait for a confirmation that the
measurement is done. This is given by a '1', indicating sensor '1' is done.
9. To retrieve data, issue this command '1D0!', that is one-Dee-zero-!. The sensor will respond with
something like this '1+1.03+20.5'. Assume Decagon 5TM sensor again, it means sensor '1' returns
two values '1.03' and '20.5'. You need the sensor's manual to determine which value means what.
In this case, 1.03 was the dielectric constant (it's not in soil so reporting the air value close to 1)
followed by 20.5°𝐶 temperature. Now the process of collecting data is complete. You can repeat
it as much as you like or disconnect the sensor, connect another sensor for configuration.
The next several sections are about specific adapters and they each have page breaks before them. You
can thus print only the adapters you have and skip those you don't have, just to save some paper.
12
4. SDI-12 USB adapter
This is the basic adapter that fits most people's need. The adapter has a couple of onboard options such
as reading basic analog inputs and counting pulses from sensors such as flow meters and rain gauges
and reports the most recent counts since last reading. This gives you the ability to add those sensors and
read them out the same way as any SDI-12 sensors. You can also purchase addon boards to add hi-res.
(16-bit autoscaling) analog inputs. This section explains how to make use of these features.
This 12-pole terminal block is organized in four sections for four inputs: “3+-“, “2+-“, “1+-“, and “0+-“.
Analog inputs
Unlike the SDI-12 “+”, these “+” are always from the 5V USB power. As a result, different USB ports, hubs,
and computers may have as much as ±0.1𝑉 of variation around the “5V”. This variation is a combination
of the difference in output voltage and voltage variations from different USB load conditions. This will not
affect you if you are reading ratiometric voltage sensors or resistive sensors (using voltage dividers) due
to the ratiometric nature of these sensors. On the other hand, if you are reading a voltage sensor that is
not ratiometric, you can have this much variation on top of uncertainty of the readouts.
For resistive sensors using voltage divider, refer to “SDI-12 + Analog adapter” under “Resistive sensors”.
The basic analog inputs don't have integrated pull-up resistors so you must supply one yourself between
'+' and the respective channel. Make sure you pick a resistor precise enough for your measurements.
13
The accuracy of the analog input is 5mV. The maximal voltage it can read is 5V. It has 10-bit or one out of
1024 (210 = 1024) accuracy across the 0-5V range. It cannot read any negative voltages.
Digital inputs
You can read HI/LO status or count with these digital inputs. The former is used to read status of ON/OFF
sensors (i.e. rain sensor ON for raining) while the latter is used to count rain gauges or rotary sensors.
Sensing commands
Analog channels are sensed the SAME way you would sensor an SDI-12 sensor. The address is ‘z’ (lower
case Z). Send 'zM8!' to the adapter for analog/digital measurements. Use 'zD0!' (zee-Dee-zero-!), to get
analog values. Use 'zD1!' to get digital ON/OFF values. Send 'zM9!' for digital counts. Use 'zD0!' to get the
counts. If you have a simple digital pulse output that goes from L to H then back to L, the counts are twice
many as you expect because it counts both L to H and H to L. Other sensors rely on alternating L/H and
L/H to report pulses. The counts are cleared after each read. Time your read so you can calculate a rate.
The adapter is in the analog/digital ON/OFF mode at start-up. To set it in digital counter mode, just
perform a counter reading with 'zM9!'. You don't have to read the counts but what the adapter does is
to set its channels to digital counter mode, clear counts, format the output, in case you do read the counts.
Any subsequent 'zM8!' reads will put the adapter back in the analog/digital ON/OFF mode.
If you mix analog and digital ON/OFF sensors, say channels 0 and 1 are analog and channels 2 and 3 are
digital, just perform a single 'zM8!' and then 'zD0!' to get analog inputs, then 'zD1!' for all digital ON/OFF
inputs. Discard analog values from channels 2 and 3 since they are your digital channels. Also discard
digital values from channels 0 and 1 since they are your analog channels. Reading an analog input as a
digital input should not affect it. When performing digital read, the adapter engages internal pull-up
resistors. When performing analog read, the adapter disengages the internal pull-up resistors.
What if you mix counters with non-counters? This is a bit more complicated. To enable counter mode,
you must first perform a counter read 'zM9!' to set the adapter to counter mode. Then when it's time to
read counters, perform 'zM9!'. You will receive the counts with 'zD0!'. To get non-counter reading,
perform 'zM8!'. You will receive analog values with 'zD0!' or digital ON/OFF values with 'zD1!'. Now you
have to set the adapter back to counter mode by performing a 'zM9!' read. The counts, if any, between
the adapter switching to analog/digital ON/OFF mode and back to counter mode are lost. It only takes a
very small fraction of a second to do this switch so unless you have a very high count rate, you are OK.
Alternatively, you could get two adapters with one dedicated to counters and the other to non-counters.
Each can also connect to several SDI-12 sensors. If you have high-speed pulses, dedicate one adapter to
reading counts only, without SDI-12 sensors on it.
The reason that the adapter can't read both counters and non-counters is a precaution against SDI-12 bus
timing error when an analog input channel is changing very fast and triggering huge number of counts,
thus interrupting the processor too frequently and causing timing to slip on SDI-12 bus.
The adapter acts as an SDI-12 sensor that reports values, depending on sensing mode. This makes it very
easy to integrate analog/digital/counter sensors into your existing data logger with SDI-12 USB adapter.
14
Complete list of SDI-12 USB adapter commands:
Command Response
'z!' 'z\r\n' This means that the adapter is responding to queries.
'zI!' 'z13Liudr SDITRD144\r\n' This indicates that the firmware is in version 1.4.4. You
may see a different number depending on the firmware version.
'zM8!' 'z0018\r\nz\r\n' This means that the adapter needs 1 second to acquire 4 single-ended
auto-scale analog values and then read the same channels as digital inputs. The second
‘z’ indicates it completed the acquisition.
'zM9!' 'z0012\r\nz\r\n' This means that the adapter needs 1 second to acquire 2 differential
auto-scale analog values. The second ‘z’ indicates it completed the acquisition.
'zD0!' 'z+1.234+2.345+3.456+4.567\r\n' if 'zM8!' was issued. These are analog voltages.
'z+100+250+0+15\r\n' if 'zM9!' was issued. These are transition counts. Each HIGH to
LOW or LOW to HIGH is counted so if your rain sensor produces a LOW-HIGH-LOW
sequence for say one spoon tipping, you double count. Some sensors alternate between
H/L and L/H transitions and thus the adapter counts both transitions. The count is
cleared after each read so if you do your read say once per 5 minutes, you can calculate
rate as readout/5minute.
'zD1!' 'z+1+0+0+1\r\n' if 'zM8!' was issued. These are H/L values of each input. Usually above
2.5V gets 1 and below 0.7V gets 0.
If you have attached a hi-res. analog addon board and its address jumper is set to 0. The following
commands are also available:
'zM!' 'z0014\r\nz\r\n' This means that the adapter needs 1 second to acquire 4 single-ended
auto-scale analog values. The second ‘z’ indicates it completed the acquisition.
'zM1!' 'z0012\r\nz\r\n' This means that the adapter needs 1 second to acquire 2 differential
auto-scale analog values. The second ‘z’ indicates it completed the acquisition.
'zD0!' 'z+1.23456+2.34567+3.45678+4.56789\r\n' or 'z+1.23456+2.34567\r\n' These are
single-ended or differential channel readings, depending on whether M or M1 was
issued before D0.
Up to 4 addon boards can be attached. If you have a second hi-res. analog addon board attached with
address jumper set to 1, replace 'zM!' with 'zM2!' and replace 'zM1!' with zM3!'. Still use 'zD0!' to get data.
Addon board 0 has zM0, zM1. Addon board 1 has zM2, zM3. 'zM0!' is the same as 'zM!'.
Addon board 2 has zM4, zM5. Addon board 3 has zM6, zM7.
15
5. SDI-12 + Analog adapter
The SDI-12 + Analog USB adapter has four analog channels along with SDI-12 connections and external
power connector and jumper. This section explains how to make use of these features. The following
figure demonstrates how to set analog channel jumpers and the SDI-12 power jumper.
The jumpers in the picture above are colored only to make the picture easy to understand. All jumpers
shipped with the adapter are black. The red jumper selects power supplied to SDI-12 sensors. To power
SDI-12 sensors with 5V from USB (default setting that works for most sensors), place the jumper between
center pin and top pin (as pictured) 5V from USB. To power SDI-12 sensors with external DC power on the
external power terminal block, place the jumper between center pin and bottom pin. Make sure the
external power is DC instead of AC and its polarity is consistent with the adapter (see back side of the
adapter).
Each analog input has three jumper pins, such as H,3,L for channel 3 below the green jumper. The green
jumper demonstrates how to enable 1K pullup resistor (jump 3 and L) on channel 3. This is ideal for reading
PT1000 temperature probes or any other resistive sensors with values around 1K. The blue jumper
demonstrates how to enable 10K pullup resistor (jump H and 1) on channel 1. This is ideal for reading 10K
thermistors or any other resistive sensors with values around 10K. Channels 2 and 0 don't have either
resistor enabled so they are perfect for reading voltage sensors such as pyranometers. In general, the "L"
("H") side connects the channel to a lower (higher) resistance value i.e. 1K (10K) pullup resistor. You can
set any channel to have 1K, or 10K, or no resistor. The precision resistors are 0.1% 10ppm/DegC.
16
Figure. SDI-12 + Analog USB adapter SDI-12 sensor wiring with USB 5V supplied to SDI-12 sensors
To supply external power, follow the wiring and jumper setting diagram below. Make sure you check the
polarity of your external power before connecting to the board. DC power ONLY!
Figure. Connecting external power and setting jumper to supply external power to SDI-12 sensors
17
Resistance sensors
The sensor changes its resistance when there is a change in the physical parameter, such as temperature
(PT1000 thermometer, NTC-negative temperature coefficient sensor a.k.a. thermistor) or light intensity
(LDR-light dependent resistor). Resistance measurements are available on every analog channel via a
voltage divider. You will use single-channel measurement command for your sensor. The channels come
with select-able high-precision low-temperature-drift pull-up resistors. You can select 1K resistor for
PT1000 and anything with low resistance or 10K resistor for 10K thermistors, LDRs, or anything with higher
resistance. The 'H' at the jumper means 10K resistor. The 'L' at the jumper means 1K resistor. Jump the
channel with 'H' connects the 10K pull-up resistor. Remove the jumper to not have either resistor
connected. See figure.
You will be collecting a voltage from this channel and using the following formula to calculate resistance
(and then temperature or brightness etc. from resistance):
𝑉𝑜𝑢𝑡
𝑅= 𝑅
𝑉𝑈𝑆𝐵 − 𝑉𝑜𝑢𝑡 𝑝𝑢
Here 𝑉𝑜𝑢𝑡 is the readout of the channel. 𝑅𝑝𝑢 is the resistance of the pull-up resistor you selected via the
jumper, either 1K or 10K. 𝑉𝑈𝑆𝐵 is the USB voltage. The USB voltage is nominally 5V but varies from system
to system. The best way to be accurate is to leave one analog channel unused and selecting 1K resistor.
The reading of this channel is the USB voltage. The next best way is to measure USB voltage between '+'
and '-' at the analog channel and note it down. This saves one channel but the fluctuation of USB voltage
will make your results fluctuate. If you have a USB device that could use a lot of power and drops USB
voltage when they are operating, such as a portable hard drive, a 3G dongle, or Wi-Fi dongle, and you
want to use PT1000, it is probably best to place these devices on a powered USB hub so they don't affect
the adapter's analog channels. For a Raspberry Pi, a powered USB hub is almost always required when
operating these high-power devices.
Voltage sensors
If your sensor generates a voltage without needing power supplied to it, such as a pyranometer, you
should remove the jumper to disable the pull-up resistors. You can use single-ended mode to
accommodate more sensors, or differential mode for better precision. In either case, the USB supply
voltage will NOT affect the readings. To connect a sensor in single-channel mode, connect the positive of
the sensor to the pin marked with the channel number, such as 0,1,2,3. Connect the negative of the sensor
to '-'. To use differential mode, use 0 for positive and 1 for negative for one sensor, 2 for positive and 3
for negative for the other sensor. Differential mode uses two channels to read one sensor at better
accuracy.
If your sensor generates a voltage but requires power supplied to it, such as a Maxbotix sonic ranger, you
should also remove the jumper to disable the pull-up resistors. You can use single-ended mode to read
the sensor, unless the sensor has a negative output separate from the negative power pin. To connect in
single-channel mode, connect the positive of the sensor output to the pin marked with the channel
number, such as 0,1,2,3. Connect the positive of the sensor power to '+'. Connect the negative of the
sensor power to '-'. If your sensor has a sensor negative output separate from sensor negative power,
you can use differential mode. Supply the sensor power with '+' and '-' and connect sensor output positive
and negative to channels 0 and 1.
18
Analog channel accuracy
The four analog channels are as accurate as 0.02mV when the signal is small, below 0.256V. The adapter
automatically uses the most sensitive scale for the signal. The highest signal allowed is 6.144V on any
channel. There are 6 ranges (gain levels), with maximal ranges of 6.144V, 4.096V, 2.048V, 1.024V, 0.512V
and 0.256V. Within each range of voltage, the analog input is turned into a numerical value between 0
and 32767. So if you have a signal that is 0.1V, using the largest range of 6.144V will give a smallest change
of 0.1875mV. This sounds very accurate, because this change is 0.1% of the signal. But the real resolution
of the ADC is not the smallest change. It is usually many times that. Plus there is fluctuation in supply
voltage and noise in the signal. The result is likely in the neighborhood of 2mV. This becomes 2% of the
signal magnitude. But if you use the 0.256V range, its smallest change is 0.0078125mV. The accuracy is
about 0.02mV to be conservative.
Auto scale
Since SDI-12 standard has no way to change scale, the adapter does it automatically. The auto scale is
done with a 10%~90% range. The adapter first reads the input with the largest scale to protect the
converter. It then calculates the smallest scale that will fit the signal within 10%-90% of that scale. It reads
at this scale and returns the value. Each channel is auto scaled independently from the other channels so
you may have some larger signals automatically read at a larger scale and smaller signals automatically
read at a smaller scale.
Sensing commands
Analog channels are sensed the SAME way you would sensor an SDI-12 sensor. The address is ‘z’ (lower
case Z). Send 'zM!' to the adapter for single-ended measurements. Send 'zM1!' for differential
measurements. If you have them mixed, say channels 0-1 is used as differential for a pyranometer and 2,
3 are single-ended for two PT1000 temperature sensors, sense it twice, once as single-ended, and discard
values from channels 0 and 1. Then sense differential, discard value from 2-3 differential.
In both modes, you use ‘zD0!’ (zee-Dee-zero-!), to get data. The adapter acts as an SDI-12 sensor that
reports values, depending on sensing mode. This makes it very easy to integrate hi-res. analog inputs into
your existing data logger with SDI-12 USB adapter.
19
Complete list of SDI-12 USB + Analog adapter commands:
Command Response
'z!' 'z\r\n' This means that the adapter is responding to queries.
'zI!' 'z13Liudr SDITRD130\r\n' This indicates that the firmware is in version 1.3.0. You
may see a different number depending on the firmware version.
'zM!' 'z0014\r\nz\r\n' This means that the adapter needs 1 second to acquire 4 single-ended
auto-scale analog values. The second ‘z’ indicates it completed the acquisition.
'zM1!' 'z0012\r\nz\r\n' This means that the adapter needs 1 second to acquire 2 differential
auto-scale analog values. The second ‘z’ indicates it completed the acquisition.
'zD0!' 'z+1.23456+2.34567+3.45678+4.56789\r\n' or 'z+1.23456+2.34567\r\n' These are
single-ended or differential channel readings, depending on whether M or M1 was
issued before D0.
20
6. SDI-12 + GPS adapter
The SDI-12 + GPS USB adapter has space for an Adafruit Ultimate GPS module (part number 746). This
section explains how to make use of these features. The following figure demonstrates how to set the
power source jumper. The jumper is between the two green 3-pole screw terminal blocks. Setting it to
the left (there is a "+X" symbol on the bottom of the board) allows external power source to power the
SDI-12 sensors. Setting it to the right (there is a "5V" symbol on the bottom of the board) allows the USB
5V to power the sensors. Notice the antenna connector on the GPS board. Its cable runs between two
green blocks on the right side of the board. This orientation allows easy removal of the antenna connector.
Figure: SDI-12 + GPS adapter (GPS module must be purchased separately from adafruit, part 746)
SDI-12 blocks
This adapter has the same layout as the basic SDI-12 USB adapter. Please refer to “SDI-12 terminal blocks”.
GPS module
You may find the need to log GPS coordinates, get accurate date and time, or speed of the logger. That
requires additional hardware and distracts you from focusing on making your logger. Enter GPS! The GPS
module works as if it were just another SDI-12 sensor so you don't even have to change the logger code,
just add address 'z' to the list of SDI-12 sensor addresses. This is the easiest way to get GPS information
on your system.
Sensing commands
GPS information is sensed the SAME way you would sensor an SDI-12 sensor. The address is ‘z’ (lower case
Z). Send 'zM!' to the adapter for location/speed. Send 'zM1!' for date, 'zM2!' for time.
21
After any measurement command, you use ‘zD0!’ (zee-Dee-zero-!), to get data. The adapter acts as an
SDI-12 sensor that reports values, depending on sensing mode. This makes it very easy to integrate
geolocation and time into your existing data logger with SDI-12 USB adapter.
Command Response
'z!' 'z\r\n' This means that the adapter is responding to queries.
'zI!' 'z13Liudr SDITRD140\r\n' This indicates that the firmware is in version 1.4.0. You
may see a different number depending on the firmware version.
'zM!' 'z0014\r\nz\r\n' This means that the adapter needs 1 second to acquire longitude,
latitude, altitude, and speed. The second ‘z’ indicates it completed the acquisition.
'zM1!' 'z0011\r\nz\r\n' This means that the adapter needs 1 second to acquire the date values.
The second ‘z’ indicates it completed the acquisition.
'zM2!' 'z0011\r\nz\r\n' This means that the adapter needs 1 second to acquire time values. The
second ‘z’ indicates it completed the acquisition.
'zD0!' The returned values depend on the command issued.
M: 'z-09412.3456+4554.3219+321.09+1.23\r\n'
GPS longitude -094 degrees, 12.3456 minutes (-94.20567 ° ), latitude 45 degrees,
54.3210 minutes (45.90535°), altitude 321.09 meters, speed 1.23 nautical miles per
hour aka 1.23 knot (1.42 mi/hr or 2.28km/hr).
M1: 'z+190317\r\n'
Day 19 of month 03 (March) of year (20)17.
M2: 'z+065402'
Hour 06, minute 54, second 02.
The reason that there are three commands is because many applications only need geolocations and
don't have to get date or time. If you need all of them logged at the same time, try my python logging
script version 1.6.0 or higher. You can specify address z and sensing commands 012 to make it log all
inputs.
22
7. Installing Python, Pyserial, and cURL
Since we will be running Python scripts for sensor setup and data logging, we will need Python version 3.4
or higher and Pyserial version 3.0 or higher. You also need to add your user to a group if you are running
linux. In order to use the server data upload feature to send a copy of your data to thingspeak.com data
server, you also need cURL (no longer needed by script version 1.6.0 and higher but still a useful tool).
If you want to log data on a raspberry pi and wish to skip all these software installation steps, you can get
a raspberry pi microSD card from me with a preconfigured system where everything is ready to go.
To check if you have the required Python version, first open a command prompt (windows) or terminal
(other OS), then enter "python". If this command starts Python Shell version 3.4 or higher, you are good
to go. Otherwise, try "python3". If this still doesn't work, you don't have python and need to install it.
To check if you have cURL, open a command prompt (windows) or terminal (other OS), then enter "curl".
If you get a response, then you already have cURL.
Windows:
Please remove any older Python first. Follow the link to download Python 3.x installer:
https://www.python.org/
Make sure that you check the box “Add Python 3.5 to PATH”. This is crucial.
https://curl.haxx.se/download.html
23
Find either 32-bit or 64-bit MSI installer. Not getting this work won't affect you if you log your data locally
or use your own routine to upload data. Starting with logging script 1.5.1, cURL is no longer needed for
uploading data. Now you should be able to use the SDI-12 USB adapter.
Mac OSX:
Please remove any older Python first. Installing Python on a Windows or Mac OSX machine is a snap. Just
follow the link to download installers (3.5.1):
https://www.python.org/downloads/release/python-351/
Once you installed Python, use pip to install Pyserial. Open a terminal (find it from launch pad) and
enter:
python -m pip install pyserial
If somehow you already have an older version of Pyserial installed, upgrade it:
python -m pip install --upgrade pyserial
Note, there are two dash lines before "upgrade". You may have to replace "python" with "python3" if you
notice that the above commands print out a lot of warnings and errors. Remember, if "python" brings up
Python 2.7, you have to use "python3" to bring up Python 3.x.
Install cURL from this link:
https://curl.haxx.se/download.html
Find the latest OSX installer. Not getting this work won't affect you if you log your data locally or use your
own routine to upload data. Starting with logging script 1.5.1, cURL is no longer needed for uploading data.
Now you should be able to use the SDI-12 USB adapter.
Raspberry Pi:
Make sure you download the latest Raspbian:
https://www.raspberrypi.org/downloads/raspbian/
Once you get your Raspberry Pi up and running, enter the following commands to update your system:
sudo apt-get update
sudo apt-get upgrade
sudo reboot
After system reboots, install the latest version of pyserial. Raspbian may come with a stock version of
pyserial that doesn't work (well enough) with its stock python3.
The first command removes this old stock version. The second command installs the latest version.
Raspbian comes with cURL. Just in case yours doesn't, do the following:
sudo apt-get install curl
24
Now you should be able to use the SDI-12 USB adapter.
Upgrade it:
After this, you may install or upgrade pyserial and urllib3 (for telemetry with thingspeak.com server):
or:
Then:
sudo pip3 install urllib3
or:
PC running GNU/Linux:
If you already found Python 3.4 on your Linux, good for you! Follow the instructions for Raspberry Pi to
get your Linux computer ready for the SDI-12 USB adapter. If you have an earlier version of Python, this is
going to be difficult. You can't just download an installer for Python 3.5 like on Windows or Mac OSX. You
are stuck with whichever Python 3 version that comes with your Linux distribution. I'll use Debian as an
example. If you have a Debian Wheezy distribution, you are stuck with Python 3.2. If you can, look for
online instructions to upgrade your distribution (details vary among distributions). If you have to use your
current distribution version, you have to compile the source code of Python 3 and install it. I suggest
installing Python 3.5. To install Python from source, read the appendix. If you are planning to upgrade
your distribution to Debian Jessie, do the upgrade and you will get Python 3.4, which is good enough. If
you have Debian Stretch, you already have Python 3.5.
Your Linux probably comes with cURL. Just in case it doesn't, do the following:
I also sell microSD cards with everything installed and ready to go, for a nominal fee. Just get a Raspberry
Pi of any model and you are good to go.
25
8. Data logging using Python Scripts
The following are based on logger script version 1.5.0. For more sophisticated script such as 1.6.0, read
the "Advanced topics on data logging" section. There are two Python scripts:
• sdi_12_config.py: This scans the SDI-12 bus for a sensor and displays its information. You may
change the sensor's address and save your change. You can only connect one SDI-12 sensor at a
time. We will use this script to set up a sensor.
• sdi_12_logger.py: This logs data to a text file. It asks you for a few parameters, such as serial
port, SDI-12 address, delay between data points, total data points, timestamp (local/GMT) etc.
You should store these two scripts in the folder that you want your logged data files. On a GNU/Linux
system, such as Raspberry Pi, it is recommended to be stored under /home/pi
First run sdi_12_config.py by typing "python sdi_12_config.py" or "python3 sdi_12_config.py" (the exact
script name includes version number such as sdi_12_config_v1_1.py) or open it in IDLE and execute it:
The script has a text-based interface (see below). This is to save resources so you can easily run it on a
Raspberry Pi over a terminal window over a 2G GPRS model, or 3G/4G wifi hotspot in the field, instead
of using up more bandwidth required by a graphical user interface.
The script asks you to select the correct serial port. Windows uses numbered port names such as COM3.
Linux/Raspberry Pi use numbered port names such as /dev/ttyUSB0. Mac uses alphanumeric sequence
26
as the port name (it's the last portion of the USB unique ID of the USB serial chip on the adapter). If you
are unsure, just select the last one on the list. If it didn't work, remove the adapter and rerun the script
to see which adapter name has disappeared. That's the correct one.
Once the script identifies the sensor address and displays its information, you may change the sensor
address and complete the configuration. If you need to configure more than one sensor, disconnect the
sensor that is configured, connect the next sensor and repeat. Now you are ready to log your data.
Run the data logging script with "python sdi_12_logger.py" or "python3 sdi_12_logger.py" (the exact
script name includes version number such as sdi_12_logger_v1_1.py) or open it in IDLE and execute it:
You will be asked the serial port, total data points, delay between data points, GMT or local time stamps,
and SDI-12 sensor address (in logger code version 1.3 and up, also whether you want to collect analog
inputs, for SDI-12 + Analog USB adapter only). To log data from multiple sensors, supply sensor addresses
such as 1234 for sensor addresses 1-4. Make sure you configure your sensors (one at a time) to these
addresses. Data logging will start immediately after you input the parameters. You may stop data
collection with Ctrl – C any time without losing any data. You may need to wait for a while before the
program is ended by Ctrl – C.
27
File Format
Your data will be stored in comma-separated-value (.CSV) format. The file name is the date and time when
the script starts logging data. There are at least three columns. The first column is the date and time the
data point is collected. Depending on your choice, it is either in GMT/UTC or local time. The next column
is the sensor address. The third column is the first value returned by your sensor. If your sensor returns
more than one value, additional columns will contain additional values.
This file format is ready to be read by any major data analysis tools such as Excel, Open Office Calc, or the
more expensive Origin Pro. Here is a sample of data collected from a Decagon 5TM soil temperature and
moisture sensor. The first data column is the relative dielectric constant (1 for air, yes, it’s NOT in soil).
The second data column is temperature.
If you prefer spaces or tabs or other separators, look for this line of the data logging script:
Just change the , into '\t' for tab, or other symbols you want.
28
9. Plotting and automatic plot update
Once your data logging has started, you can use Microsoft Excel to plot the sensor data while recording
and set the spreadsheet and plot to automatically update as more data are collected.
29
Figure. Select “Comma” as delimiters for data columns.
30
Figure. Choose Properties to make Excel automatically refresh data, optional.
Figure. Uncheck “Prompt for file name on refresh” and check “Refresh every X minutes”.
31
Figure. You may insert a chart (scatter) with time and data columns. More data will be added to the plot
and spreadsheet when Excel automatically refreshes.
Figure. Format column 1 to unhide seconds. Use custom format and type in “mm/dd/yyyy h:mm:ss”.
32
Figure. Time column now shows seconds.
33
10. Logging Data to the Internet
If you think the above is already what you need, great! I have even more free cool stuff for you. If you are
a researcher or data analyst or just want to store data online, you would love to send your data to a
database, and have it plotted on a plot real-time, for everyone to see, of course only those you intend to
share your data with.
Thingspeak.com has a wonderful Internet of Things (IoT) database for free. You can easily post your data
to the server using the free data logger script. No programming experience is needed. You can view the
plots and download all your data from the server using a simple web interface thingspeak provides. You
can also construct more sophisticated dashboards with graphs, downloads and other features using HTML,
ajax etc. The data logging script executes a cURL command to post your data online so you need to follow
The reason that there are three commands is because many applications only need geolocations and
don't have to get date or time. If you need all of them logged at the same time, try my python logging
script version 1.6.0 or higher. You can specify address z and sensing commands 012 to make it log all
inputs.
34
Installing Python, Pyserial, and cURL to install it.
If you run the data logging script V 1.5.0 with uploading enabled (by default), it will post up to six sensor
values from each measurement to the following data stream:
https://thingspeak.com/channels/359964
Here is a screen shot. You can download data and examine your data in graphs.
Figure: Data posted to the data stream. Left is soil dielectric constant. Right is temperature in DegC.
Be aware that others are also uploading to the same stream by default so you may see data from them.
You can create your own Thingspeak account and data stream (follow their tutorial). Then in the Python
data logging script, replace these values with your information:
channelID = "359964"
api_key = "GTOEBKK8ZQHI1V1B"
You may also change the maximal number of values per measurement to 8 in the code by modifying two
places that have (i<6) into (i<8). The limit set by Thingspeak is 8 values per measurement. To record more,
you must create more data streams.
35
11. Advanced topics on data logging
Since data logging for soil or water is usually year-around or at least days or weeks at a time, you may
want to consider dedicating a raspberry pi to logging data instead of using your main computer. You will
need a way to run the data logging routine for long periods of time and resume the routine in case power
is lost and later restored. This requires constant power to your logger, rugged enclosure, and installing
the data logging script as auto-start on raspberry pi. Please also consider buying a few spare adapters for
repairs and lab tests. It will keep your down time to minimal. Make sure you tidy up the wires and don’t
allow them to tangle or short circuit.
I have used a specific brand of knock-out series enclosures from the following US vendor: Polycase. They
make a ton of their own enclosures in the US but this knock-out series are imported from Germany:
https://www.polycase.com/sk-series
They use metric knock-out holes. If you see an M16/M20 hole, you can knock out a smaller 16mm
diameter hole or knock out a bigger 20mm diameter hole at the same location. The bigger hole is a ring
around the small knock-out circular cover. You can also later cover them up with hole plugs if you decide
to not use the hole. I usually purchase cable glands (cord grips) from here:
https://estore.heilind.com/M4334/HEYM4334.html
A raspberry pi looks small but its connectors (MicroUSB power, USB for the adapter, etc.) and cables
require more space than just the pi itself. Also a cable gland takes some space inside the enclosure and
makes the cable a bit more rigid right at the gland. Leave some extra space for expansion. Please plan
your layout before deciding on which one to buy. I usually use the SK-20 for its size if I have a raspberry
pi and its options with M16 holes for buttons and clear cover for LCDs. I will also purchase the mounting
plate to mount the circuits and a flange kit for mounting it against flat surfaces.
36
I have used 16mm diameter waterproof temper-resistant push buttons from Sparkfun Electronics and
Adafruit Industries. They also sell push-on cables for more convenient wiring to the buttons. The
momentary buttons are good for actions, such as inputs. The latching buttons are good for turning on and
off power to your logger or enabling/disabling a feature because it stays depressed so you don’t have to
keep your finger pressed down on the button all the time.
https://www.sparkfun.com/products/11968
https://www.sparkfun.com/products/11973
https://www.adafruit.com/product/1152
You could purchase an Arduino Micro or Sparkfun pro micro and program it to emulate keyboard button
presses when you press on these waterproof buttons. It makes it so much easier than trying to use a
wireless keyboard in the field although a wireless keyboard can be a nice backup if you need to type.
But since the data logging script starts without user's interaction, how will it receive parameters such as
the choice of serial port, delay time, total data points? You can feed all those from a file.
On a GNU/Linux system, the standard input from a keyboard can be redirected from a file. Essentially
you type up what you would enter with your keyboard in a file and let the script take the content of the
file as input. The data logging script also has output, such as startup information and prompt for inputs
and mostly debug information while it runs. It will be printed to the default HDMI output and you surely
won't be able to see it. So instead, you redirect its standard output (screen) to a file so the file will store
what the script normally sends to the screen. You can later read this file to determine if anything weird
happened.
This version expects interactive inputs from the user at the start to run. To auto start, you simply supply
these inputs from a file.
cd /home/pi/Documents/Python/SDI_logger
The ampersand is to run the command in the background so it doesn't hang the startup process
(preventing the login prompt from showing).
37
The first portion in green is the full path of the data logger script. Make sure you modify it to include the
proper version number. The second section in blue is redirected input. The less-than symbol does the
redirecting. The logger.conf file should include everything you are supposed to type in, such as:
1000
600
The above file selects 0 out of the serial port list (change it to match your system), logs 1000 data points
with 600 second delay between data points, using local time (0 for GMT, 1 for local) and SDI-12 sensor
address A. Y or N answers the "Collect analog inputs?" question in case your adapter has Analog inputs.
Answer Y if you have an SDI-12 + Analog USB adapter and want to collect analog inputs or no if you don't.
It's best to create this file on raspberry pi and make sure there is an empty new line after the last line. I
recommend using the text editor "nano" to write this file, or the GUI program Leaf.
The last portion in orange is the redirected output file. The greater-than symbol does the redirecting.
Everything the script is supposed to send to the screen is saved in it. If you want to accumulate the
information between runs, use double great-than symbol to append new output to existing output file.
Before entering the following commands at the end of /etc/rc.local, run the commands in a terminal first,
without the output redirect (>> and 2>) or background running, such as:
cd /home/pi/Documents/Python/SDI_logger
Make sure you have the correct logger script version number in the script name and logger.conf triggers
the right actions.
Just one last thing, when running the script automatically at startup, the local data files are saved under
the root directory with root as owner. Every time the raspberry pi loses power and then gets power
restored, it will start the logger script again, i.e. generating a new local file with the yyyymmdd.csv file
name so you know how many times your raspberry pi has lost power.
In case you want to terminate the data collection, log in to raspberry pi, and run command:
ps -A
This lists all processes. There will be one process called sdi_12_logger… The name is truncated from the
name of the data logging script. Copy down the process number on the same line. You want to kill this
process to stop data collection. Pretend the number is 123, enter:
38
This will stop the script. If you properly shutdown the raspberry pi, the data logging also stops. You can
then pop the raspberry pi's SD card into a card reader and get its locally stored data off your main
computer. On a windows machine, this requires a plug-in: ExtFS for windows:
https://www.paragon-software.com/home/extfs-windows/
This program allows a windows machine to mount GNU/Linux file systems (ExtFS).
If you want to make it easy to change the config file without this software, you can place it inside /boot
folder, which resides in the small FAT32 partition that any OS can read. You need sudo to copy it there:
This way it becomes easy to just pop out the SD card from an RPI, place it on a PC and edit its contents,
since any PC will display the "boot" volume and thus will have access to the config file.
Running the script in /etc/profile has the same effect as running the script in rc.local but you are in a well-
defined run level with all the support already running before the logging script runs. On my raspberry pi
system, I also have enabled VNC so I can remotely connect to the logged in user session for monitoring. I
will demonstrate how to set up logging script version 1.6.0 below. This is a more sophisticated logging
script but gives you more capabilities in logging.
A separate document is dedicated to the changes and how to set it up. Please read it carefully.
https://www.dropbox.com/s/zul4j17s2lid6um/Changes%20in%20version%201.6.0.pdf?dl=0
Add command to the end of the file. Append with & if script runs indefinitely.
cd /home/pi/Documents/Python/SDI_logger
39
Python script to load the firmware to the adapter. The script has been tested under Windows, Mac OSX,
Linux (64-bit), and Raspberry Pi so you can make the firmware update on any system. You will run the
script just like the data logging script or config script.
1. Install Python 3.4 or higher with Pyserial 3.0 or higher (instruction in the manual).
2. Unzip the content of the firmware update package in a folder.
3. On a Windows PC, check the properties of avrdude.exe to make sure that it is not blocked. On a
Linux, the python code automatically sets the correct execution bit for the Linux version.
4. Make sure your system is not running any logging script before proceeding.
5. Run the script SDI_12_firmware_update.py in Python environment IDLE.
6. Select the adapter's serial port from a list.
7. Pick the firmware file, usually SDI_12_translator_v1_x.hex (must be stored in the same folder as
the script), then wait for it to complete, which takes less than 30 seconds.
I had the adapter on COM4. Once updated, try connect to it using a terminal program and send zI! (zee-
EYE!) and you will see the response has version 1.2 in it.
40
13. Need Help with Your Project?
My open-source logger code can log multiple sensors at time intervals of your choosing and optionally
sends data to the internet. If you need help setting up your computer with Python or Pyserial, I might be
able to provide free help via Teamviewer software, essentially remotely set up your computer. I can take
you through the setup process while showing you how it is done. If you need more sophisticated data
logging scripts beyond the capability of my open-source logger code, I should be able to provide paid
consulting service. Contact me on inmojo.com, leave a message on my blog, or email me. I am a full-time
physics professor at a state university so my time during semesters may be limited. I have more time
during the summer (mid-May to mid-August) though.
Email: [email protected]
Blog: https://liudr.wordpress.com/about/
Inmojo: http://www.inmojo.com/store/liudr-arduino-and-physics-gadgets/contact/
41
14. SDI-12 sensor general guide
Each SDI-12 sensor has a one-character alphanumerical address, 0-9, A-Z, a-z. There is only one data line.
The sensor shares it with the host/master. The line is usually pulled down using 100𝐾Ω resistor. Some
sensors have internal pull-down resistors but others don’t seem to have them. My adapter has this resistor.
I think Decagon sensors have some strong internal pull-down resistors. They work even without the pull-
down resistor on the adapter. But if you gang up a number of them, the effective pull-down may become
too strong for non-Decagon brand sensors to respond. In case this happens, use a second adapter for non-
Decagon sensors.
SDI-12 commands
To communicate with a sensor, you need to send a command to it. Each command starts with the SDI-12
sensor address and ends with '!'. A command does not end with new line characters such as \r or \n. Each
sensor response also starts with its address but ends with \r then \n. I will use n to represent an SDI-12
address. I will omit \r and \n in the list below. The following commands are the most common ones:
n!
This makes the sensor respond with its address so the logger knows the sensor is responding:
nI!
This makes the sensor respond with its identification:
nAm!
This changes the sensor address from n to m. The sensor will respond with the new address:
nM!
This causes the sensor to start a measurement. It will respond with the number of seconds it will take to
do the measurement and the number of returned values. When it completes the measurement earlier, it
will send a service request, which is the sensor address. So the following is from a sensor at address 1 that
needs 1 second to do the measurement and return two values. It finishes early and sends a service request.
10012
nC!
This command is not supported on all sensors. This causes the sensor to start a measurement. It will
respond with the number of seconds it will take to do the measurement and the number of returned
values. When it completes the measurement earlier, it will NOT send any service request unlike the M
command. This way the SDI-12 bus is free for the logger to keep sending C commands to other sensors
and then take time to collect data from each one using Dn command. The following is from a sensor at
address 1 that needs 5 seconds to do the measurement and return two values. Note that the number of
returned values is now two digits, instead of one digit for M.
42
100502
nD0!
This causes the sensor to return its measurement. Using nM! or nC! alone only makes the measurement.
The results are stored on the sensor and only returned when nD0! is received. Following the above
example, the sensor response will be its address and two values:
1+1.03+24.5
nD1!
If the sensor says it returns 6 values but only returns 3, then you need to keep asking it for the rest, using
nD1!, nD2! etc. until you receive all 6 values. The maximal number of returned value is 9, limited by the
single-digit response in nM!
nM1!
If the sensor is a probe with multiple sensors in it, then it will likely have a dozen or more values to return.
The standard way is to use nM! to request the first 9 values, then use nD0!, nD1! etc. to extract the first
9 values. Then use nM1! paired with nD0!, nD1! etc. to retrieve up to 9 more values, until you retrieve all
values. Some sensors pretends to return 9 values but actually returns more. An example is an AquaCheck
multi-sensor probe with 12 sensors. It rarely packs 9 sensors in one probe so if it says 9, then it means 12.
It is kind of outside the SDI-12 spec. There are more measurement commands such as M2 M3… and C2,
C3…
There are also concurrent measurement commands that you can use to speed up the measurements but
you can read all about them from the SDI-12 support group:
43
15. Trouble shooting (windows)
What if you can't make the adapter work? Go through the following check list:
Here is a quick trouble shooting procedure to determine whether you have selected the correct serial
port, for windows machines. The terminal program mentioned is Tera Term. There is a link to the
download page in the Sensor Wiring section.
1. Disconnect the adapter from your computer. Quit the terminal program by closing all its
windows.
2. Start the terminal program and select Serial. There is a drop-down menu next to the selection,
asking for which serial port to connect to. There is probably a couple of ports on the list. Take
note which serial port numbers are on the list. Then quit the terminal program by closing all its
windows.
3. Connect the adapter to your computer, make sure it has no sensors connected. Wait for a while
to see if your computer is installing driver.
44
4. Start the terminal program and select Serial. Click the drop-down menu to see if a new serial
port has appeared on the list. If yes, select that serial port and connect, if not, the driver is
probably not installed. In the screen capture below, this new serial port is COM77 (yes, I test
each adapter so my serial port number keeps going up so I have to periodically clear this list.)
If you see a new port, connect to it. Then select menu item Setup->Serial Port. Make sure you have the
right settings 9600 baud, 8 bit data, 1 bit stop, no parity. Once this is done, click the terminal window
and type in z! (lower case z) and you should see a response. Try logging sensor address z as a practice
before moving on to an actual sensor.
45
If you don't see a new port, start Device Manager to see if there are any devices with exclamation mark
or question mark, usually labeled as unknown device. Double click the item and choose Details tab on the
dialog box. Then find Hardware ID and see what's written on it. It should read VID_0403 PID_6001,
otherwise it's not the device. Once you find this device, click update driver and hopefully this time the
driver gets installed.
46
16. Frequently Asked Questions (FAQs)
How do I get all information from the GPS adapter, including coordinates?
! Let's assume that you will be using version 1.6.0 of my script. When using this logger script, it will first
ask which serial port, what sensor address, what sensing command for each sensor address. You will
answer sensor address including both your actual SDI-12 sensor addresses and the adapter's own SDI-12
address.
For example, you have two SDI-12 sensors with addresses 1 and 2. Your answer would be 12z, with the
lower-case z representing the adapter's GPS sensor address. Then when the script is asking what sensing
commands to issue for each sensor address, when it comes to address z, you will respond with 012. 0
being GPS coordinates, 1 being date, 2 being time.
The reason that I didn't put them all together in one sensing command is that the SDI-12 standard has
limitation of how many characters may be returned per sensing command and having all information
returned with one sensing command is too many characters.
47
17. Known issues (windows)
There has not been any reported issues encountered in other operating systems. Only under windows
there is the following issue, which is completely avoidable by practicing common sense:
If you disconnect the USB cable while the logger is logging data, it will cause the script the quit, true
under any operating system, since the adapter is no longer connected. You may think that by
reconnecting the adapter to USB, you would regain access to it, true for most operating systems (I
tested PC linux Mint 18.1 and raspberry pi Raspbian). But on windows 7 and 10 you will have to either
shut down your computer then start it or reboot it in order to regain access to the adapter. To the best
of my knowledge, this issue is caused by the windows version of python and pyserial not properly
releasing lock to the serial port, essentially locking themselves and other processes out of access. If you
are using a serial port program such as MobaXterm, this issue is handled gracefully and you can go back
to talking to the adapter once you reconnect it, just not the case with python and pyserial. This may not
affect you at all since you are not thinking about unplugging the adapter while the script is logging data,
correct? Just use ctrl + C to stop the script before you disconnect, if you want to reconnect the adapter
without power cycle your windows PC. This issue may be resolved if a future version of pyserial can
properly release the lock.
48
Appendix I. Preparing Raspberry Pi for Data Logging
Before you can log data with a raspberry pi, you need some preparation. At the end of this preparation,
you will have a MicroSD card with the operating system (Raspbian Jessie), data logging script and tools,
plus the necessary configuration files for data logging. You may already have a card with Raspbian with
some software installed, but in order to eliminate unknown problems, you are better off starting a new
one. If you acquired a card from me in a kit, please read through this guide as well to understand what
has been done on the card and where to find data and config files.
https://www.raspberrypi.org/downloads/raspbian/
Follow the instructions to write the image on a MicroSD card that is at least 8 GB in size and Class 10:
https://www.raspberrypi.org/documentation/installation/installing-images/README.md
There are plenty of online tutorials for this and what to do once you boot the system. I will just point out
a few important things:
1. If you view the card on a windows PC, you will only see a volume called "boot" that is a little over
50MB with only a couple dozen files. Don't worry. The rest of the content is in an ext4 file system
that windows doesn't understand. Unless you have some software to read ext4 file system, the
rest of the content stays invisible to you.
2. For a Raspberry Pi (RPI) 2B especially 3B, you need a good-quality 5V Micro-USB power supply as
well as a good-quality Micro-USB cable. I recommend the official power supply. If you are using a
random Micro-USB cable, you may have trouble with too much power loss on the cable, even if
your supply is good. When your RPI doesn't get enough voltage, it will display a rainbow-color box
on the top right corner of the monitor. You can only see this if you directly connect your RPI to an
HDMI monitor. You will not see this box if you SSH to your RPI. If voltage is too low, RPI will stop
working. Adding power-hungry USB devices to your RPI exacerbates the problem.
3. Change your password with command "passwd" in a terminal. Default user name is pi and
password is raspberry.
4. Connect monitor and keyboard mouse to RPI and boot for the first time. The system will boot and
immediately resizes sd card to take all space on the card and reboot into a GUI.
5. Upon next boot, run "sudo raspi-config" in a terminal or use the Preferences GUI, change host
name and locale. Adjust boot option to B2.
6. The best way to update software on RPI is to connect it to a home router via Ethernet cable. You
can remote log on to it and run "sudo apt-get update" then "sudo apt-get upgrade". Python
modules are upgraded with separate commands such as "pip3 install --upgrade pyserial".
Now assume that you have a working Raspbian OS on your MicroSD card, do the following to get the
necessary software:
1. Raspbian has Python 3.5. Follow "8. Installing Python, Pyserial, and cURL" for Pyserial and cURL.
2. Place the data logging script and configuration file inside /home/pi/. I created some subfolders to
keep scripts organized so my script is here: /home/pi/Documents/Python/SDI_logger
3. Follow section 8 to generate a config file
49
4. Follow section 12 to auto start the logger at power up
5. Follow section 4, do some test runs, inspect your data before setting it up for longer runs.
6. Download and install Teamviewer host for ARMV7 32-bit if you want remote access to your RPI:
https://www.teamviewer.com/en/download/linux/
7. Set teamviewer setting with a private password so you can connect to it. Note the teamviewer
ID of the RPI so you can later remote log in to it. At the time of the writing, file transfer is not
supported with Teamviewer for RPI.
50
Appendix II. Installing Python and Pyserial on Linux or Rapsberry Pi
This appendix is intended for those that already have Linux and don't wish to upgrade your Linux
distribution to the latest edition. If the python 3.x version on your Linux is lower than 3.4.x, you need to
install a later version, such as 3.5.x. You need to build it from source code.
3. Install required tools for build. Debian/Raspbian Jessie will install libdb5.3-dev while Wheezy will
install 5.1. You need to install tk-dev to make IDLE3.5 work
sudo apt-get install build-essential
sudo apt-get install tk-dev
sudo apt-get install libncurses5-dev libncursesw5-dev libreadline6-dev
sudo apt-get install libdb5.1-dev libgdbm-dev libsqlite3-dev libssl-dev
sudo apt-get install libbz2-dev libexpat1-dev liblzma-dev zlib1g-dev
4. Make python in the unzipped source code folder (Python-3.5.1), install it in a folder that is not
the current python version, such as in /usr/local/opt, delete upzipped source folder after done
cd Python-3.5.1
./configure --prefix=/usr/local/opt/python-3.5.1
make
sudo make install
sudo mkdir /usr/local/opt/python-3.5.1
51
Appendix III. Powering SDI-12 sensor with external power source
This appendix applies to the old green SDI-12 USB adapter (see below). All current adapters have a
terminal block to connect to external power. Most SDI-12 sensors work happily with the 5V supplied by
the SDI-12 adapter. If your SDI-12 sensor requires more than the 5V source, you can power it with a
battery pack or an AC adapter.
First make sure your AC adapter outputs the right voltage range and polarity. Connect the barrel to screw
terminal block adapter to your AC adapter. Use a multimeter in DC voltmeter mode to measure the plus
screw (red test probe) against the minus screw (black test probe). If you read a positive voltage in your
sensor's supply voltage range, it is a go. If you are getting a negative number whose absolute value is in
your sensor's supply voltage range, you have a center-negative AC adapter. You have to swap the
meanings of + and - on the barrel screw terminal adapter and practice caution. Add some tags to your
wire with explanations.
The following picture features a Decagon sensor. Their wire color code is white for power, bare for ground,
and red for signal. I placed a "T" on the bare wire to add a black wire so that both the barrel adapter and
SDI-12 USB adapter have a ground wire (doesn't matter which adapter gets which because they are tied).
I didn't insulate the bare wire with electric tape only for photoshoot. Some sensors such as Aquaflex
sensors have two separate grounds, one marked as SDI-12 ground and the other as sensor ground. Then
it is pretty clear that the SDI-12 ground goes to the SDI-12 USB adapter and the other ground (marked as
sensor ground or power ground) goes to the barrel adapter. As a matter of fact, Aquaflex sensors have
these two grounds tied together internally. Other 4-wire SDI-12 sensors may not have these two tied but
it doesn't matter.
52
Appendix IV. Connecting Decagon sensors with stereo plugs
Many Decagon SDI-12 sensors come with stereo plugs for Decagon data loggers. You can purchase a
stereo plug to wire lead adapter from Decagon or get one of these stereo break out boards. Many of these
break out boards are meant for stereo earplug microphone combo jacks so instead of one ring, there are
two rings. If you insert a stereo plug into this adapter, the sleeve and ring2 contacts are shorted. This gives
us an advantage. We just need to solder ring2 (photo shows it is "not soldered" but it IS, from under side),
ring1 and tip. Then insert the adapter into the screw terminal block so that tip lines up with + while ring2
lines up with -. Remember that you are NOT to insert or remove the plug from this break out board while
the adapter is powered. Stereo plugs are awesome but they create short circuits when plugged in or
removed, i.e. all three contacts (sleeve, ring, and tip) are shorted together during insertion or extraction.
This will short power to ground. The SDI-12 USB adapter has a protection fuse but you still should practice
caution.
Figure. Connecting Decagon SDI-12 sensor with stereo plug to SDI-12 USB adapter
53
Appendix V. Tera Term (windows) data logging
My initial attempt at an easy data logging script was to use Tera Term, a terminal emulator with powerful
scripting capabilities. Eventually I moved towards Python scripts since it is portable among all major
operating systems. The same script works on windows 10, Linux (Debian), Mac OSX, Beagle Bone Black,
and Raspberry Pi. I translated my original Tera Term script into Python script, retaining all original features.
With a Raspberry Pi, you can make a very low-cost data logger. If you don't wish to use Python, the
following are the instructions for my original Tera Term script as an alternative:
Once you have connected the sensor to the adapter and to a USB port, you can do some initial tests. I will
use Tera Term for tests and data collection. Assume you already installed the USB adapter driver and it is
on COM3. Start Tera Term and it will ask you to establish a new connection:
Figure. Connect to serial port. Make sure you select the correct port.
Once connected, type “zI!” and you should see response from the adapter “z13Liudr SDITRD101”. The
adapter itself has address z. It has some basic functions to read the analog voltage on pin S but I may add
more functions to it in future firmware. If you don’t receive any response, you may need to install the
driver or select the correct COM port or maybe the COM port property is incorrect. Go to Setup menu and
select Serial Port and make sure the settings are correct:
54
Figure. Serial port settings: 9600 Baud rate, 8-bit data, no parity, 1-bit stop, no flow control.
Once you have established connection to the adapter, you can set up your SDI-12 sensor. I have a sensor
configuration script to automate the process. Remember, you can only set up one SDI-12 sensor at a time,
without any other sensors connected to the adapter. Once set up, several sensors can be connected to
one adapter.
Run the script "SDI_12_Sensor_config_V1_0.ttl" by selecting menu Control then Macro. The script will
automatically detect the address of your sensor, display its information, and asks you to set a new address.
I recommend address 1 thru 9. Don’t set it to z since that is what the adapter uses. If the script didn’t work,
check your wiring, restart Tera Term, and try again.
Now your sensor is set up. You can start logging data.
➢ Sensor address
55
➢ Total data points
➢ Delay between data points
➢ GMT or Local time zone
Just run the “SDI_12_PC_Logger_V1_0.ttl” script in Tera Term. Your data will be stored where this script
is so if you store the script in a cloud drive, you will be able to view your data remotely.
File Format
Your data will be stored in comma-separated-value (.CSV) format. The file name is the date and time when
the script starts logging data. There are at least three columns. The first column is the date and time the
data point is collected. Depending on your choice, it is either in GMT/UTC or local time. The next column
is the sensor address. The third column is the first value returned by your sensor. If your sensor returns
more than one value, additional columns will contain additional values.
This file format is ready to be read by any major data analysis tools such as Excel, Open Office Calc, or the
more expensive Origin Pro. Here is a sample of data collected from a Decagon 5TM soil temperature and
moisture sensor. The first data column is the relative dielectric constant (1 for air, yes, it’s NOT in soil).
The second data column is temperature.
Next, run the script from menu Control then Macro. The Macro will display a number of dialogs so you
can configure your data collection. The following are the displayed or collected: credit (not shown),
sensor address, total data points, delays between data points, time zone.
56
Figure. Dialogs in the data logger script.
Once the Macro is running, you will see data appearing in the terminal window:
57
Figure. Tera Term window while the data logger script is running.
You may pause or end the script at any time but I recommend doing so while the script is doing delay
between data points, indicated by “:pause” on the control box.
58
Appendix VI. Updating Adapter Firmware (Windows)
The new firmware update method involves running a python code, just like logging data or configuring
sensors. Since the python code runs on WIN/LIUNX/RPI, just like the logging and configuration python code,
it has become the preferred method. The purpose of this appendix is to maintain support of another
method that I often use on a WIN PC.
The current version of firmware is 1.2. You may update the firmware of the adapter when new firmware
becomes available. If your simple adapter is already version 1.2, you don't need any update. Analog
adapter has firmware version 1.3 and GPS adapter had firmware version 1.4, both of which are up to date.
Follow these steps to update your firmware:
1. Make sure your adapter is not connected to any sensors before proceeding.
2. Execute XLoader.exe and select “Uno”. Select the Com port with the highest number. Select
115200 Baud rate. All of the above should be automatic once you select the adapter.
3. Select the firmware file and press upload. Wait until upload complete.
4. Do a quick test by sensing SDI-12 address Zee (z).
XLoader: http://russemotto.com/xloader/
59