Watering Your Plants With an Attiny Microcontroller

by diy_bloke in Living > Gardening

26088 Views, 96 Favorites, 0 Comments

Watering Your Plants With an Attiny Microcontroller

garden3.JPG
garduino_print_annotated.jpg
garduinoprint-3.jpg
sensor.jpg

I know, there are quite a few instructables on how to automate the watering of your plants. Usually this is done around an Arduino. I decided however to use a bit of a cheaper solution with one of Arduino's little brothers, the Attiny45, but it would probably work with an Attiny13 as well. (confirmed, it does)

The circuit is quite simple. A humidity sensor attached between Vcc and Pin 3 (=analog pin2) forms a voltage divider. If the soil gets dry, the resistance of the sensor increases and the voltage on pin3 goes down.
If it falls below the level of the level set with P1, the Attiny knows the soil is too dry and makes pin 7 high. Pin 7 feeds into a solid state relay -39MF22- that switches on a pump that is submersed in a water reservoir.
I have chosen the 39MF22 for no other reason than that it was very cheap.
The zenerdiode D1 is there to protect the chip. If there is a long line coming from the humidity sensor, voltage spikes might be carried over it, hence the zenerdiode. I will discuss the jumperblock later

Till so far the Attiny has done nothing more than act as a comparator and in fact could be replaced by a 741 (if you forget about pin campatibility), but it being a microcontroller, it can do a few more things. (should you want to do it with a 741 op amp, look here)
Submersible pumps usually dont like to be left running dry, so the Attiny checks the waterlevel by means of a switch (S1) that in my case is a reed switch on the outside of the container with a magnet on a floating device IN the container. You could also use a tilt switchor a mechanical switch activated by a floating device. The simplest form I have seen was a floating rubber ducky attached to a make switch via a string. If the waterlevel got too low, the ducky would pull the switch.

If you have fantasy enough, you could for instance attache an LDR or an NTC between Pin 1 and ground and let the watering only be done at night, in the morning, during mid day or when it was the hottest moment of the day.

Picture 2 shows the mounting of the components on a PCB. As I quickly wanted to test the circuit, I had not mounted some of the components yet. It has a bit more components than are in the previous picture and that is because I added a standard 7805 based powersupply

Picture 3 shows the PCB (Download) It has some red thingies on it, and I will get to those later. Be aware that this PCB is seen from the component side and therefore it is directly useable for heat transfer: In short: print it on glossy paper, put that on the copperside of a piece of clean and degreased PCB and transfer that with a hot iron. Etch in HCl and H2O2 (my preferred method)

Picture 4 shows the humidity sensor that I use. There is a lot of discussion on humidity sensors, but it usually comes down to either 2 galvanized spikes or a gypsum sensor. I have used both and I prefer the galvanized spikes. Easy to make, easy to use. Yeah but what about corrosion?

Yep there is corrosion, especially when a current flows through the spikes (eventhough it is very little). and that is where the jumperblock in the circuit comes in. For simplicity I am feeding the spikes just from the main line, so there is a continous voltage and a continuous current and yes that speeds up corrosion.

You could chose however to feed the spikes from a digital I/O pin e.g. Pin 5. I could have put that option in the PCB design with a 3 prong jumper, but that seemed a bit foolish as I decided already I was just going to use the main line, but if you want to feed it from Pin 5 then have a look at the PCB design. It involves interrupting a copper trace and running a wire. That is all there is to it. The software already caters for it. The changes are indicated in red on the PCB design

Just a bit more about the sensor and resistor R1. Ideally, R1 has the same value as your sensor has on its 'just wet enough, could use some water' resistance. So, when you have made your sensor, stick it in your soil at a moment that it jcould use some water. So not when your soil is bone dry, but at a moment you think, well, I could water today, but maybe it will hold till tomoro.
Stick in your sensor and measure it's resistance. Chose that as resistance for your R1. In my case it was 10 k, but much depends on the type of soil, but also on the distance between the spikes. I have them close together but you could opt to put them at opposite ends of your plant bed..

