So far we have covered aquaponics/Hydroponics automation and control, we also have a soil based system to use as a comparison.
It is best if we automate this system too, Just so we have an accurate measurement of water used and the moisture level of the soil during the grow.
Probe Choices:
There are two main types of probes on the market for a reasonable price:
>Capacitive sensors [long lasting]
>Resistive Sensors [Cheap, but degrade]
This script will work for both types of probes.
[My probe draws a max of 35ma, that is very close to the arduino 40ma max rating, check yours does not exceed this on the spec sheet]
The pinout:
[note mistake on pinout for probe, Should be Analog:A8 Ground:A9 Power A12]
How to use:
>Wire up following pinout as a guide [moisture sensor can change, so use the pin descriptions on the board. you want to use analog output not digital]
>Place soil and temperature sensor in very dry soil [very dry!] click up on the lvd buttons and make a note of the ADC readout
>On same ADC readout, soak the soil with water and make a not of the ADC readout
>Plug these ADC values into the top of the code and reload to the board
>Thats it, leave the probe in the soil for as long as you like to log data about the soil [min/max temperature and moisture levels]
The Script
we are using a modified onewire and dallas library, [can be downloaded from www.michaelratcliffe.com] if your temperature does not read well, use a 10K pull up on temp data line.
Header 1 |
---|
/* Soil Moisture Measurment
28/8/2015 Michael Ratcliffe Mike@MichaelRatcliffe.com
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Parts: -Arduino - Uno/Mega -5v Relay -Water Solenoid -Soil moisture probe [Capacitive or resitive, doesnt matter] -LCD shield with buttons [DFRobot is pretty cheap]
See www.MichaelRatcliffe.com/Projects for a Pinout and user guide or consult the Zip you got this code from or Search Element14 for Adapted_Greenhouse home page [lots of info here]
*/ //************************ Libraries needed **************************************************************//
// Both below Library are custom ones [ SEE READ ME In Downloaded Zip If You Dont Know how To install] Use them or add a pull up resistor to the temp probe
#include <OneWire.h> #include <DallasTemperature.h> #include <LiquidCrystal.h> //Standard LCD Lbrary
//************************* User Defined Variables ********************************************************//
//************* Moisture Probe Related *****************************************// #define Soil_Pin A8 #define Soil_PWR A12 #define Soil_GND A9
//Power up the script and take note of ADC readings related to probe places in dry soil and watter logged soil int Dry_Soil=100; int Wet_Soil=600;
//************ Temp Probe Related *********************************************// #define ONE_WIRE_BUS 26 // Data wire For Temp Probe is plugged into pin 10 on the Arduino const int TempProbePossitive =22; //Temp Probe power connected to pin 9 const int TempProbeNegative=24; //Temp Probe Negative connected to pin 8 OneWire oneWire(ONE_WIRE_BUS);// Setup a oneWire instance to communicate with any OneWire devices DallasTemperature sensors(&oneWire);// Pass our oneWire reference to Dallas Temperature.
//***************************** END Of Recomended User Inputs *****************************************************************// float Soil_T=0; float Soil_M=0; int ADC_Reading=0;
//********************** Some Variables For Loging Min/Max Values ********************************// float MinM=100; float MaxM=0; float MinT=100; float MaxT=0;
// select the pins used on the LCD panel LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// define some values used by the panel and buttons int lcd_key = 0; int adc_key_in = 0; int button =0; #define btnRIGHT 1 #define btnUP 2 #define btnDOWN 3 #define btnLEFT 4 #define btnSELECT 5 #define btnNONE 6
//**********************Some Stuff For Uptime **************************************************//
//************************** Just Some basic Definitions used for the Up Time LOgger ************// long Day=0; int Hour =0; int Minute=0; int Second=0; long Rollover=0; int HighMillis=0; int Readings=0; int Screen=0; int buttonLast=0;
//*********************************Setup - runs Once and sets pins etc ******************************************************// void setup() { Serial.begin(9600); pinMode(TempProbeNegative , OUTPUT ); //seting ground pin as output for tmp probe digitalWrite(TempProbeNegative , LOW );//Seting it to ground so it can sink current pinMode(TempProbePossitive , OUTPUT );//ditto but for positive digitalWrite(TempProbePossitive , HIGH );
//********Setting Soil Probe Pins ************// pinMode(Soil_Pin,INPUT); pinMode(Soil_PWR,OUTPUT); pinMode(Soil_GND, OUTPUT); digitalWrite(Soil_PWR , HIGH ); digitalWrite(Soil_GND , LOW );
delay(100);// gives sensor time to settle sensors.begin(); //Temperature Probe delay(100);
Serial.println("Soiul Moisture Measurment"); Serial.println("By: Michael Ratcliffe Mike@MichaelRatcliffe.com"); Serial.println("Free software: you can redistribute it and/or modify it under GNU "); Serial.println(""); Serial.println("Make sure Probe and Temp Sensor are in Ssoil"); Serial.println(""); Serial.println("Adjust Dry and wet values in code");
lcd.begin(16, 2); // start the library lcd.setCursor(0,0); delay(1000); lcd.print("Arduino Soil"); lcd.setCursor(0,1); delay(1000); lcd.print("Mike Ratcliffe"); lcd.setCursor(0,1); delay(1000); lcd.setCursor(0,1); lcd.print("Free Software "); delay(1000); lcd.setCursor(0,1); lcd.print("Mike Ratcliffe"); delay(1000); lcd.setCursor(0,0); lcd.print("To Navigate "); lcd.setCursor(0,1); lcd.print("Use Up-Down "); delay(3000);
};
//******************************************* End of Setup **********************************************************************//
//************************************* Main Loop - Runs Forever ***************************************************************// //Moved Heavy Work To subroutines so you can call them from main loop without cluttering the main loop void loop() { GetMoisture(); GetTemp(); Log(); read_LCD_buttons(); Uptime(): PrintReadings(); // Cals Print routine [below main loop] delay(100); //Stops us entering the GETEC loop twice } //************************************** End Of Main Loop **********************************************************************//
//************ This Loop Is called From Main Loop to get Soil Temperature************************// void GetTemp(){
sensors.requestTemperatures();// Send the command to get temperatures Soil_T=sensors.getTempCByIndex(0); //Stores Value in Variable
;} //************************** End OF Tmperature Function ***************************//
//************ This Loop Is called From Main Loop to get Soil Moisture************************// void GetMoisture(){
ADC_Reading=analogRead(Soil_Pin); // Map only gives integers, we will need to modify to get better readings [thats what all the *100 are about Soil_M = map(ADC_Reading*100, Dry_Soil*100, Wet_Soil*100, 0, 100*100); Soil_M=Soil_M/100; Readings=1; ;} //************************** End OF Moisture Function ***************************//
//***This Loop Is called From Main Loop- Prints to serial usefull info ***// void PrintReadings(){
if (button>=1||Readings==1) { Readings=0;
if(Screen==1){ lcd.setCursor(0,0); lcd.print("Arduino EC-PPM "); lcd.setCursor(0,1); lcd.print("M: "); lcd.setCursor(2,1); lcd.print(Soil_M); lcd.setCursor(9,1); lcd.print(Soil_T); lcd.print("'C"); }
else if(Screen==2){ lcd.setCursor(0,0); lcd.print("ADC Readout "); lcd.setCursor(0,1); lcd.print(" "); lcd.setCursor(0,1); lcd.print(ADC_Reading);
} else if(Screen==3){ lcd.setCursor(0,0); lcd.print("Mn: "); lcd.setCursor(3,0); lcd.print(MinM,0); lcd.setCursor(9,0); lcd.print(MinT); lcd.print("'C"); lcd.setCursor(0,1); lcd.print("Mx: "); lcd.setCursor(3,1); lcd.print(MaxM,0); lcd.setCursor(9,1); lcd.print(MaxT); lcd.print("'C");
} else if(Screen==4){
lcd.setCursor(0,0); lcd.print("Uptime Counter: ");
lcd.setCursor(0,1); lcd.print(" ");//Clearing LCD lcd.setCursor(0,1); lcd.print(Day); lcd.setCursor(3,1); lcd.print("Day"); lcd.setCursor(8,1); lcd.print(Hour); lcd.setCursor(10,1); lcd.print(":"); lcd.setCursor(11,1); lcd.print(Minute); lcd.setCursor(13,1); lcd.print(":"); lcd.setCursor(14,1); lcd.print(Second);
}
};
};
void read_LCD_buttons(){ adc_key_in = analogRead(0); // read the value from the sensor // my buttons when read are centered at these valies: 0, 144, 329, 504, 741 // we add approx 50 to those values and check to see if we are close if (adc_key_in > 1000) button =0;
else if (adc_key_in < 50) button =1; else if (adc_key_in < 250) button =2; else if (adc_key_in < 450) button =3; else if (adc_key_in < 650) button =4; else if (adc_key_in < 850) button =5;
if(button==2&&buttonLast!=button){ Screen++; } else if (button==3&&buttonLast!=button){ Screen--; }; if (Screen>=4) Screen=4; if(Screen<=1) Screen=1;
buttonLast=button; };
//******************************* LOGS Min/MAX Values *******************************// void Log(){
if(Soil_M>=MaxM) MaxM=Soil_M; if(Soil_M<=MinM) MinM=Soil_M;
if(Soil_T>=MaxT) MaxT=Soil_T; if(Soil_T<=MinT) MinT=Soil_T; }
//**************************** Uptime Counter ********************************************// void Uptime(){ //** Checks For a Second Change *****// //** Making Note of an expected rollover *****// if(millis()>=3000000000){ HighMillis=1;
} //** Making note of actual rollover **// if(millis()<=100000&&HighMillis==1){ Rollover++; HighMillis=0; }
long secsUp = millis()/1000; Second = secsUp%60; Minute = (secsUp/60)%60; Hour = (secsUp/(60*60))%24; Day = (Rollover*50)+(secsUp/(60*60*24)); //First portion takes care of a rollover [around 50 days]
};
|
Future Blogs on this subject:
>Making the moisture probes last longer
>Automated watering
>A Long Lasting Diy Probe? [You can probably guess what this will be made from]
>Logging water usage