System for Calibrating Dogbone RFID Moisture Sensors using Decagon 5TM Conductivity Sensor and I2C Communication

Author: Brett Stoddard

Hello  Everyone! 

This last week I’ve been working on getting a system to log data that I will use to calibrate the Smartrac Dogbone RFID moisture sensing tags in soil

Abstract and Objectives

This blog post describes a system to log data that I will use to calibrate the Smartrac Dogbone RFID moisture sensing tags in soil using a Decagon 5TM moisture sensor. The goal of this system is to log both 5TM’s electric permittivity readings (ε) alongside Dogbone’s moisture sensor levels over a long period of time to make a relationship and eventually properly calibrate the Dogbone tags to the current industry standard, dielectric permittivity. 

Using a 2GB SD card, this system will be able to record 82 million data points, more than enough for our system (each data point takes up around 26 bytes and 2*230/(26) = 82*106 ). The period that the measurements are taken at can be changed easily, but is currently set at 10 minutes which gives a solid resolution but is still small enough to analyze easily. Theoretically, measurements could be taken with a minimum period of 5 seconds. The logged data points will be saved as a CSV file because those can be read by Excel which will make analyzing data fairly trivial. 




After encountering a few problems, the system that I settled on was two Arduinos that would communicate over I2C. I was forced to do this because the “SDI Library” that is needed to communicate with the 5TM soil sensor I was using is incompatible with the “SoftwareSerial” that was critical for debugging and testing the code.

I2C communication was originally developed for and is usually used for multiple chips on the same embedded electronic system to communicate over the same bus. It’s useful for when tasks need to be split between multiple Arduinos. I2C is implemented in Arduino using the Wire library. For this situation, the slave Arduino was the one reading data from the TM5 sensor. The nice thing about I2C is that it is relatively trivial to add additional sensors to any sensors to a setup in case we want to make multiple readings at the same time. The code for implementing this setup was written by following this tutorial

One Arduino was set as a slave and read the data from the 5TM sensor. I followed Chet’s Decagon 5TM sensor guide to set this up. The master Arduino had the GPS logger, and RFID reader shields on it to record the values. The RFID reader shield uses pins 2 and 3; the GPS SD logger pins 13, SCL, and SCA; and I2C pins GND, A4 and A5 on the master Arduino. The 5TM sensor used pins 6, 5V, and GND; and I2C pins GND, A4 and A5 on the slave Arduino. The hardware diagram shown below illustrates this.


The code for this system will be posted in the examples folder of my RFID Github library under the title “Calibrator example”.


Last night, the first data set was collected using this setup over the course of 16 hours. Below is the graph (made in Excel) that shows the Dogbone moisture values (units not named) vs the 5TM conductivity measurements (dielectric permittivity, ε). There was a recorded R^2 value of .75 which means there was a moderately high correlation between the two. As one can see from the graph, over time the 5TM’s electron permittivity decreased slowly as the soil slowly dried out. Longer-term tests where the soil has time to go from saturated to dry will be key for properly calibrating the Dogbone tags to the current industry standard, dielectric permittivity.

The x-axis has units of number of 10 minute intervals

The x-axis has units of number of 10 minute intervals

Make it Slide!


After having the first prototype of the hyperspectral camera rotating mount, it was time to start the rail version. We have aluminum extrusion in the lab, but I still need to design the carriage that will carry the camera. One important factor in this design is that it has to be modular, meaning that we have to be able to make it as small or big as needed. Having all this in mind, I set off in search for solutions that would allow me to put together this modular rail.


To find the best material that will balance weight, modularity, and precision in order to create the rail version of this product. 

Materials and Methods:

Internet searches were the main method of investigation.


  • Aluminum Extrusion
  • Rails
  • Rollers 
  • Linear Systems
  • Linear guides


After surfing the web, I concluded on 4 potential paths to take in order to commence the build of the rail version of the hyperspectral camera rotating mechanism. The options are: linear guides,  Buy Rollers or 3D print rollers.

In terms of guides, the options were good but expensive. I found T, W, and V style linear guides. I easily found T and W, but I didn’t find V until the end of my search. This was due to the fact that it’s not common among the mass-produced material. The problem with the 40×40 aluminum extrusion that we have in the lab is that there exists almost nothing in terms of rollers, and the ones that do exist are expensive.  I did a couple of test prints for the rollers, but I was not satisfied with the quality, therefore this was not an option. 

As of right now, I think that going with the V style guides is our best option. This is because they are the most economical of all and they are specifically manufactured for linear motion systems. The price is about $6/m, compared to the others this is cheap! The other materials were coming in at $825.82/m, $301.72/m, and $65.55/m; this is for the w and t style rails. 

The website that carries the V style guides also has the necessary components to mount the rails onto the aluminum extrusion and has the plate for the carriage. This way we can get everything from the same vendor and at a  reasonable price. 


3D printed rollers3D printed rollers

3D printed rollers


W Style guides

T Guides 1

T Guides 2

V Guides

Working with the “Internet” for the Internet of Agriculture


WiFi Data Logging

For the last few weeks I have been working on using an Arduino Uno and a couple different ESP8266 WiFi modules for the purpose of  logging sensor data in real time to a Google sheet and develop a network Gateway for all of our sensor devices.


The  ESP8266  WiFi Module. The IOA's internet! The  ESP8266  WiFi Module. The IOA's internet! 

The ESP8266 WiFi Module. The IOA’s internet! 

Hazzah!  Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. Hazzah!  Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. 

Hazzah! Breakout board variation of the ESP8266 Chip which eliminates the need for wire wraps, external voltage regulation,  and has expanded communication capabilities. 

The ESP8266 WiFi Module is a self contained SOC with integrated TCP/IP protocol stack that can give any microcontroller access to a WiFi network. The ESP8266 is capable of either hosting an application or offloading all Wi-Fi networking functions from another application processor. This function is most important for this particular project and will be used as gateway to log data straight to the internet.


Working around Secure Connections

Google Forms requires a secured connection (SSL) but the Arduino (Or autonomous huzzah board) doesn’t have enough power/memory to create SSL connections. We will use a third party Application program interface, PushingBox to work around this. 

PushingBox API is really simple in concept and in practice.  To launch a “scenario” of notifications you can send an HTTP request . The only argument you should attach is the DeviceID (details on how to find this found below in a link) . This is the unique key that identify the scenario you want to launch. The DeviceID can be found on the Scenario Page.You can also put more arguments to define customs notifications text using your own variables which is what we will do to allow sensor data to be uploaded to a google sheet.

This allows PushingBox to confirm the secure connection needed for google to begin passing on data uploaded from the Arduino. All this in real time. A more indepth explanation of this process can be found in a tutorial found here

Setting up the Google sheet

Another important aspect of this project was to prepare the google spreadsheet for the data it is about to receive. This is done in a google G-script (similar to java) and the instructions on how to do this can be found here.  This step is a bit technical and requires some patience while working through.

Data, Links , Projects, and References

Wiring and other example projects the OPEnS lab has worked on  can be found here.

Original ESP8266 setup running through an Ardiuno Microcontroller.  Original ESP8266 setup running through an Ardiuno Microcontroller.  

Original ESP8266 setup running through an Ardiuno Microcontroller.  

***Important note***

If you are using the older ESP8266 chip it is important to have an external voltage regulator. (This problem was resolved in the Hazzah board which contains an internal voltage regulator)

On Arduino Uno, / Mega the 3.3V regulated output is able to supply 150 mA max. The ESP8266 draws up to 500 mA and could damage the Arduino.
Add a 3.3V Voltage regulator such as LM1117-3.3 to power the ESP.

A helpful diagram to reference can be found here. 

Hazzah Board being flashed using a FTDI cable Hazzah Board being flashed using a FTDI cable 

Hazzah Board being flashed using a FTDI cable 


Note: On the Huzzah Breakout Board, the module must be put into bootloader mode described below before you can upload a sketch from the Arduino integrated development environment (IDE). 

  1. Hold down the GPIO0 button, the red LED will be lit
  2. While holding down GPIO0, click the RESET button
  3. Release RESET, then release GPIO0
  4. When you release the RESET button, the red LED will be lit dimly, this means its ready to bootloader

Then in the upload the sketch found here with the appropriate libraries found here.

Specifics on how the pinout and wiring differs for the Huzzah breakout board can be found on the adafruit site here

Conclusions and Results

After much frustration and hours of tweaking code for the ESP modules and G-Script,  I was successfully able to hardline pseudo data from the microcontroller, through the ESP module to Google sheets via the PushingBox API. This ability really opens up an expanded capability for our sensors that are in developed and will prove to be an integral part of the OPEnS lab remote sensing. 

Pseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google SheetsPseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google Sheets

Pseudo data from the Arduino was successfully pushed the the Gateway generated by The PushingBox API to Google Sheets

Extension of Work

The next step in this project is going to be integrating this data logging interface with data transmitted from the LaRo Radio module. This project will continue in the coming weeks in collaboration with Marissa Kwon.

Work on integrating the LoRa radio receiver and the Huzzah ESP8266. Work on integrating the LoRa radio receiver and the Huzzah ESP8266. 

Work on integrating the LoRa radio receiver and the Huzzah ESP8266. 

– Tom DeBell, Beginning Researcher Support Program Researcher

A Simpler Pump Test: No SD


This is a follow-up to the previous post, “A Simple Pump Test”. There were several complications with storing the pump data on an SD so this post will describe a new method that stores data on the Arduino’s own memory.


In the field, the pumps will be run for 2.5 minutes per sample for 24 samples, resulting in one hour of total runtime. As described in the previous post, the pumps used in the sampler are poorly documented and information on their lifespan and behavior under long periods of use is needed. 

