AVR Project – Relay Timer with ATmega8 AVR MCU

Timers are widely used in industrial and domestic application for automating tasks. Microcontrollers can be used to design versatile and accurate timers with ease. Here I present a simple timer that can be used to turn on/off a load after user specified time.

The Timer uses a standard 16×2 lcd module for user interface (UI). User can set the time using a 3 button keypad.

After that Timer is started. While count down is in progress, the time left is displayed on screen.

The program use our LCD driver library more details of which can be found in here. Use avr-gcc + AVR Studio to compile.

The prototype was developed using xBoard MINI, a low cost easy to use ATmega8 development board. The program was burned to the MCU’s flash memory using eXtreme Burner – AVR Software and Hardware. A basic knowledge of working with different tools of AVR development is required, so please refer to following articles.

Note:

  • Fuse Must be set as follows, HIGH FUSE=C9 LOW FUSE=FF (Very Important)
  • If display is blank please adjust RV1
Part List
01 ATmega8-16 PU U1
02 16×2 LCD Module LCD1
03 16 MHz Crystal X1
04 BC548 Transistor Q1
05 1N4007 Diode D1
06 4.7K Resistor R1,R2
07 10K Variable Resistor VR1
08 22pF Disk Capacitor c1,c2
09 0.1uF Disk Capacitor c3,c4
10 Large Push Buttons s1,s2,s3
11 PCB Mountable Relay RL1

Schematic (Circuit Diagram)

Relay Timer with AVR ATmega8

Fig.: Relay Timer with AVR ATmega8

Program


/******************************************************

A Simple Device Timer project designed using ATmega8

AVR MVU. The Timer is usefully for keeping a device
"ON" for a specific period of time. After the set time
elapse the timer automatically turns the load off.

The Timer uses a standard 16x2 lcd module for user interface
UI. User can set the time using a 3 button keypad.

After that Timer is started. While count down is in 
progress, the time left is displayed on screen.

The program use our LCD driver library more details
of which can be found in Web site.

Use avr-gcc + AVR Studio to compile.

Author: Avinash Gupta
E:Mail: me@avinashgupta.com
Web: www.eXtremeElectronics.co.in

*** THIS PROJECT IS PROVIDED FOR EDUCATION/HOBBY USE ONLY  ***

*** NO PROTION OF THIS WORK CAN BE USED IN COMMERIAL       ***
*** APPLICATION WITHOUT WRITTEN PERMISSION FROM THE AUTHOR ***

EVERYONE IS FREE TO POST/PUBLISH THIS ARTICLE IN
PRINTED OR ELECTRONIC FORM IN FREE/PAID WEBSITES/MAGAZINES/BOOKS
IF PROPER CREDIT TO ORIGINAL AUTHOR IS MENTIONED WITH LINKS TO
ORIGINAL ARTICLE 



Copyright (C) 2008-2009 eXtreme Electronics, India.

******************************************************/

#include <avr/io.h>
#include <avr/interrupt.h>

#include "lcd.h"

//Connection of Load
#define LOAD_DDR DDRC
#define LOAD_PORT PORTC
#define LOAD_POS PC0

//Global variable for the clock system
volatile unsigned int   clock_millisecond=0;

volatile char        clock_second=0;
volatile char        clock_minute=0;
volatile char        clock_hour=0;


void Wait(uint8_t n)
{

   uint8_t i,temp;
   temp=n*28;

   for(i=0;i<temp;i++)
      _delay_loop_2(0);
}


void LoadOn()
{
   LOAD_PORT|=(1<<LOAD_POS);
}

