SDi-12 + GPS USB adapter test

I was able to perform some tests on the new SDI-12 + GPS USB adapter. I don’t have the GPS module but do have an arduino shield that features the same GolbalTol GPS module so I used some jumper wires to connect the GPS to the adapter. I did tests last night and overnight. Things are looking good. Here are some results:


To get longitude and latitude, you will issue “zM!”. The return values are z(long)(lat)\r\n. The longitude and latitude are both in standard NMEA format of 100*(degree.minute). For instance, a longitude of -9412.3411 means -(94 degrees 12.3411 minutes).

To get day, month, and year, you will issue “zM1!”. The return value is again in standard NMEA format of +DDMMYY. For example, a date of +190317 means the 19th of March, 2017.

To get hour, minute, and second, you will issue “zM2!”. The return value is also in standard NMEA format of +hhmmss. For example, a time of +123507 means 12:35:07 in 24hr style so it is 12:35:07 PM for those that use 12hr style.

Sample commands (in red) and returns (in green):

Single-sensor measurement:


Concurrent measurement:


SDI-12 + GPS module

After some development, I am glad to show a prototype of an SDI-12 + GPS USB module. This module incorporates the following features:

  1. USB connection
  2. SDI-12 translator with 4 SDI-12 connections (on a single SDI-12 bus)
  3. Header for a GPS module
  4. External power connection for sensors that need more than 5V from USB
  5. External power/5V USB selection jumper
  6. You can also use other serial devices or sensors such as Maxbotix serial sonic ranger, with some modification to the firmware
  7. Both SDI-12 senors and GPS are addressed like SDI-12 sensors, for easy integration of GPS signal into your existing SDI-12 logging scripts

Here is a picture:

I ran out of GPS modules. New ones are on the way. Once I get them, I’ll solder one on an adapter and do a demo video.

Phi-panel circuit board update

Recent comments from customers interested in phi-panels have convinced me that going from the original buttons with black plungers to low-profile metal buttons was a bad idea. On my end, the low-profile buttons on the front side of the board required me to reflow both sides of the boards, something that takes a lot of time and extra effort.

So I have made a recent priority update to the phi-panels, both 20X4 and 16X2, to use the original buttons with black plungers again. I’ll be building these boards soon and post some photos.

From now on, all kits will have pre-built components on the back side. All you need to solder are:

  • Buttons
  • LEDs and their resistors
  • Connector for serial port
  • LCD
  • Buzzer

If you buy assembled version, as always, everything is assembled and ready to go.

Here is the back side of the kit board, with key components already reflow-soldered on:

Here is front side of the kit board, just a blank board:


Here is assembled unit, same as before:

Here is assembled unit’s back side:


There are many types of I2C character LCDs on the hobby electronics market. To design my new open source data loggers and Phi-3 Arduino shield, I decided to move away from the bare parallel HD44780 character LCDs and go with character LCDs and I2C backpacks (aka I2C LCDs). I found out a few popular designs and thought that I would summarize them for your convenience.

Most I2C LCDs are based on the following two ICs, all of which are I2C I/O (port) expanders:

  • PCF8574 or PCF8574A
  • MCP23008


Both ICs have 8 I/O pins. MCP23008 is more versatile but that is irrelevant to simple applications in LCDs.

Adafruit designed an I2C LCD backpack and Arduino LCD shields based on MCP23008. There are compatible devices sold on ebay. I can’t tell without seeing the sample code to decide whether an ebay seller is actually selling a compatible product. But if you do want to get one on ebay, make sure you find their library code and confirm that the library contains Adafruit’s names. Libraries you find from ebay sellers are likely out of date though. One good thing is that the compatible ones are very likely using the same pin assignments as Adafruit’s so it’s easy to get it to work once you get the library installed.

FM (Francisco Malpartida) designed an I2C LCD backpack based on PCF8574. There are lots of compatible devices sold on ebay and they don’t have the same pin assignments! This creates issues when you are making purchases thinking that they have certain pin assignments. The pin assignments refer to which PCF8574 pin is connected to which HD44780 display pin. Also the I2C addresses are all different. I don’t mean one might have an address of 0x3F and another might have 0x3E. What I mean is that one might have 0x3F and another one may be 0x20. There is no way to set one display that has address 0x20 to address 0x3F! PCF8574 has address space of 0x20 to 0x27. PCF8574A has address space of 0x38-0x3F. Most common addresses I’ve seen are 0x20, 0x27, and 0x3F, with the latter two sharing pin assignments that are different from the ones with 0x20 address. Most of these displays allow you to cut traces or solder pads to change addresses. Why would you if you don’t have multiple LCDs?


