Thursday, November 22, 2018

Arduino avr alarm clock using atmel studio


Objective


How to Create Digital clock using Atmega328p Microcontroller with an Alarm function




Arduino lcd travel alarm clock



Requirements

  • Arduino UNO
  • 16X02 Character LCD Screen
  • Active Buzzer 5V
  • 9V Battery and Connector
  • Push Buttons
  • Bread Board
  • Jumper cables
  • Header Pins
  • Resistors
In this project you must use the internel timer to create the 1 second delay.Timer1 is a 16BIT.To obtain exactly 1 second delay without flag counting you must used  the Timer Compare mode (CTC).


              OCRn =  [ (clock speed / Pre-scaler value) * Desired time in Seconds ] - 1


above equation  using 16Mhz and 1024 as pre-scaler value oscillator of Arduino UNO, OCR1 register value should be 15624 in decimals.Enabling global interrupts  every 1second  ISR (TIMER1_COMPA_vect) function is triggered.


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


Digital clock using Atmega328p Microcontroller with an Alarm function circuit diagram

Download links for circuit diagram and code are below the page

Code (C Language) With Comments 


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

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, "WELCOME");
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;

}

}

// 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);
}


  //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);
}

}


 //Write the string pointed to by "str" at the current position

void stringout(char *str)
{

do{

writedata(*str);
str++;

}while(*str!= '\0');


}


//  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);

}


 // 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);

}


//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);

}


CODE DOWNLOAD  


CIRCUIT DIAGRAM DOWNLOAD