void LoadOff()
{
   LOAD_PORT&=(~(1<<LOAD_POS));
}
main()
{

   while(1)
   {
      LOAD_DDR|=(1<<LOAD_POS);

      LoadOff();

      //Enable Pullups on Keypad

      PORTB|=((1<<PB2)|(1<<PB1)|(1<<PB0));

      int8_t hr,min; //Target Time
      hr=min=0;

      //Initialize the LCD Subsystem
      InitLCD(0);
      //Clear the display

      LCDClear();

      //Set up the timer1 as described in the
      //tutorial
      TCCR1B=(1<<WGM12)|(1<<CS11)|(1<<CS10);
      OCR1A=250;

      //Enable the Output Compare A interrupt

      TIMSK|=(1<<OCIE1A);

      //Enable interrupts globally
      sei();

      LCDClear();
      LCDWriteString("    Welcome     ");
      LCDWriteStringXY(0,1,"   Relay Timer  ");

      Wait(4);

      LCDClear();
      LCDWriteString("Set Time - 00:00");
      LCDWriteStringXY(0,1," Start     ^");

      uint8_t selection=1;
      uint8_t old_pinb=PINB;

      while(1)
      {
         while((PINB & 0b00000111) == (old_pinb & 0b00000111));

         //Input received


         if(!(PINB & (1<<PINB2)) && (old_pinb & (1<<PB2)))
         {
            //Selection key Pressed

            selection++;
            if(selection==3)
               selection =0;
         }

         if(!(PINB & (1<<PINB1)) && (old_pinb & (1<<PB1)))
         {
            //Up Key Pressed

            if(selection == 1)
            {

               //Hour is selected so increment it
               hr++;

               if(hr == 100)
                  hr =0;
            }

            if(selection == 2)
            {

               //Min is selected so increment it

               min++;

               if(min == 60)
                  min =0;
            }

            if(selection == 0)
            {
               //Start Selected
               break;
            }


         }

         if(!(PINB & (1<<PINB0)) && (old_pinb & (1<<PB0)))
         {
         //Down Key Pressed

            if(selection == 1)
            {

               //Hour is selected so decrement it
               hr--;

               if(hr == -1)
                  hr =99;
            }

            if(selection == 2)
            {

               //Min is selected so decrement it

               min--;

               if(min == -1)
                  min =59;
            }

            if(selection == 0)
            {
               //Start Selected
               break;
            }

         }


         old_pinb=PINB;



         //Update Display

         LCDClear();
         LCDWriteString("Set Time - 00:00");
         LCDWriteStringXY(0,1," Start    ");

         //Hour
         LCDWriteIntXY(11,0,hr,2);

         //Minute

         LCDWriteIntXY(14,0,min,2);

         if(selection == 0)
            LCDWriteStringXY(0,1,">");

         if(selection == 1)
            LCDWriteStringXY(11,1,"^");

         if(selection == 2)
            LCDWriteStringXY(14,1,"^");

         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);

         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);
      }

      //Start the Load

      LoadOn();

      //Now start the timer
      clock_hour = hr;
      clock_minute = min;
      clock_second =0;

      LCDClear();
      LCDWriteString("  Power Off In ");

      while(1)
      {
         LCDWriteIntXY(4,1,clock_hour,2);
         LCDWriteString(":");
         LCDWriteIntXY(7,1,clock_minute,2);
         LCDWriteString(":");
         LCDWriteIntXY(10,1,clock_second,2);

         if((clock_hour == 0) && (clock_minute == 0) && (clock_second == 0))
         {
            //Time Out

            LoadOff();

            LCDClear();
            LCDWriteString("Load Turned Off");

            while(1)
            {
               LCDWriteStringXY(0,1,"*Press Any Key*");

               Wait(1);

               LCDWriteStringXY(0,1,"                ");

               Wait(1);

               if((~PINB) & 0b00000111)
                  break;

            }

            break;



         }

         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);
         _delay_loop_2(0);
      }
   //Continue again

   }


}

//The output compate interrupt handler
//We set up the timer in such a way that
//this ISR is called exactly at 1ms interval
ISR(TIMER1_COMPA_vect)
{
   clock_millisecond++;
   if(clock_millisecond==1000)
   {
      clock_second--;
      clock_millisecond=0;
      if(clock_second==-1)
      {
         clock_minute--;
         clock_second=59;

         if(clock_minute==-1)
         {
            clock_hour--;
            clock_minute=59;
         }
      }
   }
}