Adafruit has its own library Adafruit_LiquidCrystal. This library is decent. It can take different pin assignments as parameters. On the other hand, it is a different library than Arduino’s included LiquidCrystal library. So code you wrote for LiquidCrystal library may need some change when you switch to an Adafruit compatible I2C LCD.

FM wrote a library New LiquidCrystal. This library is pretty good. You can use a number of different LCDs including parallel HD44780 LCDs, I2C LCDs using PCF8574, LCDs using shift registers etc. A nice feature is that there is a base class LCD so regardless what actual type of LCD you are using, as long as it’s supported by this library, it works the same way on the software level as another supported LCD.

Since not all PCF8574/74A I2C lcds have the same pin assignment, or even back light polarity, using the correct definition will be crucial. I found the following three definitions. Each seems to work with the particular I2C address, although there is no relation between I2C address and how the pins are assigned (by circuit designer):

The first two work on backpacks that look like this:

Notice that only the address is different. Pin assignments and back light polarity are all the same.

LiquidCrystal_I2C lcd(0x3F, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Blue potentiometer with back light jumper.

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Blue potentiometer with back light jumper.

The last definition works on backpacks that look like this:

Notice that pins are very different and back light polarity is negative.

LiquidCrystal_I2C lcd(0x20, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // Tiny mental potentiometer no back light jumper.


In case you can’t determine the address or pin out, say none of the above definitions work, but you’re sure the IC is PCF8574/74A, you should first scan the I2C bus for the address, and then use your meter to map out the pin assignments, and then use your definition. The lcd constructor has the following parameters: lcd(add, En, Rw, Rs, d4, d5, d6, d7, Bl, Pol).

Here is the I2C scanner I use by Tod E. Kurt:


Open source data logger videos

Open source data logger videos:

Quick demo:

Features introduction 1,2,3

Assembling the logger


Phi-3 shield videos

Here is a video of me navigating through the alarm clock program’s menu:

Here is a video of me explaining the components of the shield:

Here is a video of me explaining the different kits you can buy:

OK one more assembling modules on the shield:

Teaser photo

What can this new board do?


Guesses? Comments? Answer revealed after US Thanksgiving holiday (2016-11-24)!

(There is nothing on the back side)

Read analog sensors on SDI-12 USB + Analog adapter

Reading analog sensors are easy. The adapter has SDI-12 address of ‘z’, lower case. So reading the analog sensor just involves querying the SDI-12 address ‘z’. There are two sensing modes: single-ended, and differential. If you have mixed single-ended and  differential channels, read single-ended, then differential. Discard channels you don’t need. It won’t hurt the sensors or the adapter if you wire them in differential mode but read in single-ended mode. The reverse is also true.

The sensing commands are ‘zM!’ for single-ended readings, and ‘zM1!’ for differential readings.

In both modes, you use ‘zD01!’ zee-Dee-zero-!, to get data. Essentially, the adapter itself is an SDI-12 sensor that reports 2 or 4 values, depending on sensing mode. This makes it very easy to integrate analog sensors into your existing data logger that is based on the original SDI-12 USB adapter. It is still advantageous to keep the original SDI-12 USB adapter so it can split SDI-12 sensors with the SDI-12 + Analog adapter. In case one SDI-12 sensor gets broken and interferes with the rest of the sensors on that adapter, the SDI-12 sensors on the other adapter will be unaffected.

To make this complete, the SDI-12 USB + Analog adapter also responds to the following commands:


Response: ‘z\r\n’ This means that the adapter is responding to queries.

Command: ‘z!’

Response: ‘z13Liudr   SDITRD130\r\n’ This indicates that the firmware is in version 1.3.0.

Command: ‘zM!’

Response: ‘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.

Command: ‘zM1!’

Response: ‘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.

C0mmand: ‘zD0!’

Response: ‘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.


Update on the SDI-12 + Analog USB adapter


Here is an update:

In case you wonder what all those green screw terminal blocks are doing, here is a graphical explanation:

Both the SDI-12 USB and SDI-12 + Analog USB are explained in this illustration.

To maintain the same compact size, I printed all the pin information on the bottom of the board again. So if you don’t know what a certain pin on a block does, just flip it around and you’ll see it. The jumper information is all on top side.

The SDI-12 + Analog USB adapter comes with a jumper to select either internal 5V or external voltage at the Ext. Power screw terminal block. You may connect a small 9V battery to the Ext. Power screw terminal block. You can also connect your  12V battery that powers your logger to this pin. The external power is only sent to the SDI-12 sensors. It’s not powering the adapter or sent to the analog inputs’ “+” connections. Those “++ connections are always from the 5V USB power. There are 3 pins on the terminal block and the center pin is not connected to anything. It makes it easier to separate the + and – of the external power and I don’t have to source 2-pole blocks besides 3-pole blocks.

All four SDI-12 blocks have “+ S -“. The “+” is either USB 5V or external power depending on the power jumper. “S” is SDI-12 signal. “-” is ground. All grounds should be connected together. These four blocks are all connected. They are not four separate buses. There is no way to transparently bridge one USB serial port to more than one SDI-12 bus. If you wish separate SDI-12 bus for each sensor, which is unnecessary, get a separate adapter for a separate SDI-12 bus. This need for separate SDI-12 bus may come from some suspicion that if a single SDI-12 sensor breaks, it may take the whole bus down with it. I have not been so unfortunate and broken SDI-12 sensors I have had didn’t affect good ones. In any case, a broken sensor needs replacement. Unless you deploy redundant sensors one set on each SDI-12 bus, you are OK with a single adapter that bridges a single SDI-12 bus for all sensors.

The four analog channels are as accurate as 0.02mV when the signal is small, below 0.256V. The adapter automatically uses the best scale to determine 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 an 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. 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 starts with the largest scale to protect the converter and reads the signal. It then calculates the smallest scale that will fit the signal within 10%-90% of the 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.

The meaning of single-ended channel is that each one of the four channels is read against the common ground. This is less accurate for small signals over long wires. If you have a pyronometer or some other small voltage signal sensor, you may want to use two channels in differential mode. In this mode, the “+” wire is connected to say channel 0, and the “-” wire is connected to channel 1. The difference between these two are read and the difference may either be positive or negative. Range of the difference between these wires can be +-6.144, … +-0.256Vetc.

(to be continued)


SDI-12 USB + Analog prototype

So finally the boards and parts are here and I built the first batch of 3 boards (purple as in Here is a photo of one of them with my hand as size reference:


This board is twice the size of the original SDI-12 USB adapter and features the following additional features:

  1. 4 SDI-12 screw terminal blocks. The original adapter can handle multiple SDI-12 sensors if you wire them all together to the single SDI-12 block. On the other hand, I can make this easier by providing more connectors. 4 connections don’t mean limit of SDI-12 sensors to 4. You can wire any number of sensors to the same connection. More connections just mean more convenience when building your logger or swapping sensors in the field.
  2. External power supply block. With the original adapter, SDI-12 sensors are powered by 5V from USB. If it is not enough, you need another power source and some additional wiring. With the new version, just wire external power to this connection and select the SDI-12 power jumper to Ext., less wiring.
  3. Analog channels: Many users asked about using analog sensors that are NOT SDI-12 sensors. That requires additional hardware and distracts you from focusing on making your logger. Enter 4 analog channels! Each channel is capable of 16-bit analog to digital conversion and can have up to 16X gain. The smallest voltage you can read is down to 8 micro volts! You are welcome, pyranometers! You can use them as 4 single-ended channels, for PT1000 or other resistive temperature sensors or as 2 differential channels, best suited for pyranometers.
  4. Resistance sensors: resistance measurements are available on every analog channel. 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 or anything with high resistance. If your sensor generates a voltage, such as pyranometer, you can disconnect the jumper to disable this pull-up resistor. Each channel is separately configurable and auto-scales for best precision.
  5. Analog channels are sensed the SAME way you would sensor an SDI-12 sensor. The address is ‘z’ (lower case). Just in case you wonder, there is also a differential mode to further increase precision of small signals if you pair channels 0 and 1 as a differential channel, or 2 and 3 as another differential channel. 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, discard values from channels 0 and 1. Then sense as differential, discard value from 2-3 differential.
  6. Every key component, such as the analog-to-digital converter IC, the ATMEGA328 processor, the FT232RL USB chip, crystal oscillator, fuse, and precision resistors, comes from reputable vendors such as digikey, mouser, or newark. Every adapter is assembled by myself and tested with an actual SDI-12 sensor (also an analog or resistive sensor). I don’t know how else to ensure excellent quality! There is no guarantee coming with ebay purchases!

I expect this product to be available in a few weeks after I conclude my testing phase. My estimate retail price is $89. I will release data logger code that can log both SDI-12 sensor and the analog channels when this is offered for sale.

%d bloggers like this: