Arduino Soil Probe Using DS18B20 and DIY Moisture Hardware

7,059

103

11

About: Ugly pirate roaming the seas in search of Treasure.

As a fanatical gardener or a professional farmer, knowing the environmental conditions of our soil is invaluable. Obviously, we can't measure the number of worms or pieces of organic humus, but we can measure temperature and moisture content really easily.

This is not a difficult project and what you end up with is a very swanky looking bit of kit that will impress most people until you put it in the soil and it gets completely covered in dirty, sticky mud!

Step 1: Parts

  1. Resin that is used for pasting onto glass fibre
  2. Resin hardener.
  3. 6mm 316 grade stainless steel rod.
  4. DS18B20 temperature probe with water proof cable attached.
  5. 4.7 K Ohm resistor (yellow, purple, red, gold)
  6. 10 K Ohm resistor (brown, black, orange, gold)
  7. 35 mm OD stainless steel tube
  8. 3mm bolts and nuts x 2
  9. 3mm wire terminals x 2
  10. Twin core cable
  11. Arduino uno

Step 2: Fabrication

I have been developing these devices for a year or so now and the use of liquid resin is incredibly effective and produces a very professional looking results.

Following the photos above:

  1. Use a 32mm hole saw to cut out a steel and a plywood disc to hold the sensor probes in place during fabrication.
  2. Flatten and drill the ends of the probes to 3mm for the electrical connections.
  3. Attach the cables.
  4. Drill three holes in the plywood disc for the two long probes on the outside and the short DS18B20 probe in the middle.

Next is a three stage process for applying the resin:

  1. Insert the plywood about 1/4 way up the body of the main tube and pour in a small amount of resin and hardener, making sure that there is plenty of space between all the electrical contacts.
  2. After the resin has set hard, turn the assembly upside down and fill the tube with resin around the three probes.
  3. After this batch of resin has set, turn it back upright and fill the top of the tube with resin.

Now test the device for short circuits with a multimeter.

Step 3: Test and Calibrate the Probe Using Arduino

The DS18B20 is easy to set up, but the wiring is counter intuitive and there are two different ways to wire it which can create more confusion. For the probe with a stainless tip and leads attached, yellow = signal and black and red are connected together and go to ground (GND).

Download and install the Dallas Temperature library (http://www.pjrc.com/teensy/arduino_libraries/OneWire.zip or search the interweb for latest version). Then use the oneWireSearch program to find your probe's address.

Copy and paste the address into the main code in the next step.

Simple?

Run the main code and immerse the soil probe in very, very wet soil - it should be a thick goo type liquid. The soil should be the same as the soil you want to monitor and it will have various salts in it that conduct electricity when wet. When the soil is dry, the conductivity dramatically reduces to almost zero.

If you look at my code, I have used a value of 0.102 to multiple against the analogue pin reading, but every soil type will be different. The probe should read 'zero' in the air or in dry soil. Extra sensitivity can be created by deciding at what point soil is actually dry, so we could just measure to that point rather than to 'absolutely bone dry', however, I have not done this in this example, just to keep it simple.

Step 4: Arduino Uno Code for Soil Probe

The code is mostly fairly straight forward but it's important to pulse the moisture probe rather than supplying a constant voltage. For one, this saves energy, but most importantly, it helps prevent the electrodes from corroding too quickly. In this example, power for the device is pulsed from pin 9. (Updated September 2018)

#include <OneWire.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example

// http://www.pjrc.com/teensy/td_libs_OneWire.html  http://www.pjrc.com/teensy/td_libs_OneWire.html  http://www.pjrc.com/teensy/td_libs_OneWire.html


// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library http://www.pjrc.com/teensy/td_libs_OneWire.html http://www.pjrc.com/teensy/td_libs_OneWire.html

OneWire  ds(10);  // on pin 10 (a 4.7K resistor is necessary)
int sensorPin = A0;    
int sensorValue = 0;  // variable to store the value coming from the moisture sensor
unsigned long moistureValue = 0;
float tempsoil;
int moisturePowerPin = 9; 
void setup(void) {
 pinMode(moisturePowerPin, OUTPUT);
 Serial.begin(9600);
}
void loop(void) {
  byte i;
  byte present = 0;
  byte type_s;
  byte data[12];
  byte addr[8];
  float celsius, fahrenheit;
  
  if ( !ds.search(addr)) {
    Serial.println("No more addresses.");
    Serial.println();
    ds.reset_search();
    delay(250);
    return;
  }
  
  Serial.print("ROM =");
  for( i = 0; i < 8; i++) {
    Serial.write(' ');
    Serial.print(addr[i], HEX);
  }
  if (OneWire::crc8(addr, 7) != addr[7]) {
      Serial.println("CRC is not valid!");
      return;
  }
  Serial.println();
 
  // the first ROM byte indicates which chip
  switch (addr[0]) {
    case 0x10:
      Serial.println("  Chip = DS18S20");  // or old DS1820
      type_s = 1;
      break;
    case 0x28:
      Serial.println("  Chip = DS18B20");
      type_s = 0;
      break;
    case 0x22:
      Serial.println("  Chip = DS1822");
      type_s = 0;
      break;
    default:
      Serial.println("Device is not a DS18x20 family device.");
      return;
  } 
  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);        // start conversion, with parasite power on at the end
  
  delay(1000);     // maybe 750ms is enough, maybe not
  // we might do a ds.depower() here, but the reset will take care of it.
  
  present = ds.reset();
  ds.select(addr);    
  ds.write(0xBE);         // Read Scratchpad
  Serial.print("  Data = ");
  Serial.print(present, HEX);
  Serial.print(" ");
  for ( i = 0; i < 9; i++) {           // we need 9 bytes
    data[i] = ds.read();
    Serial.print(data[i], HEX);
    Serial.print(" ");
  }
  Serial.print(" CRC=");
  Serial.print(OneWire::crc8(data, 8), HEX);
  Serial.println();
  // Convert the data to actual temperature
  // because the result is a 16 bit signed integer, it should
  // be stored to an "int16_t" type, which is always 16 bits
  // even when compiled on a 32 bit processor.
  int16_t raw = (data[1] << 8) | data[0];
  if (type_s) {
    raw = raw << 3; // 9 bit resolution default
    if (data[7] == 0x10) {
      // "count remain" gives full 12 bit resolution
      raw = (raw & 0xFFF0) + 12 - data[6];
    }
  } else {
    byte cfg = (data[4] & 0x60);
    // at lower res, the low bits are undefined, so let's zero them
    if (cfg == 0x00) raw = raw & ~7;  // 9 bit resolution, 93.75 ms
    else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
    else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
    //// default is 12 bit resolution, 750 ms conversion time
  }
  celsius = (float)raw / 16.0;
  fahrenheit = celsius * 1.8 + 32.0;
  Serial.print("  Temperature = ");
  Serial.print(celsius);
  Serial.println(" Celsius, ");
  Serial.println("");
  Serial.print("Soil temperature:   ");Serial.print(celsius);Serial.println(" Celsius, ");
  digitalWrite(moisturePowerPin, HIGH);              // Powers up the moisture sensor for 0.1 seconds to prevent corrosion.
  sensorValue = analogRead(sensorPin)*0.102;         // The sensor is calibrated by multiplying by 0.102.
  delay (100);
  digitalWrite(moisturePowerPin, LOW);               // Powers down the moisture sensor
  Serial.print("Soil moisture:      "); Serial.print(sensorValue); Serial.println(" %");
  delay (10000);
}