The SD breakout board used in the previous test was a 3.3v board and was not compatible with 5v arduino logic without some voltage conversion in between. While it worked some of the time, it resulted in corrupt data after a few points. Rather than using a 5v board or something to step down the signal voltage, the Arduino’s own memory can be used to store a small amount of data.

Arduinos have a small amount of available memory that doesn’t get reset between power cycles, known as EEPROM. A single byte can be stored per register, and an Arduino Uno has 512 available registers.

Setup and Method

A 12v peristaltic dosing pump is wired such that the positive end is connected to a 12v source and the negative end is split between a .85 Ohm resistor and the Arduino’s A0 analog input pin. The Arduino’s GND is connected to GND on the power source and VIN is connected to 12v. The other end of the .85 Ohm resistor is connected to GND.

A jumper wire connects GND to the Arduino’s digital pin 3, which is initialized to INPUT_PULLUP.

When powered on, the Arduino continuously checks that pin 3 is LOW. If it is, the voltage across the .85 ohm resistor is effectively measured via an analog read of pin A0 and the value is stored in a register of EEPROM. The register address is incremented and the loop resets.

If pin 3 is HIGH, data collection is turned off and the Arduino checks for a serial input of “p”. If the user inputs in the serial monitor “p” then it prints all the data from the registers separated by spaces. This data should be copied and pasted into a text file, but can be reprinted as long as pin 3 is HIGH.


// A simple voltage logger that is 

#include <EEPROM.h>

const int sensorPin = A0;
const int startPin = 3;

long sTime = 0; // last sample time
int maxPoints = 240; // maximum number of points to store
int sDelay = 30000; // delay between samples
int addr = 0;

void storeData();

void setup() {
  pinMode(startPin,INPUT_PULLUP); // if grounded, enable recording


void loop() {
  //If datalogging is enabled, store data in a new address
    if(millis() – sTime > sDelay){
      Serial.println(“reading data point ” + String(addr));
    Serial.println(“Enter ‘p’ to print out data”);
      int input = 0;
      if(Serial.available() > 0){
        input =;
      if (input == 112){
        for(int i = 0; i < maxPoints && i < EEPROM.length(); i++){
          Serial.print(” “);

 * store the sensorPin voltage and increment the address. If the address has
 * reached the limit of number of the points or hit the last address of
 * the EEPROM, don’t store data and return from the function.
void storeData(){
  if(addr == EEPROM.length() || addr == maxPoints){
    Serial.println(“Max addr reached”);
    sTime = millis();
  EEPROM.write(addr, analogRead(sensorPin)/4);
  sTime = millis();

Python Code

# This code will take in data via a text file that was collected using
# the pumptest arduino code. Data points should be separated by spaces.

import matplotlib.pyplot as plt

data = []
splitter = []
voltage = []
current = []
average = []
avg = 0

with open(‘pumplog_2_p1t2.txt’) as f: #file name for test data to be graphed
    reader = f.readlines() #read in the data

for line in reader: #split up the data. Could be conbined with converting to int but is more readable this way.

for point in splitter[0]:
    data.append(int(point) * 4) # turn each point of data into an int. Data values were divided by 4
                                # to fit into EEPROM.

for point in data: # calculate the voltage at each point.
    voltage.append(point * 5 / 1024)

for point in voltage: # calculate the current at each point.
    current.append(point / .85)

for point in current: # calculate the average current.
    avg += point
avg = avg / len(data)

for point in data: # turn average into a plottable list

plt.title(“Pump 1 Test 2”) #rename based on test
plt.xlabel(“time (minutes)”)
plt.ylabel(“current (A)”)


Initial Results


Three tests have been run so far. They were graphed using Python 3 and matplotlib.pyplot. Another test is currently being run on the second pump. The data between the two pumps will be compared using a two-sample T test to check if the two pumps perform the same. The same method will be used for the pumps under condition of pumping water.

The initial three tests might suggest that there is a long term decrease in the pumps’ current draw. Future tests should be conducted for a full day and a linear regression analysis should be performed. More importantly, such inconsistency in the current draw suggests the flow rate though these pumps is not constant. A test should be conducted to observe the trend and variance in the mass flow rate of water through the pump via a logging scale. A better conclusion can be made once the first round of testing is finished and statistically analyzed.


Low and slow


Why go slow? We need to take pictures at very slow speeds and at a continuous rate using a hyperspectral camera! With the old electronics board, this was not possible, but the new one works amazing!


Rotate the stepper motor at very slow and steady rates to allow the camera to take pictures. 

Materials and Methods: 

Using the Sparkfun’s EasyDriver Stepper Motor Driver, we are going to drive the stepper motors for this project. We were previously using Adafruit’s TB6612 Stepper Motor Driver but it was not giving us the performance that wee need.  Here is the wired up motor driver:


Using Sparkfun’s board we are able to achieve the results that we wanted. We are going use the new board instead. It works great at very low speeds and is very steady.