Agricultural Field Crop Irrigation Monitor




Introduction: Agricultural Field Crop Irrigation Monitor

Another weather station... of sorts. This is more for water in the soil, garden etc. It beats walking around with a tensiometer any day. It is a fantastic tool and when you are chasing around frantically in the summer it cannot half save you some time. I have tried to build it with more industrial components so it should last, so for it does seem to.

This will:

  • Measure the capacitance and temp at the surface.
  • Measure the Temp and Humidity (wherever you stick the sensor, please not there).
  • Measure the soil resistance at depth and convert it to centibar.
  • Measure the temperature at depth.

Remote monitoring of field conditions is starting to become more prevalent with the IOT drive. I wanted something that I could used to analyse the data in whatever way I fancied even prompt triggers. I looked at a lot of the already available options and decided they were either wayyy too pricey and/or didn't have the flexibility I wanted.

So I set about trying to figure out how to. Fortunately I had a little experience with Particle and knew that this platform, with a bit of 'sweat', could deliver a very flexible tool. (They essentially work as a middle man giving you the flex either end).

Why have I put this guide together

I've created this guide to speed up and enlighten things for others, hope it helps. It took me ages to figure it out and I wouldn't have done it with the shared info from others so I feel it is only right to give back. If your in the ag sector this should show you the whole process from soil to graph.

Step 1: Parts Required

You don't need them all to get it working it'll just put out weird numbers for that measurement.

  • Built with a Particle Electron but should work with Boron if by GSM (sim card) or Photon/ Argon if it'll be close enough for WiFi.You will need to change the B0 & B2 pins to something else if not using an electron.
  • Battery, the Electron comes with one, the Photon will also need a battery shield or thing to connect/charge it.
  • Sensors, parts are removable or changeable depending on your requirement/motivation.
    • AM2320, I had one, but if buying I'd advise a pinned out(aka broken out) BME280. Pimoroni, Adafruit, Sparkfun are good places to look.
    • Chirp!, cracking little sensor, go for the rugged one the others don't last long outside...... Tindie Chirp This is a very reactive sensor and will tell you very quickly if things have changed unlike the irrometer which takes a bit of time.
    • Tipping bucket, I used an old one off a weather station I wasn't bothered about serious precision or shelling out. If you are there are plenty of options out there and you just need to adjust the resolution in the code.
    • Irrometer, great bit of kit for measuring soil water tension, centibars, the thing you want to know if you irrigate. Irrometer website
    • DS18B20 waterproofed and on a length of cable. Cheap, easily available and effective.
  • A waterproof box (that can take a beating from a sprayer boom if in the field). I used a screw lid Tupperware thing.
  • Maybe some sort of shroud for the temp sensor. Mines off an old weather station, I reckon you could get away with sticking it out the bottom of the box if not irrigating.
  • Some pipe to go on the irrometer to make it easy to find and insert. Yes this can cause slight inaccuracies because water will run down it... But hell it's easier than trudging around with a spade. I used a bit of conduit, electrical tape a heat gun.
  • Solar panel with a decent bit of go ideally @ 5/6V to go straight into the USB. Amazon- This is what I used, cheap and it works.
  • A few 4.7K Ohm resistors, USB cable and some diodes.
  • PCB strip board and headers. Could be done without or on a breadboard but it does make it easier.

Step 2: Hardware Hookup

This took me a bit of figuring out and a few prototypes. I originally made the board to fit in a box which I didn't use in the end hence the shape, you could probably do it simpler following the circuit diagram.

A big thank you to Mr Vinduino, genius with the irrometer! If I'd have wanted a more out the box solution he has it. The clever thing about his method is that it pulses the sensor one way then the other so you do not get the corrosion issues seen if you just run the circuit one way.

The chirp and AM2320 are I2C which makes life a whole lotta simpler. This is computer talk for the less informed, it means everything can be connected together on the same 4 wires. You could literally have 100's of things connected on 4 wires. Interestingly quite a few of the maker manufacturers have cottoned onto this and are doing their own easy plug versions of stuff. I put these on telephone connectors RJ11 because I was chopping and changing a lot and I've got loads of old leads kicking about, couldn't throw them away, far too useful for something. But they could be wired direct. Do not forget the resistors 10K ones would work it just needs something to pull it up.

