Watering Your Plants With an Attiny Microcontroller




About: I am a physician by trade. After a career in the pharmeceutical world I decided to take it a bit slower and do things I like. Other than my hobbies that involves grassroots medicine in S.E.&P Asia. I have bu...

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..

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

* 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'

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)
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.

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.

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.



    • Trash to Treasure

      Trash to Treasure
    • Jewelry Challenge

      Jewelry Challenge
    • Tape Contest

      Tape Contest

    18 Discussions


    3 years ago on Introduction

    As I currently cannot edit my instuctable, just a remark here about the micrprocessor: I have been using an Attiny45, but one can use an attiny13 as well.
    The Attiny13 core sometimes seems to have some problems with analogRead and therefore if one uses an attiny13, one needs to add a statement to the setup, being:


    im electrical engneering student.

    Im interested to do this project as my final project.

    please send me information, complete project detail and programming details.


    1 reply

    see my earlier reply. I do not know the sim900D as a display but as a gsm module. Not sure what it is yo want to do.
    seems you would need a microcontroller to sense the moisture and the temperature and send that info to yr sim900

    can i integrate this project with sim900D to display the temperature and moisture of the soil..
    thank you


    Reply 6 years ago on Introduction

    I think i have made mistake.(i know for sure) I have made a setup in our garden with two sensors with common ground, i measure for the north and south sensor almost the same value.

    What i will measure with above setup is something of:

    A replacement resistance for a parallel resistance setup

    This setup can only work (good) with each ground seperated, like each plant with his own pot wit a sensor in it ground is seperated.

    A setup like a "keyboard" matrix is a better idea when there are 6 or more sensors. 2 rows and 3 columns this gives you one input more then there is available on a tiny. the last output is for the pump with an AND port to the level sensor.

    I go further with it, maybe this will be a new instructables.


    Reply 6 years ago on Introduction

    Yes, I had noticed that already but I thought it was just a simple sketch to illustrate an idea but it may work anyway, you just have to keep track what pin you are making high. The mere fact that the readings on several places in yr plantbed are the same is no proof of failure.

    Looking forward to an eventual instructable on this


    Reply 6 years ago on Introduction

    You mean for more diverse measuring, or to reduce corrosion?
    Certainly an interesting thought, though ofcourse the Attiny wld only allow just a few probes.


    Reply 6 years ago on Introduction

    My idea was a direct measurement by the plant it self or with squarefoot gardening each square a probe.
    But certainly it reduce the corrosion too. This is a good point.

    You can use a 4051 or 74HC595 to extend the number of outputs.


    Reply 6 years ago on Introduction

    Oh, I see, yes indeed, but one could wonder if that is worthwhile, as still the entire bed is serviced with one pump and I guess that if one plant was dry, all the others would be dry.
    Nevertheless, it would give a possibility to do 'spot metering' and on basis of that decide to irrigate.

    595 would be a good choice as you need only 3 pins to read 8 sensors.

    Going a bit off the chart here, I am fantasizing about a small nozzle that is attached to 2 motors (stepper/servo) that bring that nozzle to a specific plant to deliver it some water if it goes dry.

    Hmm, now that might be a project, though probably more for fun to see what can be done than for real practical efficiency


    Reply 6 years ago on Introduction

    An other option i have found is a CD4017 decade counter, this one use the clock pulse as counter, it use one output of the attiny.

    I had almost same the idea of 16 tubes side by side and a motor on a rail with a nozzle attached to it.

    If i have more time maybe i'm going to build something like that.


    Reply 6 years ago on Introduction

    I'd be interested to see that. Ofcourse some construction problems to overcome as a nozzle cannot move freely over (through) the plants. Maybe one rails at the side and then somehow make the nozzle go in between a row of plants and back, But again, maybe more interesting to do for fun than really the most effective way :-)
    I;ll check into that CD4017


    Reply 6 years ago on Introduction

    Adding to my previous reply. If you have seen my other irrigation project (the one with an opamp) you might have spotted that I am an SQF gardener (partly). Typically my beds have 16 squares, so two 295's would be needed to measure every square. Just of the top of my head I think one could do that with 4 pins. That would leave + 1 pin for the actual reading leaves one pin for a pump control, but you'd have to use something else for the sensor level kill switch.

    Might be a challege to see qhat one could do with a small chip like this, though it might be wiser to go to an ATMega328.

    Good thinking though