Soil tester software

Introduction

The software runs on the Adafruit Feather M0 and, as usual, is written using the Arduino IDE. The program uses libraries provided by Adafruit to work with the OLED display and there is plenty of documentation on their site. I believe a library is available for the TMP102 but I have used a routine from the Arduino Playground for a number of years and I have continued with that as a function.

After it boots up, the software measures the number of pulses it receives on pin 12 (which is inversely proportional to the electrical resistance across the probes) and outputs some corresponding text which indicates the moisture level in the soil.

The text is, hopefully, suitably evocative: Rainforest, WetWetWet, WetWet, Wet, Good, Quite dry, Dry!, Very dry!, Atacama!

If pin 11 is low (determined by the mode switch), the software retains the wettest value detected until the trigger is released.

The software

// soil dampness monitor
// 12.3.18
// dampness5
// for Feather with OLED for testing
// measures a pulse length which is related to
// the reistance between two probes which, in turn
// is related to the dampness of the soil in which
// the probes are inserted (amongst other things)
#include <SPI.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Wire.h>
#define BUTTON_A 9
#define BUTTON_B 6
#define BUTTON_C 5
#define LED      13
#define TMP102_I2C_ADDRESS 0x48 // I2C address TMP102 A0 to GND
Adafruit_SSD1306 display = Adafruit_SSD1306();
int pulse_pin = 12;
unsigned long duration;
//----------------------------------------------
void setup() {
pinMode(pulse_pin, INPUT); // set pin up as input
// these pins are connected to buttons on the OLED
// not used at present 
pinMode(9, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
// initialize with the I2C addr 0x3C (for the 128x32)
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
Serial.begin(9600);
// Clear the buffer.
display.clearDisplay();
display.display();
display.setRotation(2); //if you're right handed
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0,0);  
}
//-----------------------------------------------
// function to get temp from tmp102
int getTemp102(byte ADD_TMP102){
byte firstbyte, secondbyte; //these are the bytes we read from the TMP102 temperature registers
int val;
float convertedtemp; //We then need to multiply our two bytes by a scaling factor, mentioned in the datasheet.
Wire.beginTransmission(ADD_TMP102); // start talking to sensor 
Wire.write(0x00);
Wire.endTransmission();
Wire.requestFrom(ADD_TMP102, 2);
Wire.endTransmission();
firstbyte      = (Wire.read()); 
//read the TMP102 datasheet - here we read one byte from
//each of the temperature registers on the TMP102
secondbyte     = (Wire.read()); 
//The first byte contains the most significant bits, and 
//the second the less significant 
val = firstbyte;
if ((firstbyte & 0x80) > 0) {
val |= 0x0F00;
} 
val <<= 4;
//MSB
val |= (secondbyte >> 4);    
// LSB is ORed into the second 4 bits of our byte.
convertedtemp = val*0.625; // temp x 10
//correctedtemp = convertedtemp - 0;   //should be 5 according to playground author
int temp = (int)convertedtemp;
return temp;
}
//-----------------------------------------------
void loop() {
int tempNow = getTemp102(TMP102_I2C_ADDRESS);
// measure a positive pulse in microseconds
// the large number is the maximum time to wait for a pulse
duration = pulseIn(pulse_pin, HIGH, 50000000);
duration = duration / 100;
Serial.println(duration);
display.clearDisplay();
display.setCursor(0,0);
if (duration > 680){
display.println("Atacama!");
}
else if(duration < 5){
display.println("Rainforest");
}
else if(duration < 10){
display.println("WetWetWet!");
}
else if(duration < 20){
display.println("Wet Wet!");
}
else if(duration < 30){
display.println("Wet");
}
else if(duration < 85){
display.println("Good");
}
else if(duration < 150){
display.println("Quite dry");
}
else if(duration < 200){
display.println("Dry!");
}
else if(duration < 690){
display.println("Very dry!");
} 
display.print("Temp is ");
display.print(tempNow / 10);
display.display();
}

Back to electronics, back to construction