I put the tipping bucket on a spare pin of the telephone connectors for the same reason but again could be wired direct. The same could be said for the DS18b20 but I couldn't be bothered to change it again. If you want to do this then just adjust the code accordingly e.g. change the pin number. The tipping bucket works on a reed switch when it's one way the circuit is disconnected and the other it's connected. The electron will sense the change, wakeup and add to it's rain record.

Step 3: Particle Code has set up a cloud and hardware system which greatly simplifies the job of getting the data up to the fluffy things. The hardware is also pretty robust and developer friendly hence my preference.

In order to use their equipment you need to get signed up and setup on their website. I'm not going into detail here it's safe to say there's plenty of documented info out there, they are really good at getting people going, no need to stare at the headlights. You also need to register your device, again there's guides.

Once your here you need to navigate to the IDE and plumb my code in. As I say it is messy at the moment, I have 'grand plans' to make it slightly more universal but they are plans. Creative steps are rarely tidy. Apologies.

The code is designed to measure the sensors, Publish to the cloud, turn everything off and then sleep for a half an hour(this is adjustable). It will also wakeup and register a tip of the rain bucket. It will reset the count at midnight.


  1. Use this link to Jerry my code (I don't blame you): F Particle electron field sensor
  2. Follow 4.+ below.


  1. Copy my code to the first page.
  2. Add the DS18B20 and Adafruit_Sensor library (bottom left side, libraries - search - click on - then click include in project and then click on the relevant one.
  3. Add the extra tabs and code as labelled in me picture.
  4. Flash to device (top left lightening bolt, I do it over the air, by USB is a ... ache) you may need to select the device (bottom left target - click the star next to the device so that it is yellow). Make sure the device is connected to the cloud (Cyan).
  5. The device should boot up flash green then Cyan, stay on for a
    while and then turn off, if you tip the rain bucket it should come back on again.
  6. In theory it is working!!! Well done.

Things to note

  • One of the big problems was getting the AM2320 to work, In the end I had to jimmy an edited part of arduino code onto another tab (you'll see) hence why I say use a BME280 they are far better documented. I have tried to include as much info as possible as I know how annoying it is when someone doesn't share everything and it fails again and again.
  • The Chirp library code had to be added onto a tab because currently there isn't a library in particle. VintageGeek has written a library specifically for the photon Vitage Geek Chirp and Photon
  • DS18B20 is currently commented out the chirp will do soil temp but the DS18B20 is better for depth.
// This #include statement was automatically added by the Particle IDE.<br>#include "I2CSoilMoistureSensor.h"
I2CSoilMoistureSensor i2CSoilMoistureSensor(0x20);
#include "Adafruit_Sensor.h"
#include "Adafruit_AM2320.h"
Adafruit_AM2320 am2320 = Adafruit_AM2320();
float tempC;
float humidity;

const int      MAXRETRY          = 4;
const uint32_t msSAMPLE_INTERVAL = 2500;
const uint32_t msMETRIC_PUBLISH  = 30000;
DS18B20  ds18b20(D5, true); //Sets Pin D5 for Temp Sensor and  // this is the only sensor on bus
double   soilC;
double   soilF;
float chirpTemp;
unsigned int chirpLight;
unsigned int chirpCap;
byte soilmoisture;
// A FuelGauge named 'fuel' for checking on the battery state
FuelGauge fuel;
float voltage;
float soc;
 int count24 = 0;
 float rainfall24 = 0;
// unsigned int minuteOld = 0;
// unsigned int currentMinute = 0; 
 unsigned long currentHour = 0;
// unsigned int lastHour = 24;
 unsigned long currentDay = 1; //I think long is needed for the comparitor
// unsigned int lastDay = 0;
// unsigned int reset_time = 0;
 unsigned int debounce_time = 0;
 boolean tipState = 0;

// For the soil moisture sensor Thankyou Mr Vinduino
#define NUM_READS 10    // Number of sensor reads for filtering
long buffer[NUM_READS];
int inde;
typedef struct {        // Structure to be used in percentage and resistance values matrix to be filtered (have to be in pairs)
int moisture;
long resistance;
} values;
const long knownResistor = 4700;  // Constant value of known resistor in Ohms
int supplyVoltage;                // Measured supply voltage
int sensorVoltage;                // Measured sensor voltage
values valueOf[NUM_READS];        // Calculated moisture percentages and resistances to be sorted and filtered
int i;                            // Simple index variable
unsigned long sensor1;
long read1;
long read2;
int cbar;
void setup() {
//    pinMode(D6, OUTPUT);  
//    pinMode(D7, OUTPUT);
//    digitalWrite(D6, HIGH);//Turn the DS18b20 temp
//    digitalWrite(D7, LOW); 
    pinMode(D2, OUTPUT);  // The I2C is powered by the D2,3 pins 
    pinMode(D3, OUTPUT);
    digitalWrite(D2, HIGH);
    digitalWrite(D3, LOW); //Turn I2C stuff
//    Serial.begin(9600);
//  while (!Serial) {delay(10); }// hang out until serial port opens
    tipState = digitalRead(D4);
  pinMode(B0, OUTPUT);   // Pins for reading the soil resistance 
  pinMode(B2, OUTPUT);   
  Serial.println(" Electron weather test");
//  Time.beginDST();
void loop() {
if ( != currentDay) { //Resets 24hr counters at 24hrs
        count24 = 0;   
        rainfall24 = 0; // inches (0.05 inch per tip)
        currentDay =;
        if (Time.isDST() == 1){  // if Day light saving time is in effect apply it to the time
        } else {
    currentHour = Time.hour();
    if (currentHour == 0 && lastHour == 23){ //Resets 24hr counters at 24hrs
        count24 = 0;
    lastHour = Time.hour(); */
    if ((tipState != digitalRead(D4))&&((millis() - debounce_time) >= 1000)){ //Adds to the rain counter at tip of gauge
        debounce_time = millis();
        tipState = digitalRead(D4);
        rainfall24 = ((count24)*0.05); // inches (0.05 inch per tip)
    Serial.print(" Time");
    digitalWrite(D2, HIGH);//Turn off I2C stuff
    digitalWrite(D3, LOW);
//    digitalWrite(D6, HIGH);//Turn the DS18b20 temp
    chirpTemp = i2CSoilMoistureSensor.getTemperature(); //chirp temperature register
    chirpTemp = ((chirpTemp)/10);
    chirpCap = i2CSoilMoistureSensor.getCapacitance();
    soilmoisture = map(chirpCap, 300, 750, 0, 100); //max and min seeen in testing mapped to %
    if (soilmoisture > 100 || soilmoisture <= 0){
        soilmoisture = NAN;
//    chirpLight = i2CSoilMoistureSensor.getLight(true);//true initiates startMeasureLightand adds a 3 second pausebefore reading, false reads immediately
    Serial.print(" Raw Cap :"); Serial.print(chirpCap); 
    Serial.print(", %Moist :"); Serial.print(soilmoisture); 
    Serial.print(", CTemp :"); Serial.print(chirpTemp, DEC);
//    Serial.print(", CLight :"); Serial.print(chirpLight);
    tempC = am2320.readTemperature();
    humidity = am2320.readHumidity();
    Serial.print(", Temp: "); Serial.print(am2320.readTemperature());
    Serial.print(", Humidity: "); Serial.print(am2320.readHumidity());
 //   getTemp();
 //   Serial.print(", SoilC "); Serial.print(soilC);
    digitalWrite(D2, LOW);//Turn off I2C stuff
    digitalWrite(D3, LOW);
//    digitalWrite(D6, LOW);//Turn off the DS18b20 temp
    voltage = fuel.getVCell();
    soc = fuel.getSoC();
    Serial.print(", Battery: "); Serial.print(voltage); Serial.print(","); Serial.print(soc);
    read1 = average();
    read2= average();
    sensor1 = (read1 + read2)/2;
    cbar = ((sensor1-550)/137.5); //Simple equation to shown the relationship between resistance and CB
    if (cbar > 250 ){
        cbar = NAN;
    Serial.print (", resistance bias =" ); Serial.print (read1-read2);
    Serial.print (", sensor bias compensated value = "); Serial.print (sensor1);
    Serial.print (", Centibar = "); Serial.println (cbar);
        String SENSORS = String::format(
//        "\"soiltempC\":%.2f," 
//      soilC,
//    Serial.println(SENSORS);
//    delay(40 * 1000);// Delay 20sec
    Particle.publish("json", SENSORS, 60, PRIVATE);
    System.sleep(D4, CHANGE, 30*60); //Used to allow a wakeupon the bucket tip pin sleep for seconds
/*void getTemp(){
  float _temp;
  int   i = 0;
  do {
    _temp = ds18b20.getTemperature();
  } while (!ds18b20.crcCheck() && MAXRETRY > i++);
  if (i < MAXRETRY) {
    soilC = _temp;
    soilF = ds18b20.convertToFahrenheit(_temp);
  else {
    soilC = soilF = NAN;
    Serial.println("Invalid reading");
void measure (int sensor, int phase_b, int phase_a, int analog_input)
  // read sensor, filter, and calculate resistance value
  // Noise filter: median filter
  for (i=0; i
    // Read 1 pair of voltage values
    digitalWrite(phase_a, HIGH);                 // set the voltage supply on
    supplyVoltage = analogRead(analog_input);   // read the supply voltage
    digitalWrite(phase_a, LOW);                  // set the voltage supply off
    digitalWrite(phase_b, HIGH);                 // set the voltage supply on
    sensorVoltage = analogRead(analog_input);   // read the sensor voltage
    if (sensorVoltage <= 0){sensorVoltage = 1;} //Very important the particle will brick it if it reads 0
    digitalWrite(phase_b, LOW);                  // set the voltage supply off
    // Calculate resistance
    // the 0.5 add-term is used to round to the nearest integer
    // Tip: no need to transform 0-1023 voltage value to 0-5 range, due to following fraction
    long resistance = (knownResistor * (supplyVoltage - sensorVoltage ) / sensorVoltage) ;
// Averaging algorithm
void addReading(long resistance){
  buffer[inde] = resistance;
  if (inde >= NUM_READS) inde = 0;
long average(){
  long sum = 0;
  for (int i = 0; i < NUM_READS; i++){
    sum += buffer[i];
  return (long)(sum / NUM_READS);

Step 4: Webhooks, Say Whaaaat. Tinamous

The code should now be being published to the cloud and you can see it coming into particle:

  • Navigate to the Console (bottom left in the IDE, looks like home made dominoes > The events tab on the left >_ or devices (cube top left) > the device). Please note my picture shows some out of range data, quite a few of the sensors were not hooked up.

This is good but other than sitting there in your chair all day and monitoring the state of things, live is a bit limited.

So what next? Well we need to push the data to something so that we can record and analyse it over time. For one device knocking out a tad of data occasionally do we really want to pay a lots of moneys subscription....? Your not exactly monitoring data servers! I know, ideally you want it plumbed to your PC, but that is a whole 'nother kettle O fish'. I am working on it, but the hurdles are tricky!

There are a few options out there on the cloud with their hooks and catches. I have used weather underground with my home brew weather station but I would feel a bit guilty doing that with Irrigation data (it's not really raining is it). I can also recommend Ubidots but it is more faff to setup and if you have ham mands like me then you'll spend a couple of hours trying to figure out which letter is wrong. They also charge. Initial state is good but free tier only saves 24hrs of data. IFFFT is also a good shout but at the moment the most you can do is whack it in a google spreadsheet.

The simplest I have found for this type of thing is Tinamous. It does a really good job on stuff like this. If you expand there is facility for it and the pricing seems very fair, also UK based. The great thing about Tinamous is it has a Particle Bot, yeeeessssss. It does all the coding and getting the commas in the right place for you.

  • You'll need an account.
  • Once in click top right More button > Bots > Add > Add Particle Bots, Whack your details in, simples.
  • If you then go to the devices tab you should see it has pulled in all your devices for you.

Now this is the clever bit, because we named the data json (yea I bet you were wondering) and formatted it accordingly. It will recognise it and table it. NB. JavaScript Object Notation is a way of formatting data so that things can read it.

  • If you click the name of the relevant device it will graph out the data it has seen from it. You can select deselect etc. and change the time period.

It may take a bit of time for that data to come in, maybe shake the bucket a few times or press the reset on the particle to get it to fire up again.

This data can then be added to a dashboard (tab at the top) and you can post a notification if you so wish. I'll leave you to sweat with that!

Step 5: Thanks

A big thanks to all those who have shared their methods through various guides, Vinduino, Particle, Tinamous, Adafruit, Chirp to say a few. I would love to list all but I have been to that may pages that I would struggle to remember. I love the collaboration and I hope this adds.

Comments/critics welcome,


Step 6: Future Ideas and Improvements


  • Tidy the code
  • Upgrade it to their mesh system and have it linkable to other units, this would greatly increase the battery life and possibly do away with the need for a solar pannel.
  • Make the publish string self buildable depending on the sensors available.
  • Make it adaptable to grain store monitoring, giving it a winter use. It's basically the same job with less going on.
  • More inputs; would be nice to have the solar rad, leaf wetness and possibly even C02 but I'm a way away from that yet.
  • Personal data store.
  • Get it to talk to the irrigator and pump :).


I'm working on lots of farm based ideas mostly along this line, some are coming to fruition but time and finance do weigh. If your like minded and fancy collaborating drop me a message.

Build a Tool Contest

Participated in the
Build a Tool Contest

Be the First to Share


    • The 1000th Contest

      The 1000th Contest
    • Battery Powered Contest

      Battery Powered Contest
    • Hand Tools Only Challenge

      Hand Tools Only Challenge

    4 Discussions


    1 year ago

    Impressive. I am currently implementing many similar sensors plus some extra (e.g. leaf wetness, solarradiation, water clarity [aquaponics], CO2), currently in a coldframe for testing, but would be just as usable in a greenhouse or outside. All on an ESP8266 platform. Logging currently in influxdb on an RPi. Oops, I mean 'logging it in a personal cloud'
    Hope to publish it soon on instructables.
    Definitely be interested to share ideas with you


    Reply 1 year ago

    Ah wow that sounds really good. What sensors are you using? I have also biult a weatherstation with a TSL2561 for light, It's quite good but I found it didn't like being turned on and off. I put a BME 680 on it which measures VOC's still not quite sure what it is telling me!
    Are your plans to make it hardy? The biggest thing I have come up against is making it stand the test of time. A lot of the hobby sensors are not rugged enough for the big outdoors.
    The water sounds really interesting, I really want to start monitoring the water quality in our stream, again I havn't looked at it yet I keep finding the cost of the hardware prohibative and I cannot find a good enough reason for it.
    I'm guessing your opperating this on a local network? Influx is great especially if you get grafana or similar tied in. Another good one to look at is Node-Red it's great when you start wanting to get things to react ect. Or domoticz (home automation but you can lever it for this purpose).
    I'm trying to intergrate various systems and have developed pump controllers amoung other things. The idea is to get everything talking.
    Best of luck,


    Reply 1 year ago

    I am using several ds18b20's coz I am monitoring temp within the coldframe, outside temp, soiltemp, watertemp as well as the temp in a nearbij compost heap.
    using DHT12 for humidity. I am quite familiar with the BME280, have it in a weather station. reason not to use it in current project is that the DHT12 came in a decent casing as opposed to the BME280 is a bare PCB. I may in future replace the DHT12 with an SI7021 or HTU21D, but for now the DHT12 seems rocksolid. My 'problem' with the BME680 is that just like you said, one has no idea what the VOC output actually means.
    For light I use the Si1145. a totally wrong choice. it's crap. Perhaps the tsl2561 is a better choice.
    Waterclarity I measure with a DIY sensor. basically 2 glass tubes immersed in the water, 1 with an led and one with an LDR. Not sure if it's totally lineair, but for my purpose that's not really necessary.
    CO2 I use an MH-Z17. They are not cheap, but I was lucky enough to find it in an old ac unit. There are cheaper CO2 sensors in the MQ sensor series, but also there the outcome is confusing as one just gets a value for mixed gasses.
    I measure soulhumidity with a capacitive sensor. it is an integrated one that outputs an analogue signal so I don't have to do any signal processing myself.
    As I am using an ESP, I added an I2C ADC converter for the couple of analogue signals I have to process.
    I indeed use grafana with influxdb. Good combination. it is all tied in with openhab and communication with mqtt. I have worked with node red, but have not had the time or the need yet to dive into it.
    Durability is indeed an issue. that's why for now I am testing it in a coldframe. the DHT's are known to suffer under high humidity, so will be interesting to see how that holds up. The leaf wetness sensor as I have ofcourse is prone to electrolytic degradation, but it's cheap to replace. Am considering adding a heating element to it


    Reply 1 year ago

    Looking forward to seeing the write up sounds like I'll learn something!