Software:
------
/* Garden 3
april 2012
Sensors:
-Humidity spike on analog pin2

*
*----------------------Humid------------------------------
* Schematic:
*[Ground] -- [10k-pad-resistor] -- | -- [Spikes] --[Vcc]
*
* Analog Pin 2
*
*
ATTiny pins
Physical Analoog Digital
1 0 5 Reset, PinChange Interrupt
2 3 3 INT0,3
3 2 4 INT0,4
4 Ground
5 0 INT0,0
6 1 INT0,1
7 1 2 INT0,2
8 Vcc
*/
//Pin definities
const byte levelPin= 3; //analogue Pin3 ->Physical pin2 set level
const byte humidPin=2; //analogue Pin2 ->Physical pin3 Humidity sensor
const byte pumpPin =2; //digital Pin2 ->Physical pin7 Pump
const byte emptyPin=1; //digital Pin1 ->Physical Pin6 waterlevel
const byte spikePin=0; //Digital Pin0 ->Physical Pin5 Extra for intermittent switching of spike
// Variable setting
int moist=0; //float is not necessary
int irrigate=0; //level for irrigation
byte level=0;
//The following function, "setup", must always be present
void setup()
{
pinMode(levelPin,INPUT); // set level
pinMode(humidPin,INPUT); // measures humidity
pinMode(emptyPin,INPUT); // measures reservoir
pinMode(spikePin,OUTPUT); // for alternative supply to spikes
pinMode(pumpPin,OUTPUT); // Output for Relay
digitalWrite(pumpPin, LOW);
digitalWrite(spikePin, LOW);
}

void loop() //This function must always be present
{
level= digitalRead(emptyPin);
/*
First read the level set with P1 on the levelPin and store that in 'irrigate'
*/
irrigate=sample(levelPin);
/*

Then we read the Humidity sensor.
We'll first have to set the spikePin to HIGH, in case that is used to feed the sensor. After the reading we set it back) If the value read ('moist') is smaller than what is considered dry ('irrigate') then the pump should be switched on for a specific time. This is done by indicating a higher treshhold for switching the pump off
*/
digitalWrite(spikePin, HIGH);
moist=sample(humidPin); //read humiditySensor
digitalWrite(spikePin, LOW);
level= digitalRead(emptyPin);
if (moist <= irrigate) digitalWrite(pumpPin, level);
if (moist >= irrigate+5) digitalWrite(pumpPin, LOW); // prevents Jitter
//end loop
}
int sample(int z)
/* This function will read the Pin 'z' 5 times and take an average.
Afterwards it will be mapped by dividing by 4
Thus: divide by 20
*/
{
byte i;
int sval = 0;
for (i = 0; i < 5; i++){ sval = sval + analogRead(z);// sensor on analog pin 'z'
}
//sval = sval / 5; // average
//sval = sval / 4; // scale to 8 bits (0 - 255)
sval=sval/20;
return sval;
}

The software is quite straightforward and does not need much explaining. The measuring is done with the function 'sample' (I 'stole' that somewhere but I forgot where so the credit is not all mine). Every time before the function is called, the 'spikePin' is set high in case you use that to feed the spikes. If you just feed it from teh 5V line, that instruction can be left out.
As it is, the software continuously measures, so it really does not make that much difference where you feed the spikes from. If you chose to feed the spikes from the digital I/O pin, it would make sense to also build in a delay in the measuring, like once every hour , or two times a day. As the circuit does not have a clock, it is easiest to do that delay with one or more 'delay' instructions.

Getting the software in the Attiny
There are plenty of instructions on that and it is not the subject of this tutorial. You could use a dedicated programmer, another arduino, or even your serial or parallel port.
But in short you have to install an Attiny85 core and select that when compiling and programming. Go here for cores and explanation.


Extra:
Pin 1 of the Attiny is pulled high because this is usually the reset pin and one does not want that to hang loose. If one would replace R4 with a 1k resistor in series with a LED, that can be used for signal functions like 'I am measuring now' or 'The water level is too low'. However, you need to program that pin as an ordinary Digital pin and it thus loses its reset function. That means that reprogramming is not possible without an HighVoltage programmer.

Note:
If you are making the PCB, it is wise to make the pads where the conenctors go in a tad bigger with e.g. a felt pen or some nailpolish, so when you solder in the connectors they can get good grip.