Arduino AVR alarm clock using ATMEGA328P

 Arduino AVR alarm clock using ATMEGA328P

OBJECTIVE: -

 

In this project, we designed an Arduino based Time Clock with alarm. When we turn on the clock start run because now, we didn’t use any RTC module we hope we will use RTC module later but when we push alarm button then alarm will on, and we can adjust time of clock and alarm clock by respective button. By pressing alarm button, we set alarm and we can select hour and min on which we want set alarm and when clock time match alarm time then whole min buzz will make sound.

PRTEUS SIMULATION





FLOW CHART


·       Sir yet we didn’t use the rtc module I didn’t visit they city when I go there I will pick it up now we are working with simple clock start from 00:00:00 and time goes up

 

Requirements

·       Arduino UNO(ATMEGA328P)

·       16X02 Character LCD Screen

·       Active Buzzer 5V

·       9V Battery and Connector

·       Push Buttons

·       Bread Board

·       Jumper cables

·       Header Pins

·       Resistors

·       IR SENSOR

 

Features

·       Digital Clock displays in Hours, Minutes and Seconds.

·       Alarm Set Mode.

·       Dual key press to Alternate between Alarm set mode/Timer set mode

·       Alarm On/Off Button.

 

 

How it work:-

First, the clock we choose here is 16000000 Hz, dividing it by 1024 gives 10800. So, for every second we get 15625 pulses. So, we are going to start a counter with 1024 pre-scaler to get the counter clock as 10800 Hz. Second, we are going to use the CTC (Clear Timer Counter) mode of ATMEGA. There will be a 16 bit register where we can store a value (compare value), when the counter counts to the compare value an interrupt is set to generate.

 

We are going to set the compare value to 15625, so basically, we will have a ISR (Interrupt Service Routine on every comparison) for every second. So, we are going to use this timely routine to get the clock we needed.

 


TCCRIB

ICNC1

ICES1

-

WGM13

WGM12

CS12

CS12

CS12

 

YELLOW(WGM12): These bits are for selecting (CTC) mode of operation for timer.

 

Now since we want the CTC mode with compare value in OCR1A byte, we just must set WGM12 to one, remaining are left as they are zero by default.

YELLOW (CS10, CS11, CS12): These three bits are for choosing the pre-scalar and so getting appropriate counter clock.


Since we want a 1024 as pre-scaling, we must set both CS12 and CS10.

TCCRIB

ICNC1

ICES1

-

WGM13

WGM12

CS12

CS11

CS10

 

Now there is another register which we should consider:


TIMSK1

-

-

ICE1

-

-

OCIE1B

OCIE1A

TOIE1

 

YELLOW (OCIE1A): This bit must be set for getting an interrupt on compare match between counter value and OCR1A value (15625) which we set.

 

OCR1A value (counter compare value), is written in above register.

How to use

Push buttons increments the time variables. Clicking both HOU,MIN buttons alternate to alarm time setting mode along with making the Alarms status ON. Otherwise ALM is also can be used to change the alarms status without setting up the alarm time.ALM button will on/off the buzzer with the alarm mode.


COMPELETE PROJECT:- GITHUB

SOURCE CODE:-

Main.c


#include <avr/io.h>
#define F_CPU 16000000 
#include <util/delay.h>
#include <stdio.h>
#include <avr/interrupt.h>


void init_lcd(void);
void moveto(unsigned char, unsigned char);
void stringout(char *);
void writecommand(unsigned char);
void writedata(unsigned char);
void writenibble(unsigned char);
ISR(TIMER1_COMPA_vect);

int SEC2 = 5;//allocating integer memory for storing seconds
int SEC1 = 5;
int MIN2 = 0;// allocating integer memory for storing minutes
int MIN1 =0;
int HOU2 =0;// allocating integer memory for storing hours
int HOU1 =0;


int ALMMIN2 = 1;//  storing  alarm minutes
int ALMMIN1 =0;
int ALMHOU2 =0;//  storing alarm hours
int ALMHOU1 =0;