Downloads

My Prototype.

I used the xBoard MINI as a base board for making the timer. The external components attached were the LCD and 3 push buttons.

Fig.: AVR Timer Project Prototype.

 

Using the Timer

The user interacts with the timer using 3 push buttons and the LCD module. The function of 3 keys are :-

  1. Select Key – Select Different items like hour,minute and start. It moves the arrow on screen to indicate which option is currently selected.
  2. Up/Increase Key – Increase the value. For example, select "minute" using "select" key and press this to increase its value.
  3. Down/Decrease Key – Same as above but it decreases the value.

When the timer is powered up the load is in off state. A welcome message is shown. Then you can set the time using the above buttons. After that move to "start" option by using select key. Then press any key to start the timer. Now the screen shows the count down and the load is powered on. When count down reaches 0 the load is turned off. The pictures and videos below illustrate the process.

timer operation

Fig.: Use SELECT key to move between options.

 

AVR TIMER PROJECT COUNTDOWN

Fig.: Count down in progress (HH:MM:SS).

 

AVR TIMER PROJECT

Fig.: The Load Turned Off.

Video

Facing problem with your embedded, electronics or robotics project? We are here to help!
Post a help request.

Avinash

Avinash Gupta is solely focused on free and high quality tutorial to make learning embedded system fun !

More Posts - Website

Follow Me:
FacebookLinkedInGoogle Plus