Step 5: Final

The next thing to do would be to transmit the data to somewhere nice and warm and dry where we can sit leisurely drinking coffee and gaze in adoration at our work. I certainly don't want to be constantly having to walk over to the soil probe to look at a tiny LCD screen - I'm far too lazy for that!

http://www.goatindustries.co.uk/weather/

This soil probe is connected to a full blown GPRS weather station module which will be featured in a separate Instructable - just as soon as I retrieve the rain gauge data from a black hole in the Arduino's memory system!

Watch this space for more weather station Instructables including testing a proper professional anemometer and wind vane and maybe even a weather station development printed circuit board.

Share

    Recommendations

    • PCB Contest

      PCB Contest
    • Comfort Food Challenge

      Comfort Food Challenge
    • Epilog X Contest

      Epilog X Contest

    11 Discussions

    0
    None
    sahaby

    4 weeks ago on Step 5

    Hi
    I want just to make moist monitoring system
    Can I get a tutorial and code
    BTW I like your prope

    0
    None
    alfon1917

    2 years ago

    Have you tried removing the

    delay (100);

    line and moving the line

    digitalWrite(moisturePowerPin, LOW);

    directly after the analogRead line?

    Doing so should further diminish the power consumption / corrosion rate without affecting the measurements

    1 reply
    0
    None
    diy_blokeacolomitchi

    Reply 2 years ago

    My, my. You really did your research :-)

    I actually had not expected a drift.

    We'll get to the perfect sensor yet

    0
    None
    Tecwyn Twmffatacolomitchi

    Reply 2 years ago

    nOT REALLY LOOKED INTO IT MUCH, BUT I'm AWARE IT COULD BE A PROBLEM. Sorry - hit caps lock button - I'm not really after a super accurate results, but, just for fun, I'm going to go over to capacitance probes which will be designed and built in the dark months of winter. I guess they will be temp dependant too?

    0
    None
    acolomitchiTecwyn Twmffat

    Reply 2 years ago

    > I'm going to go over to capacitance probes which

    > will be designed and built in the dark months of winter.

    Here's mine: https://www.instructables.com/id/Automatic-Waterin...

    After reading it, just to wet your appetite before jumping into designing one, I'd be willing to send you one of my spare probes and a controller board - the rest of the components will be up to you (I don't want to take any responsibility for any eventual faulty parts I bought from chinese. Haven't has any problems until now, but one never knows). The only thing I want in return is an "I built it" comment.

    PM me with your postal address if you want to have a go.

    > I guess they will be temp dependant too?

    Unfortunately, yes, though less than what I gather about the resistive probes.

    See here: www.mdpi.com/1424-8220/12/7/9773/pdf

    I didn't compensate for temperature variation in my built, but they did the job for me.

    0
    None
    diy_bloke

    2 years ago

    I didnt see where the metal disk you made was used. At the top I presume, where the cables come out. but why 3 holes then?

    2 replies
    0
    None
    Tecwyn Twmffatdiy_bloke

    Reply 2 years ago

    Yes, sorry, this is a bit vague. There's two disks, one made in wood and the other in metal and they could easily both have been wood in hind sight. The metal one could indeed have just had 2 holes in it as it just supports the ends of the moisture probes during fabrication and is then removed. The wooden disk has 3 holes, two for the moisture probes and one for the temperature probe and gets permanently embedded in the resin.

    0
    None
    diy_blokeTecwyn Twmffat

    Reply 2 years ago

    yes, thanks, I sort of figured that. I was thinking maybe leave the metal one in place, attached to the resin, for a nice finish :-)

    0
    None
    diy_bloke

    2 years ago

    very professional look. Those bolts will last for quite a while especially when only doing intermittent measuring