int ALMstatus=0;  // pass 0 or 1 for alarm status   1-> on   0-> off

void displayAlmststus(int ALMstatus); //print the alarm status to the display
void setbuzzer(int MIN1,int MIN2,int HOU1,int HOU2,int ALMMIN1,int ALMMIN2,int ALMHOU1,int AIMHOU2,int ALMstatus); // compare the time value and alarm time


int timer;
int backtime=0;


int main(void) {



init_lcd();
char str[80];
char str1[80];
char ALM[80];

DDRC |=0b00000001; //set output to buzzer

DDRC &= ~(1<<PCINT9);  //set A1 as a  input 

// new add
DDRC &= ~(1<<PCINT10);  //set A2 as a  input
DDRC &= ~(1<<PCINT11);  //set A3 as a  input
DDRC &= ~(1<<PCINT12);  //set A4 as a  input
DDRC &= ~(1<<PCINT13);  //set A4 as a  input   //for the IR senser 

// alarm status button and backlight button

DDRB &= ~(1<<PCINT3);  //set 11 as a  input
DDRB &= ~(1<<PCINT4);  //set 12 as a  input

DDRB |= (1<<PCINT2);  //pin 10 output to the Backlight 




					DDRD |=0b00000100;
					PORTD |=0b00000100;
					_delay_ms(10000);
					

TCCR1B=(1<<WGM12);
OCR1A = 15625;
TIMSK1=(1<<OCIE1A);

sei();

TCCR1B |=(1<<CS12)|(1<<CS10);


sprintf(str1, "IBRAR");
stringout(str1);


_delay_ms(10000);
	
while (1) {               
	
	// Loop forever
	
	moveto(0,0);
	
	sprintf(str, "%d%d:%d%d:%d%d",HOU1,HOU2,MIN1,MIN2,SEC1,SEC2);//send data to display
	stringout(str);
	moveto(0,9);
	sprintf(ALM, "ALM:");
	stringout(ALM);
			
			
			if((PINC & 0x02)== 0x02 ) //If switch is pressed change min of Clock
			
			{			
				MIN2++; 
				
				_delay_ms(3000); 
		
				if (MIN2 == 10)
				{
					MIN2 = 0;
					MIN1= MIN1 + 1;
					
					if (MIN1 == 6)
					{
						MIN1 =0;
						MIN2 =0;
					}
					
				}
				
			}
			
			
			if((PINC & 0x04)== 0x04 ) //If switch is pressed change hou of CLock
			
			{			
				HOU2=HOU2+1;
				
			
				_delay_ms(3000);
			
				
				if (HOU1 ==2 && HOU2 == 4 )
				{
					HOU2 = 0;
					HOU1 = 0;
				
				}
				else {
			
					
					if (HOU2==10)
					{	
						HOU2=0;
						HOU1=HOU1+1;
					}
					
				}
				
				
				
				
			}

			
			// set the alarm mode
			
			if((PINC & 0x02)== 0x02 && (PINC & 0x04)== 0x04 )
			
			{			
				moveto(1,0);
				
				sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
				stringout(str1);
				ALMstatus =1;
					
				_delay_ms(3000);
			}
			
			
				//	IR senser ditect
			
			if((PINC & 0b00100000)== 0b00100000 )
				{
					
					backtime=SEC2;
					if(backtime < 5)
					{
						backtime+5;
					}
					
					if (backtime >= 5)
					{
						backtime-5;
					}
					
					_delay_ms(250);
					PORTB |= (1<<PCINT2); // ON backlight
					_delay_ms(250);
				
				
				}		
			
			
			if((PINC & 0x08)== 0x08 ) //If switch is pressed change ALMmin 
			
			{			
				ALMMIN2++;
				ALMstatus=1;
			
				_delay_ms(3000);
			
				moveto(1,0);
				
				sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
				stringout(str1);
				
				if (ALMMIN2 == 10)
				{
					ALMMIN2 = 0;
					ALMMIN1= ALMMIN1 + 1;
					moveto(1,0);
					
					sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
					stringout(str1);
					
					if (ALMMIN1 == 6)
					{
						ALMMIN1 =0;
						ALMMIN2 =0;
						moveto(1,0);
						
						sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
						stringout(str1);
					}
					
				}
				
			}
			
			
			if((PINC & 0x10)== 0x10 ) //If switch is pressed change ALMHOU
			
			{			
				ALMHOU2++;
				ALMstatus=1;
				
				_delay_ms(3000);
				
				
				moveto(1,0);
				
				sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
				stringout(str1);
				
				if (ALMHOU1 ==2 && ALMHOU2 == 4 )
				{
					ALMHOU2 = 0;
					ALMHOU1 = 0;
					moveto(1,0);
					
					sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
					stringout(str1);
				}
				else {
					
					
					if (ALMHOU2==10)
					{
						ALMHOU2=0;
						ALMHOU1=ALMHOU1+1;
						moveto(1,0);
						
						sprintf(str1, "%d%d:%d%d:ALARM",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
						stringout(str1);
					}
					
				}
				
			}
			
			
				if((PINC & 0x08)== 0x08 && (PINC & 0x10)== 0x10 ) //If switch is pressed backlight on for 5 seconds	
				{		
					//backtime=SEC2;
						if(backtime < 5)
						{
							backtime+5;
						}
						
						if (backtime >= 5)
						{
							backtime-5;
						}
				
						_delay_ms(250);
						PORTB |= (1<<PCINT2); // ON backlight
						//PORTB &= ~(1<<PCINT2); // OFF backlight
					
				
				}
			
			
			
			// check the alarm button status and change the alarm mode 
			
			
				
				_delay_ms(100);
				
				if((PINB & 0x10)== 0x10 ) 			
				{		
					
					if (ALMstatus==0)
					{
						ALMstatus=1;
						
						_delay_ms(3000);
						
						setbuzzer(MIN1,MIN2,HOU1,HOU2,ALMMIN1,ALMMIN2,ALMHOU1,ALMHOU2,ALMstatus);
						
					}
					else
					{
						ALMstatus=0;	
						
						_delay_ms(3000);
						
						setbuzzer(MIN1,MIN2,HOU1,HOU2,ALMMIN1,ALMMIN2,ALMHOU1,ALMHOU2,ALMstatus);
						moveto(1,0);
						
						sprintf(str1, "              ",ALMHOU1,ALMHOU2,ALMMIN1,ALMMIN2);//send ALM data to display
						stringout(str1);
					}
				
					
					
								
				
			
				}  
			
			
			
			
	
	
	
	displayAlmststus(ALMstatus);  // calling the alarm function
	_delay_ms(200);
	moveto(0,14);
	
	setbuzzer(MIN1,MIN2,HOU1,HOU2,ALMMIN1,ALMMIN2,ALMHOU1,ALMHOU2,ALMstatus);
	
   }





    return 0; 
}

ISR(TIMER1_COMPA_vect){    //This is the interrupt request
	SEC2++;
	
	//backlight off session	
	//#################################
	if (SEC2 == backtime )	{
		
			PORTB &= ~(1<<PCINT2); // OFF backlight		
	}
	
	//###############################
		
	if (SEC2 == 10)
	{	
		
		SEC2 = 0;
		
		//backlight off session
		//#################################
		if (SEC2 == backtime )	{
		
			PORTB &= ~(1<<PCINT2); // OFF backlight
			}
		
		SEC1 = SEC1 +1;
			PORTB &= ~(1<<PCINT2); // OFF backlight		
	
		if (SEC1 == 6)
		{	
			SEC2 = 0;
			SEC1 = 0;
			MIN2 = MIN2 +1;
			
			if (MIN2 == 10)
			{	
				MIN2 = 0;
				MIN1= MIN1 + 1;
				
				if (MIN1 == 6)
				{
					MIN1 =0;
					MIN2 =0;
					HOU2 = HOU2 +1;
					
					if (HOU2 ==10 && HOU1 == 1 || HOU1==0)
					{
						HOU2 = 0;
						HOU1 = HOU1 +1;
					}
					else{
						HOU1 =0;
						HOU2 =0;
					}
				}
			}
		}
	} 
}


void displayAlmststus(int ALMstatus){  // print alarm status
	
	char ALM[80];
	
	if(ALMstatus == 0 )
	{	
		moveto(0,13);
		sprintf(ALM, "OFF");
		stringout(ALM);
		
	}
	else
	{	

		moveto(0,13);
		sprintf(ALM, " ON");
		stringout(ALM);
		
		
	}
	
	
}


void setbuzzer(int MIN1,int MIN2,int HOU1,int HOU2,int ALMMIN1,int ALMMIN2,int ALMHOU1,int ALMHOU2,int ALMstatus){
	if(ALMstatus == 1 )
	{
			
			if (MIN1==ALMMIN1 && MIN2==ALMMIN2 && HOU1==ALMHOU1 && HOU2==ALMHOU2)
			{	
		
				PORTC|=0b00000001;
				_delay_ms(1000);
					
				PORTC &= ~(0b00000001);
				_delay_ms(1000);
				
			}
	
	}else{
		
		PORTC&=0b11111110;
			
	}
	
	
	
	
}


/*
  init_lcd - Configure the I/O ports and send the initialization commands
*/
void init_lcd()
{
    /* ??? */                   // Set the DDR register bits for ports B and D
	DDRD|=0xF0;
	DDRB|=0x03;
    _delay_ms(15);              // Delay at least 15ms

	
	writecommand(0x03);
    /* ??? */                   // Use writenibble to send 0011
    _delay_ms(5);               // Delay at least 4msec
	writecommand(0x03);
    /* ??? */                   // Use writenibble to send 0011
    _delay_us(120);             // Delay at least 100usec

    /* ??? */                   // Use writenibble to send 0011, no delay needed
	writecommand(0x03);

	writecommand(0x02);
    /* ??? */                   // Use writenibble to send 0010
    _delay_ms(2);               // Delay at least 2ms
    
    writecommand(0x28);         // Function Set: 4-bit interface, 2 lines
_delay_ms(2);
    writecommand(0x0f);         // Display and cursor on
_delay_ms(25); 

writecommand(0x01); 
_delay_ms(25); 
//writecommand(1);
}

/*
  moveto - Move the cursor to the row (0 or 1) and column (0 to 15) specified
*/
void moveto(unsigned char row, unsigned char col)
{
    
	if(row==0){
		
		writecommand(0x80+col);
	}
	if(row==1){
		
		writecommand(0xc0+col);
	}
	
}

/*
  stringout - Write the string pointed to by "str" at the current position
*/
void stringout(char *str)
{
    
	do{
		
		writedata(*str);
		str++;
		
	}while(*str!= '\0');
	
	
}

/*
  writecommand - Send the 8-bit byte "cmd" to the LCD command register
*/
void writecommand(unsigned char cmd)
{
	unsigned char temp;

PORTB&=~(0x01);
temp=cmd&0xF0;
writenibble(temp);
temp=cmd&0x0F;
temp=temp<<4;
writenibble(temp);
_delay_ms(3);

}

/*
  writedata - Send the 8-bit byte "dat" to the LCD data register
*/
void writedata(unsigned char dat)
{
unsigned char temp;

PORTB|=0x01;
temp=dat&0xF0;
writenibble(temp);
temp=dat&0x0F;
temp=temp<<4;
writenibble(temp);
_delay_ms(3);

}

/*
  writenibble - Send four bits of the byte "lcdbits" to the LCD
*/
void writenibble(unsigned char lcdbits)
{
PORTD = lcdbits;//&0xF0;
//PORTB |= 0x02;
PORTB &= ~(0x02);
PORTB |= 0x02;
PORTB &= ~(0x02);
}


إرسال تعليق

Post a Comment (0)

أحدث أقدم