62 thoughts on “AVR Project – Relay Timer with ATmega8 AVR MCU

  • By Zagg - Reply

    Hi !
    Thanks again for your very great tuto !

    Zagg

  • By Zagg - Reply

    Hi again!
    An idea proposal for your next project/tutorial :

    Adding output to ATMega with an 74HC595 :–)

    Have a nice day!

    Zagg

  • By Uttam Dutta - Reply

    Mr. Avinash
    Thank You again for developing such a nice stuff. I am waiting long for such kind of tutorial, one request-how can I marge real time clock with it.
    Regards,
    Uttam Dutta

  • By kapil - Reply

    Please describe the fuse….
    How can set the fuse bits for the external crystal and for other purpose.

    • By Puiu - Reply

      Note:

      Fuse Must be set as follows, HIGH FUSE=C9 LOW FUSE=FF (Very Important)
      If display is blank please adjust RV1

  • By Businge elly - Reply

    this is a very nice tutorial and i have liked it.Please am begging you could you send me a pdf of the tutorial.my email is ell86bu@gmail.com

  • By Lee - Reply

    Thanks for your great tuto.

  • By Gandoulf - Reply

    Hello

    @kapil:
    You can set the fuse bits by this way (with avrdude):

    avrdude -c %your programing device% -p m8 -P %programing device emplacment% -U hfuse:w:0xC9:m -U lfuse:w:0xFF:m

    Have a nice day !

  • By kapil - Reply

    @ Gandoulf
    thanx. But how you decide about the fuse bit and how they are calculated. one more point is that this is for mega8 how fuse bit is set for the mega16/32/8535 or other?
    thanks!

  • By HYNIX - Reply

    @kapil

    Man ever herd of a thing called DATASHEET ???????????

  • By Marian Neagu - Reply

    Hello!First of all I want to thank you for this tutorial.
    Now I have a question: can I use an ATTINY2313 instead Atmega8 to build this timer?
    I have to say I’m newbie in microcontrollers and when I try to use attiny, it let me set the clock, but when I start the timer, instead of “:” between hours and minutes and seconds it display all kind of characters changing.
    Thank you again.

    P.S. Please excuse my english.

  • By andy - Reply

    Hi,

    Nice tuto, could you show me how to setting about clock source for AVR…?
    I used extrnal crystal 4MHz with Atmega8535, what are registers to be setting to make avr work in proper clock…?

    Cause default setting is CKSEL = 0001 and SUT = 10.

    Thank you

  • By Antons - Reply

    Can you please give me some clue for which compiler is the code written for?
    Cannot just manage to get it parsed by my CodeVisionAVR 2.04

    Thanks in advance!

  • By Avinash - Reply

    @Anton

    I think you have not read the comments given on the code !!!

  • By Antons - Reply

    Sorry my bad!
    As it usually goes: you skip a line == you skip everything…
    Pity that those C notations are so different.
    Nice tutorial of a nice project, by the way!
    Thanks!

  • By Dreggie - Reply

    Hi,

    that’s a nice project ^^

    I would need the same but with a second relay, which turns off at last 10 minutes. It’s for turning off the heat-resistors.

    Need it for my clothes dryer, but it’s an older one, so I don’t get a new timer for it.

    Couldmaybe someone help me out for a chanced code?

  • By seema - Reply

    Hello avinash,

    i have some crazy problem …can you please help me ?

    I am using AVR Studio4 as compiler and JTAGICE mkII and ATmega16 controller .
    Problem is like when I build my program then building is sucess but it showing following things:

    AVR Memory Usage
    —————-
    Device: atmega16

    Program: 17148 bytes (104.7% Full)
    (.text + .data + .bootloader)

    Data: 151 bytes (14.7% Full)
    (.data + .bss + .noinit)

    Build succeeded with 5 Warnings…

    and I am not able to put it in my controller its tell hex file does not fit in selected device

    can you help me ? Is it like I have to change my controller?

    Program: 17148 bytes (104.7% Full) is this mean my controller is full

  • By seema - Reply

    hello Avinash

    plz reply I am in problem …with this error

  • By Ritesh - Reply

    Hi avinash,

    what is use of
    ISR(TIMER1_COMPA_vect)

    why you put this out of main() function ?

  • By sanjeev pandey - Reply

    hi, i m final yr student of EE. i m making a project by using
    atmega853 which is used for the protection of dc motor(12v) with the help of over voltage, undervoltage and over current relay and the value of voltage and current is also being displayed on the lcd . plz can u send me the proper ckt. diagram as well as the programming.

    • By Avinash - Reply

      @Sanjeev
      🙁
      Don’t spoil the name of Indian Students in front of the world. This is no homework site! Why would anyone do the project work for you ??? Its your headache to handle it your self.

  • By Felix Khan - Reply

    Hello Mr. Gupta:

    I have recently started learning AVR and C language programming. I found your website through search engine as I was looking for learning material that would get me started at a beginners level. You are doing a excellent job in explaining this rough and tough material in a very simplistic way. I love your approach of being repetitive and understanding of the beginners needs.

    I am wondering if you write code for others who wish to compensate you for your time? I have a project that I would like to have coded by someone who has the experience to keep the code tidy. If you are interested in helping me out then please let me know. I would love to call you if you wouldn’t mide sharing your phone number with me.

    I hope you keepup the good work.

    Best regards.

    Felix Khan

    Tucson, Az
    USA

  • By murali - Reply

    Hi Avinash
    how to set high fuse =c9 low fuse=FF. I am using ponyprog2000 for writing my atmega8 chip.
    My timer is taking 16secs to skip 1 sec to turn off the load.
    thanks
    Murali

    • By Avinash - Reply

      @Murali,

      See the forum there is a topic on Ponyprog

  • By murali - Reply

    Hi Avinash,
    Thank u for the response. Could not locate the topic ponyprog on the forum, please help.
    Thanks

  • By Neil Ablang - Reply

    any reason why the variables below are set as char instead of integer int?

    volatile char clock_second=0;
    volatile char clock_minute=0;
    volatile char clock_hour=0;

    • By Avinash - Reply

      @Neil

      Because we are running on 8bit CPU and it can handle 8bit variable much more efficiently. It we know value that a variable will hold is in range of -127 tp +128 then we use char only. Another typedef for it is int8_t which stands for 8 bit integers.

  • By neil ablang - Reply

    @avinash

    thanks for the clarification. uint8_t can be used too for those global variables? I am trying use part of your codes into my programs, being newbie on AVRs but not on C.

    anyway, I found your tutorials so easy to follow . It helps a lot, along with reading the Datasheets.

  • By shohaib - Reply

    thanks for this project…..
    I remained searching for hardware requirements for a ATMEGA8l for proper operation for the whole last week,
    basically i was trying to shift to AVR’s from 89c51’s,
    so was trying to find, what are the necessities….
    but was unable to find one,,,,
    but your project clearly shows , what hardware is necessary,
    once again thanks

  • By paul - Reply

    Bonjour

    je vien de réaliser ce montage,j’ai juste un petit problême a la fin du décompte l’affichage reviens a welcome.ont a juste le temps de voir la ligne pour relancer le programme.

    cordialement

    Paul

  • By paul - Reply

    Bonjour

    Problème résolu par la mise en place de poussoirs liniature a la place de modeles plus gros !
    cordialement

  • By masoud - Reply

    hi i am iranian
    thanks for it circuit

  • By Pepe Gonzaez - Reply

    Dear Sir:

    I just build this project, but your C code counts HH:MM, what I have to do to change it to count MM:SS

    Thanks

  • By Raj - Reply

    Dear all,
    I want to make an event detection timer using 16 MHZ external crytal and atmega32 microcontroller which will be able to calculate the event difference between two port in nano second range. Please help me.

  • By Emil - Reply

    Hi!
    I have the same problem like “pepe gonzaes”: i want to use this countdown timer for a UV exposure unit PCB and I need Minute:Seconds.
    If you can put a HEX for this it will be great (and appreciated!)
    tnx!

  • Pingback: universal auto matic relay circuit to disconnect charger from supply in ful charging

  • By kostas - Reply

    Dear avinash,
    Thank you very much for sharing such working projects!!! i really love your tutorials … always helping me to learn manipulating avrs!! I would like to ask you what the function of the myutils.h file and if the lcd.c and lcd.h files are written by you or are libraries for driving lcd’s?
    thank you very much in regards!

  • By Riey - Reply

    This relay timer only could work with 16Mhz External Crystal, cannot lower or higher, or will not exactly match with the clock.
    Attention for the fusebit, Can set with AVRIOSP Software.
    I suggest you better make it with CMOS IC Such as 74HC595 or 74LS164.
    Keep Posting for the next an amazing project…

  • By handrianto - Reply

    thank for you aplication

    mr i have problem with this project because when i compile this program in code vision evaluation there is error in this part
    void Wait(uint8_t n)
    {

    uint8_t i,temp;
    temp=n*28;

    for(i=0;i<temp;i++)
    _delay_loop_2(0);
    }

    in this part VOID WAIT ( UINT8_T N )
    is declration syntax error

    tanks for u kindness

  • By handrianto - Reply

    thank for you aplication

    mr i have problem with this project because when i compile this program in code vision evaluation there is error in this part

    in this part VOID WAIT ( UINT8_T N )
    is declration syntax error

    tanks for u kindness

    • By Avinash - Reply

      @Handrianto,

      because you forget to read this instruction

      “Use avr-gcc + AVR Studio to compile.”\

      Its there in the program itself.

      Please I don’t like careless peoples making mistakes and eating my time !

  • By handrianto - Reply

    i very apriciate to your project
    i will try it for my student

  • By Rajeev - Reply

    Can you plese publish a clock with a light control to On/Off Porch light at every evening (eg. On at 6.30 pm and Off at 10.30 Pm unattended by settin On off time)

  • By Vito - Reply

    Circuit on the breadboard tested at the moment and with two types of relay 5V, works very well.
    Of course, I had to set the fuse as indicated on the site, otherwise it will not work well, he was going too slow.
    I think it should also work with a relay 230V, right?
    Hello.

  • By nishad - Reply

    plz give pcb layout of this pro

  • By Jatin - Reply

    Problem solved Guys !!!
    Was able to recover those IC’s by providing an external crystal support .
    The Project now works PERFECT !!!
    Just as word of precaution
    ALWAYS ..flash the AVR first and then set the Fuse to HIGH:C9 and LOW:FF ….Dont do it the other way round .
    This was the mistake I did …Now i learnt !!
    Thanks for a great project .
    Jatin

    • By Avinash - Reply

      @Jatin,

      You are wrong and confused, you can do it either way. But I don’t have time telling you what wrong you are doing coz it’s just lack of your common sense.

  • By Abdul majeed - Reply

    Hey Avinash I have a problem.
    I am driving a relay from attiny2313 microcontroller through BC546 transistor. When i connect ac appliance eg a bulb and drive the relay then it becomes on then suddely becomes off.But if no ac load is apllied then relya works fine what could be the problem. Should i saprate the ground of mcu from relay driving transistor ground?

  • By omid - Reply

    Hi tanks for you
    very very good
    omid from iran from iran
    goodbay engineering

  • Pingback: IR dálkové ovládání a ?asova? k DSLR Sony | elektro.akceasouteze.cz

  • By André Souza - Reply

    Hello, could you help me set a schedule for a timer cascade that controls 15 ports or more? After that triggers the first, the other will then switch on 3 for 3 seconds. Are you doing this?
    With atmega?

    • By Sandeep - Reply

      Have you found solution for Sequential timer ?

      If yes, please send me details

      Thanking you in advance

  • By manoj - Reply

    sir: i do my final year project ( automatic synchronization)

    can you help me?
    i need program for frequency comparator , counter ,timer program

    in my idea?

    first select timer counter
    set timer t1,
    t2

    next timer mode
    count port
    reg move
    port a t1,t2
    compare reg timer
    if less than port c1 on
    if greater than port c2 on
    if equal port c3 on

  • By Nic - Reply

    Hello
    Can this controller programmed in such way to set the countdown time from a week up to 2 months?

  • By nima - Reply

    Hi thanks for your projects;
    I have a quuestion.
    i want to create a timer that set and get number from keypad.
    i.e set the hour and minute with numbers on keypad.
    please help me!

  • By Ritabrata - Reply

    Hello Avinash,

    The Circuit design and your explanations have been very helpful. However, I, myself not being a programmer would require some additional help if its not of too much trouble to you.
    I require the system to ask the user for a particular time period for which it will stay on and also a time period for which it will stay off. Having entered the time period the system should enter an infinite loop of operation. It will keep being ON for the SET period and remain OFF for the SET period. the time set should not get wiped off at power down.

    I wish to employ this as an airconditioner controller at my place!!

    I would be grateful to you if you could help me out!

  • By andreas ioannides - Reply

    Hello Avinash,how are you , i am andreas ioannides from cyprus , nice to meet you ,,

    i do a project that i find it on the web with dmx and stepper motor ,,

    as i see your project is atmel avr gcc ..

    i need very much your help .. for my project ,,

    can you please find little time to share this project together ,,

    please email me

    best recards

    andreas

  • By Surjit - Reply

    Sir how can give me example on eeprom based timer where the interval valve can be store in eeprom.

  • By Dyra - Reply

    Hello sir, nice to meet you !!!
    is a good project, i’ve tried it and succeeded. only what if the program listing to control with the second, please ……………., thanks a lot

  • By nithin - Reply

    very nice project sir.
    but i have a dought, when the supply is stoped to micro controller then what about the timer it will stop .
    but i want to stop the timer when supply is stoped and continue after supply is given with the time where it stoped so what i should do..
    plz rply me sir..

  • By Vitaliy - Reply

    Hello!
    Executed your project on Atmega16.
    Used the internal generator on 8 MHz
    The select button does not work.
    up and down work fine.
    Please tell me what could be the problem!

  • By Humayun Kobir - Reply

    temp=n*28; can you pls clarify this line?

Leave a Reply

Your email address will not be published. Required fields are marked *


9 + nine =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>