Gardening is one of the common hobbies. It keeps you close to nature. It is healthiest hobby that anyone can have. Though, plants and trees are like pets. They need continuous care without break. One needs to be with them all time. This is not always possible. One may have to go for vacations or business trips or travel for other reasons. At such times, the garden may remain unattended for some time or even could be left unattended for a long period of time. This project aims to make garden care for itself with the help of electronics. This will eliminate the unnecessary obligation and also ease the gardening.
This project is a garden monitoring and automation system. It is built using AVR Microcontroller and a bunch of electronic sensors. The AVR controller used in the circuit is ATmega16. The ATmega16 continuously monitors the soil moisture with the help of Soil Moisture Sensor and controls a water pump (here DC Motor for demonstration purpose) as the soil goes dry. The controller also tracks the ambient temperature with the help of LM35 Temperature Sensor and switches the water pump as the temperature rises. The ATmega16 also manages to control the lighting of the garden. It tracks if it is day or night with the help of a Light Dependant Resistor. If it is night, then it monitors if someone enters the garden with the help of IR sensors. It tracks number of visitors using IR sensors and switches on LED lights as per the number of occupants in the garden. The controller is also interfaced with a 16X2 Character LCD where it displays current temperature and percentage of soil moisture from LM35 and Soil Moisture Sensor respectively.
The controller is programmed using embedded C. The AVR Studio 4 is used to write, edit and compile code for ATmega16. This project makes a garden fully automated and self caring. It also saves electricity by controlling the pump only when water is required in the garden.
Component Required –
16×2 LCD display – 1
IR module – 2
LM32 – 1
Soil moisture sensor – 1
LDR – 1
16 MHz crystal oscillator – 1
LED – 4
5v Relay – 1
2N2222 – 1
1K resister – 3
10K resister – 1
22pf capacitor – 2
10K potentiometer – 1
AVR programmer – 1
PCB/breadboard – 1
7805 – 1
Connecting Wire – As required
Block Diagram:-
Fig. 1: Block Diagram of AVR ATmega16 based Garden Monitoring and Automation System
Circuit Diagram –
Fig. 2: Circuit Diagram of AVR ATmega16 based Garden Monitoring and Automation System
Prerequisite Skills –
Before trying this project, the developer must have the following prerequisite skills –
1) The developer must have basic knowledge of AVR Microcontrollers.
2) The developer must be familiar with programming in AVR Studio 4.
3) The developer must know that how 16X2 LCD is interfaced with AVR controller and text is displayed on it.
4) The developer must know how to control DC motor using AVR microcontroller.
5) The developer must have understanding of working with internal ADC of AVR controller.
Circuit Connections –
The circuit of this project is based on AVR ATmega16. All other components are interfaced to the controller. The circuit is designed by assembling the following components –
1) AVR ATmega16 – Atmega16 is a 8-bit AVR microcontroller with 32 I/O pins. It is interfaced with sensors and character LCD to design the circuit of this project. ATmega16 has the following pin diagram –
Fig. 3: Pin Diagram of AVR ATmega16 Microcontroller
2) 16X2 Character LCD – A character LCD is interfaced to the controller to display the ambient temperature and moisture level of the soil. The VSS pin of the character LCD is connected to ground and VDD pin is connected to 5V DC. The RS, RW and E pins of the LCD are connected to bits 0, 1 and 2 of Port C of ATmega16 respectively. The LCD is interfaced in 4-bit mode with the AVR controller. The data pins D4, D5, D6 and D7 of the LCD are connected bits 4, 5, 6 and 7 of Port C of ATmega16 respectively.
3) LM35 Temperature Sensor – LM35 is a popular temperature sensor. The sensor has three terminals – VCC, Output and Ground. The VCC and Ground terminals are connected to 5V DC and common ground respectively. The output terminal is connected to bit 2 of Port A of ATmega16.
4) Soil Moisture Sensor – The moisture sensor measures the volumetric water content of the soil with the help of a sensing probe which must be put into the soil. The sensor module operates between voltages of 3.3 V to 5V. It has a LM393 comparator on-board. The module has four terminals – VCC, Ground, Data out and Analog output. The VCC and Ground pins are connected to the common VCC and Ground respectively. The analog output pin of the sensor is connected to bit 1 of Port A of the AVR.
5) LDR Sensor – The LDR sensor is used to detect day or night in this circuit. The LDR sensor is two-terminal light sensitive resistor. It is connected as a voltage divider network at bit 0 of Port A of the ATmega16.
6) IR Sensors – There are two IR sensor modules used in the project. The two modules are used to detect entrance and exit of a visitor. Each sensor module is built from a pair of IR Transmitter and IR Receiver. The emitter is simply an IR LED and the detector is simply an IR photodiode which is sensitive to IR light of the same wavelength as emitted by the IR LED. The sensor module has a digital output. The sensor module must output either HIGH logic or LOW logic so that it could be detected at GPIO pin of the microcontroller. The analog output from the photodiode can be converted into digital data using Analog to Digital Converters (ADC). An Operational amplifier is used to convert the analog output from photodiode to digital logic of LOW or HIGH. The IR Sensor Modules have the following circuit diagram –
Fig. 4: Circuit Diagram of IR Sensor Module
For making the sensor module, the IR transmitters are connected in series with pull-up resistors of 470 ohm between VCC and ground in forward bias configuration. The IR receivers are connected in series with variable resistors between VCC and ground in reverse bias configuration forming a voltage divider circuit. The output from the IR receivers (photodiodes) is drawn from the junction of cathode terminals of the IR receiver and variable resistors. Such one pair of IR receiver and transmitter is connected between VCC and ground to form the IR sensor module. The output from the IR receivers is connected to the bits 3 and 4 of Port A of the ATmega16 via OPAM comparator. LM358M can be used as OPAMP comparator.
7) LEDs – There are 4 LEDs interfaced at bits 0, 1, 2, and 3 of Port B of ATmega16. These LEDs are for demonstration purpose to show control of lighting in the garden. In a practical version of the circuit, there could be LED lights controlled through relays by the controller.
8) DC Motor – A DC motor is interfaced at bit 5 of Port D of the AVR. This motor is for demonstration purpose to show control of water pump by the controller. In a practical version of this circuit, there could be actual water pump that can be interfaced to the controller with the help of a 6V relay.
9) Power Supply – The circuit can be powered by a battery and 5V regulator IC like 7805. It can also be powered through AC mains by using a step down transformer and rectifier circuit with 7805 voltage regulator.
First of all, one needs to load the hex code in the ATmega16 using AVR programmer. Then, the circuit can be assembled either on a breadboard or soldered on a PCB. It will be better to first test on a breadboard.
How Circuit Works –
When the microcontroller is powered on by a 5V DC supply, it first flashes some initial messages on the LCD screen like “Engineers Garage “ and “WELCOME TO GARDEN MONITORING”. After these messages are flashed on the LCD screen for once, the controller reads analog voltages from Soil Moisture Sensor and the LM35 Temperature Sensor. It converts the analog voltages to digital values using in-built 10-bit ADC channels. The digitized readings are converted by the code to measurements in actual physical quantities i.e. percentage of moisture in soil and ambient temperature, and then displayed on the character LCD.
If the moisture level detected by the moisture sensor has dropped below a threshold level, the controller switches on the motor to pump water in the garden. The water is supplied to different parts of the garden with the help of a drip kit. Similarly, if the ambient temperature has risen above a threshold level, the controller again switches on the motor to pump water in the garden. So that, the temperature of the garden, can be cooled down.
This garden monitoring system also controls the lighting of the garden. It tracks day or light with the help of LDR sensor. If it is night, it detects entrance and exit of any visitor with the help of two IR sensor modules. If a person enters the garden in night, it switches on one LED. If another person enters, it switches on one more LED. Similarly, other LEDs are switched on. Similarly, if number of occupants in the garden is reduced on exit of one or more occupants, the LEDs are similarly turned off according to the number of current occupants in the garden.
The ATmega16 senses the analog voltage from moisture sensor and the temperature sensor and convert them to digital readings using in-built ADC channels. ATmega16 has 10bit ADC Resolution, so, it can convert voltage readings to a value between 0 and 1023.
2n -1 = 210 -1 = 1023
It has 8 ADC channels that have input at pins 0 to 7 of the Port A. The working of this circuit is based on the ADC feature of the microcontroller. Atmega16 has the following internal registers associated with the in-built ADC feature –
1) ADMUX (ADC Multiplexer Selection Register)
2) ADCSRA (ADC Control and Status Register)
3) ADCL & ADCH (ADC Data Registers)
4) SFIOR (Special Function IO Register)
The functioning of the ADC channels is controlled by ADMUX register in Atmega16. The ADMUX register has the following bit values –
Fig. 5: Bit Values of ADMUX Register of AVR ATmega16
The REFS1 and REFS0 bits are used for selecting the voltage reference. The voltage reference is selected as per the following bit values of REFS1 and REFS0 –
Here, AVCC with external capacitor at AREF pin mode is selected, for which, REFS0 is set to 1 and REFS1 is set to 0. As REFS1is by default zero so only REFS1 need to be modified as follow –
ADMUX = (1<<REFS0);
The ADLAR bit affects the presentation of the ADC conversion result in the ADC Data Register. On writing 1 to ADLAR, the conversion result is left adjusted. Otherwise, the result is right adjusted.
Fig. 6: Bit Shifting of ADC Data Registers as per status of ADLAR Bit in ADMUX register
The bits MUX4 to MUX0 are used to select analog channel, type of input and gain. The input channel and gain selection is done as follow –
Here ADC Channel 3 is selected by setting MUX0 to 1 and MUX1 to 1 as follow –
ADMUX = (1<<MUX1) | (1<<MUX0); // for ADC channel 3
The ADCSRA has the following bit values –
Fig. 7: Bit Values of ADCSRA Register of AVR ATmega16
The ADEN bit is used to the enable ADC. The bits ADPS2, ADPS1, ADPS0 are used to determine the division factor between the XTAL frequency and the input clock to the ADC. The bit ADSC is used to start each conversion in Single Conversion mode and start the first conversion in Free Running Mode. The bit ADATE is used to enable Auto Triggering. The bit ADIF is set when an ADC conversion completes and the Data Registers are updated. The bit ADIE is used to activate interrupt when conversation is completed. Here the ADC control register is set as follow –
ADCSRA = (1<<ADEN)| (1<<ADPS2)| (1<<ADPS1)| (1<<ADPS0);
SFIOR register is used for Auto Triggering. This register not used in programming this project.
Programming Guide –
This system is based on AVR ATmega16. It is programmed in embedded C using AVR Studio 4. Other programming tools like Atmel Studio or Notepad++ can also be used to write and compile the code. Firstl of all, user needs to add LCD library given below in zip file then copy and paste the code in AVR Studio 4 to generate hex file.
Here, ATmega16 is used for sensing the condition of garden and take appropriate actions to control the gardening equipments like motor and lights. The LCD is interfaced with atmega16 to monitor the value of ambient temperature and soil moisture via sensors.
Constants used in the code:-
#define F_CPU 16000000UL :– Constant used to define clock frequency of the MCU
#define IR1 0b00001000 :– IR sensor 1 is Connected to the pin 4 pin of PORTA
#define IR2 0b00010000 :– IR sensor 2 is Connected to the pin 5 pin of PORTA
Variable used in code:-
int num_LDR; :– To get ADC value from LDR
int num_Moist; :– To get ADC value from soil moisture sensor
int num_temp; :- To get Temperature v
int person=0; :– To Count the number of person entered or exited
int moist_per; :– To calculate the moisture in percentage
int temp_c; :- To calculate temperature in Celsius
char LDR[5]; :– To print LDR value on LCD
char Moist[5]; :– To print Soil moisture percentage on LCD
char temp[5]; :– To print LM35 value in Celsius on LCD
Header file and Libraries used in the code:-
#include <avr/io.h> :- Standard AVR header for input/output
#include <util/delay.h> :- Standard AVR header to provide time Delays
#include <lcd_lib.h> :- External library for LCD operations
Functions used in the code:-
adc_init :– To initialize the ADC in ATmega16
adc_read :– To Read the ADC value at selected channel
ir_count :– To count the person entered/exited to control LED
LCDinit :– To initialize LCD
LCDclr :– To clear LCD
LCDcursorOFF :– To Turn off the cursor
LCDGotoXY :– To map the cursor
LCDstring :– To print the String on LCD
sprint :– Store value as character to print on LCD
Algorithm:-
The code for this garden monitoring and automation system works according to the following algorithm –
1) When the circuit is powered on, first of all, the Ports are initialized as input and output. The Port A is set as input by defing DDRA to 0x00. The Port B and Port D are set as output by defing DDRB and DDRD respectively to 0xff. Initially, all ports are set LOW by passing 0x00 to Port A, Port B and Port D.
DDRA = 0x00; DDRB = 0xff; PORTA = 0x00; PORTB = 0x00; DDRD = 0xff; PORTD = 0x00;
2) After this, the ADC is initialized by the function adc_init() to turn on the ADC operation on ADC pins. The LCDinit() function is used to initialize LCD for LCD operations. When LCD is turned on, it may have garbage value, so, LCDclr() function is used to clear the LCD and cursor is turned off using LCDcursoroFF() function.
adc_init(); LCDinit(); LCDclr(); LCDcursorOFF();
3) Here, LCD cursor is mapped at (3,0) which means first row and 3rd column. It is used to print “ENGINEERS” then LCD cursor is mapped at (4,1) which is 2nd row and 4th column and “GARAGE” is printed. It takes some delay after which, LCD is cleared using LCDclr() function.
LCDGotoXY(3,0); LCDstring("ENGINEERS",9); LCDGotoXY(4,1); LCDstring("GARAGE",6); _delay_ms(1500); LCDclr();
4) Now, the LCD is ready to print next message. So, LCD cursor is set to the (4,0) to print “WELCOME” and it is again set to (6,1) to print “TO”. After some delay it is cleared and a new massage “GARDEN”, “AUTOMATION” is printed as per defined mapping. The message remains on screen and after some delay, the final massage “Moisture =”, “Temperature =” are printed on LCD with Sensor Outputs.
LCDGotoXY(4,0); LCDstring("WELCOME",7); LCDGotoXY(6,1); LCDstring("TO",2); _delay_ms(1000); LCDclr(); LCDGotoXY(5,0); LCDstring("GARDEN",6); LCDGotoXY(3,1); LCDstring("MONITORING",10); _delay_ms(1500); LCDclr(); LCDGotoXY(0,0); LCDstring("Moisture = %",15); LCDGotoXY(0,1); LCDstring("Temperature =",13);
5) Now, the sensor values from ADC channel are initialized into the variables – num_LDR, num_Moist and num_temp. The value of Moisture and Temperature is analog in nature, So, they are mapped via formula. The moist_per is used to calculate the value of moister in percentage and temp_c is used to calculate the value of temperature in Celsius.
num_LDR =adc_read(0); num_Moist =adc_read(1); num_temp =adc_read(2); moist_per=((float)num_Moist/1023*100); moist_per=100-moist_per; temp_c=((float)num_temp/1023*5*100);
6) Now, the LCD cursor is mapped at (10,0) to print the moisture percentage. After this, the LCD cursor is mapped at (13,1) to print the value of temperature in Celsius.
LCDGotoXY(10,0); sprintf(Moist,"%d ",moist_per); LCDstring(Moist,strlen(Moist)); LCDGotoXY(13,1); sprintf(temp,"%dc ",temp_c); LCDstring(temp,strlen(temp));
7) There are two conditions added for moisture sensor – a) when percentage goes below 30 then the pin 5 of port D will be on where relay is connected and it will turn off when moisture value exceed the 70 percent. After this, there is a condition for LDR to detect the light or dark. If LDR value is below 500 in term of ADC, then, it is dark outside so the ir_count() function will be called which will turn on light according to the number of person entered/exited in garden.
if (moist_per<30) { PORTD |= (1<<PD5); } if(moist_per>70) { PORTD &= ~(1<<PD5); } if(num_LDR<500) ir_count(); else PORTB &= ~0x0f;
Check out the complete code and try this project now.
You may also like:
Project Source Code
###
//Program to /* * Garden_monitoring.c * * Created: 3/11/2019 10:45:12 AM * Author : Administrator */ #define F_CPU 16000000UL #include#include #include #define IR1 0b00001000 #define IR2 0b00010000 char LDR[5],Moist[5],temp[5]; int num_LDR,num_Moist,num_temp; int person=0; int moist_per,temp_c; uint16_t adc_read(uint8_t ); void adc_init(); void ir_count(); int main(void) { DDRA = 0x00; DDRB = 0xff; PORTA = 0x00; PORTB = 0x00; DDRD = 0xff; PORTD = 0x00; adc_init(); LCDinit(); LCDclr(); LCDcursorOFF(); LCDGotoXY(3,0); LCDstring("ENGINEERS",9); LCDGotoXY(4,1); LCDstring("GARAGE",6); _delay_ms(1500); LCDclr(); LCDGotoXY(4,0); LCDstring("WELCOME",7); LCDGotoXY(6,1); LCDstring("TO",2); _delay_ms(1000); LCDclr(); LCDGotoXY(5,0); LCDstring("GARDEN",6); LCDGotoXY(3,1); LCDstring("MONITORING",10); _delay_ms(1500); LCDclr(); LCDGotoXY(0,0); LCDstring("Moisture = %",15); LCDGotoXY(0,1); LCDstring("Temperature =",13); while (1) { num_LDR =adc_read(0); num_Moist =adc_read(1); num_temp =adc_read(2); moist_per=((float)num_Moist/1023*100); moist_per=100-moist_per; temp_c=((float)num_temp/1023*5*100); LCDGotoXY(10,0); sprintf(Moist,"%d ",moist_per); LCDstring(Moist,strlen(Moist)); LCDGotoXY(13,1); sprintf(temp,"%dc ",temp_c); LCDstring(temp,strlen(temp)); if (moist_per<30) { PORTD |= (1< 70) { PORTD &= ~(1< ###
Circuit Diagrams
Project Video
Filed Under: Electronic Projects
Filed Under: Electronic Projects
Questions related to this article?
👉Ask and discuss on EDAboard.com and Electro-Tech-Online.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.