Introduction:
In our everyday college life, we would rather perform routine tasks with voice activation instead pressing buttons. For example, we would probably want to activate the lights in our apartments via a simple voice command, or answering the phone with a simple voice command. As a result of this, we have decided to design and implement a voice activated alarm clock.
The rationale of our idea is to provide an additional convenience for routine activities that many people have to face every night; that is, setting their alarm clocks! The alarm clock we implement will feature a voice activated alarm setting component. With a simple voice command, the alarm clock will turn on or off the alarm as the user desires.
High Level Design:
When we first attack the project, we have come up with several designs which we think would be applicable for it. For the final design of the clock it consists of the following functions:
- Time in military mode or the normal 12-hour mode
- Alarm setting
- Lights for the ease of seeing the clock at night
- Calendar with automatic day adjustment (30days, 31 days and self adjust for the month of February)
Hardware Design
The hardware we used in the voice recognition alarm clock is as follows:
One of the speaker is connected to PORTB for sound generation by timer0. The other speaker is connected directly to the voice recognition unit.
2 LEDs are connected in parallel and in series with a 10k resistor to ensure proper current and voltage going through them, so the LED do not get too much power and destroy it.
LCD display is connected directly to PORTC, as seen in the schematics page.
2-33pf capacitors is used to connect the 8MHz crystal to the AT90S8515 micro-controller.
We build our own prototype unit that is stand alone and can be displayed on a desktop like a normal clock.
Micro-controller:
The AT90S8515 was chosen for the purposes of our project. We used the 90S8515 because we can utilize the built-in timer1 and timer0 interrupts more than special functions with FLASH memory or any analog to digital conversions. As well, due to the simple structure of our implementation we only utilized C programming in our project.
Timer1 Interrupt:
We used timer1 interrupt to keep track of the time to ensure we have an accurate clock scheme. OCR1A for the timer1 is set to 8000,
which allows it to go into interrupt every 1ms.
We chose 1ms to be our basis point because this gives the easiest prediction of how the state machines will behave in our program. Other variables like minutes, hours, days, etc are all being calculated within the 1ms interrupt time base. In the Timer1 interrupt program, there is a counter where ‘second’ will increment once when the counter equals to 1000. This is because 1000 x 1ms = 1 sec.
The hardware we used in the voice recognition alarm clock is as follows:
- 10 Pushbuttons
- VoiceDirect 364TM speech recognition unit
- 2 Speaker (one for alarm, one for voice recording command)
- 2 LEDs
- 1 LCD display (2x16 characters)
- 1 microphone
- Atmel AT90S8515 micro-controller chip
- 2-33pf capacitors
- 8MHz Crystal
- 1 10kW resistor
One of the speaker is connected to PORTB for sound generation by timer0. The other speaker is connected directly to the voice recognition unit.
2 LEDs are connected in parallel and in series with a 10k resistor to ensure proper current and voltage going through them, so the LED do not get too much power and destroy it.
LCD display is connected directly to PORTC, as seen in the schematics page.
2-33pf capacitors is used to connect the 8MHz crystal to the AT90S8515 micro-controller.
We build our own prototype unit that is stand alone and can be displayed on a desktop like a normal clock.
Software Design
There are two main state machines running at the same time. The first one is to check whether there is a button press and the second one carries out respective function after a button is pressed.
The first state machine (StateMachine) uses the debounce scheme that has been using in previous lab to detect a button press. Debounce scheme is used to avoid the performance of multiple tasks when the button is held for too long. Inside this state machine, when it detects a button press the flag ‘buttonpress’ will become 1. This signal tells state machine two whether a button is being pressed or not.
The second state machine (Operation) synchronizes with the first one by the ‘buttonpress’ flag. It performs instruction only when ‘buttonpress’ is equal to 1. When a function is carried out in state machine two, before exiting ‘buttonpress’ is set back to 0 to avoid a continuous running of the second state machine. The following describes what will happen if different button is pressed.
When Set button is pressed:
The state machine will go to the SetHour state where variable ‘temphour’ is alternated by the increment and decrement button. Also it detects to see whether it is now in 12-Hour mode or 24-Hour mode since different display method for the variable Hour is required. ‘temphour’ is running in a military time bases (0-23), adjustment is made on the variable hour depends on whether it is now in 12-Hour state or 24-Hour state.
The state machine will keep running in the SetHour state unless Set button is pressed. When the set button is pressed, SetMin is the next state and there the variable Minute is alternated. Same criteria as SetHour. The next state will be DaySet, MonthSet, YearSet and WeekSet. Inside these states, they are all using the same mechanism as the one in SetHour. They follow one another and when Set is pressed in the WeekSet state the state machine will jump back to the Release state to wait for next button press.
When Alarm Set is pressed:
The state machine will jump into the AlarmSetHour state. Again the same mechanism is used as SetHour but this time the variable Alarmtemphour is being altered. The next state will beAlarmsetmin. If Set is pressed in the Alarmsetmin state it will jump back to the release state.
When 12HR/24HR is pressed:
The state machine will jump into the HourSwitch. If it is currently in 12HR mode it will change to 24HR mode by doing some calculations on the Hour variable with reference to the ‘temphour’, and vice versa.
When Alarm is pressed:
The state machine will not jump to anywhere but setting the Alarmbutton to 1 if it is currently 0 and vice versa. This indicates the Alarm function that the button is pressed so when time alarm time matches the current time it will buzz. The alarm will not be working at all unless Alarmbutton = 1, even if alarm time equals to the current time.
When Light is pressed:
It switches on and off of the LEDs.
Another function called Alarm is running at the background also. Every interrupts it will check to see if the alarm time is equal to the current time or not. If they are and the alarmbutton = 1, the buzzer is turned on.
The Trigger function is used to keep the voice recognition system in listening mode so that it will provide respective respond if there is a match word.
The AT90S8515 was chosen for the purposes of our project. We used the 90S8515 because we can utilize the built-in timer1 and timer0 interrupts more than special functions with FLASH memory or any analog to digital conversions. As well, due to the simple structure of our implementation we only utilized C programming in our project.
Timer1 Interrupt:
We used timer1 interrupt to keep track of the time to ensure we have an accurate clock scheme. OCR1A for the timer1 is set to 8000,
which allows it to go into interrupt every 1ms.
1ms x 1/(8MHz) = 8000
\OCR1A = 8000
Timer0 Interrupt:
We used timer0 interrupt to generate sound for our alarm, and keep track of how fast the button push state machines are. Similarly, we calibrated timer0 to interrupt every 1ms to allow us to have an easy prediction of how and when the interrupt is set and entered.
Results of the design:
In our final product, we have implemented a light for the user to see the time in the dark. However due to the angle of luminance of the LEDs, it might not be able to light the display fully, hence compromising its function and performance.
The clock is extremely accurate; we have run a real-time test by setting our clock to the time of a computer clock, and leaving it on for several hours. At the end of the trail, there is no lag between our clock and the computer clock.
The usability of the voice recognition hardware proves to be a little complicated. Although, it detects the Recorded Sound under some noisy conditions, it does not work all the time as we have run several trails of test on it. When we were testing the voice recognition unit in the lab, with significant and varying amount of background noise, the unit fails to work almost 85% of the time. However, if we expose the unit just to the noise of the alarm beep, it fails to work only 50% of the time. Now, if we reduce the background noise dramatically, the unit is able to detect voices much more accurately. Due to this problem with the voice recognition unit, we are afraid that the usability of the system might not be very effective.
Another problem we have encountered is the fact that operating modes that are not 100% suitable to our needs. The first mode is recognition of a word after a press of a button. The second mode is the recognition of a word after a keyword is detected. We chose to use the first mode of operation because we would rather speak only one word to the unit and have it detect. The press of a button is activated every time the hardware goes into an interrupt. However, this poses to be a problem because the voice recognition unit would only work under a certain time frame hence not 100% concurrent with the rest of the program. The way we work around the problem is to have a LED which comes on and indicate to the user to speak only when the LED is lit.
//Including the standard file
#include <90S8515.h>
#include <stdio.h>
#include <stdlib.h>
#include <lcd.h>
//Defining constant and states
#define begin {
#define end }
#define LCDwidth 16
#define t1 50
#define t2 15
#define t3 100
#define t4 1
#define t5 200
#define t6 100
#define prescale1
#define clear_on_match
#define Start 1
#define Release 2
#define Maybe 3
#define StillPressed 4
#define DebounceRel 5
#define SetMin 6
#define SetHour 7
#define HourSwitch 8
#define OperationStart 9
#define AlarmSetHour 10
#define AlarmSetMin 11
#define EnterCal 12
#define DaySet 13
#define MonthSet 14
#define YearSet 15
#define WeekSet 16
//Variables that have used
void initialize(void);
void LCD(void);
void StateMachine(void);
void Operation(void);
void clocksetLCD(void);
void alarmLCD(void);
void Alarm(void);
void CurrTime(void);
void Trigger(void);
unsigned char PushState;
unsigned char Function;
unsigned char States;
unsigned char hrFlag;
unsigned char reload;
unsigned char time1;
unsigned char time2;
unsigned char time3;
unsigned char time4;
unsigned char time5;
unsigned char time6;
unsigned char lcd_buffer[17];
unsigned char led;
unsigned char AMFlag;
unsigned char PMFlag;
unsigned char LCDcheck;
unsigned char buttonpress;
unsigned char tempkey;
unsigned char secondcounter;
unsigned char AlarmhrFlag;
unsigned char AlarmAMFlag;
unsigned char AlarmPMFlag;
unsigned char Alarmcounter;
unsigned char OnFlag;
unsigned char Alarmbutton;
unsigned char TriggerCounter;
unsigned int counter;
unsigned int second;
unsigned int minute;
unsigned int hour;
unsigned int temphour;
unsigned int changinghour;
unsigned int settemphour;
unsigned int Alarmhour;
unsigned int Alarmsettempmin;
unsigned int Alarmtemphour;
unsigned int Day;
unsigned int Month;
unsigned int Week;
unsigned int Year;
unsigned int Weekday;
//Assigning PORTC to LCD output
#asm
.equ __lcd_port=0x15
#endasm
//======Timer 0 Interrupt=====================================================
interrupt [TIM0_OVF] void timer0_overflow(void)
begin
TCNT0=reload;
if (time1>0) --time1; //To control the LCD display function
if (time2>0) --time2; //Detect key press and debounce
if (time3>0) --time3; //The major state machine
if (time4>0) --time4; //Alarm time checking
if (time5>0) --time5; //Triggering the listening mode of the voice kit
end
//=============================================================================
//timer 1 compare-match A ISR
interrupt [TIM1_COMPA] void cmpA_overflow(void)
begin
if (counter==1000) //1 second, interrupt every 1ms, 1000 ms=1 sec
begin
if (secondcounter==0) secondcounter=1;
else secondcounter=0;
counter=0;
//--Calender Part------------------------------------------------------------
if ((temphour==23)&&(minute==59)&&(second==59))
begin
Day++; //Incrementing day if it is 00:00:00
Weekday++; //Incrementing day of the week
if (Weekday>7) Weekday=1; //Reseting day of week after Sunday
//Months with 30 days
if (((Month==4)||(Month==6)||(Month==9)||(Month==11))&&(Day>30))
begin
Day=1;
Month++;
end
//Months with 31 days
else if (((Month==1)||(Month==3)||(Month==5)||(Month==7)||(Month==8)||(Month==10)||(Month==12))&&(Day>31))
begin
Day=1;
Month++;
end
else if ((Month==2)&&(Day==30)&&(Year%4==0)) //February with 29 days
begin
Day=1;
Month++;
end
else if ((Month==2)&&(Day==29)&&(Year%4!=0)) //February with 28 days
begin
Day=1;
Month++;
end
if(Month>12) //Resetting month after December
begin
Month=1;
Year++;
end
end
//--Time Part------------------------------------------------------------------------------
if (second < 59) second++; //Incrementing the second
else
begin
second=0; //Resetting second to 0 if second=60
if (minute < 59) minute++; //Incrementing minute
else
begin
if (hrFlag==0) //If it is in 12-HR mode
begin
minute=0;
if (AMFlag==1) //If it is AM
begin
temphour++; //Incrementing hour, temphour is in 24HR mode always
if (temphour==12) //If it is 12:00pm
begin
AMFlag=0;
PMFlag=1;
end
hour=temphour;
end
else if (PMFlag==1) //If is is PM
begin
temphour++;
//Minus 12 from temphour to obtain the time in 12HR mode
if ((temphour>12) && (temphour<24)) hour=temphour-12;
else if (temphour==24) //If it is 12:00am midnight
begin
hour=temphour-12;
temphour=0; //Resetting temphour to 0
AMFlag=1; //Back to AM
PMFlag=0;
end
end
end
if (hrFlag==1) //If it is in 24HR mode
begin
minute=0;
if (temphour == 23) //Resetting temphour if is 12:00 midnight
begin
temphour = 0;
hour=temphour;
end
else
begin
temphour++; //Else increment temphour
hour=temphour;
end
end
end
end
end
else counter++;
end
//===============================================================================================
void main(void)
begin
initialize();
while(1)
begin
if (time1==0)
begin
if (LCDcheck==1) LCD(); //The normal LCD display mode
else if (LCDcheck==2) alarmLCD(); //The alarm setting mode
else clocksetLCD(); //The clock setting mode
end
if (time2==0) StateMachine(); //The detect button press and debounce
if (time3==0) Operation(); //The main state machine
if (time4==0) Alarm(); //Detect if current time = alarm time
if (time5==0) Trigger(); //Triggering the listening mode
//of the voice chip
end
end
//================================================================================================
void StateMachine(void)
begin
time2=t2;
switch (PushState)
begin
case Start:
begin
PushState=Release; //Go to Release state
end
break;
case Release:
begin
buttonpress=0; //No button is pressed
if (PINA!=0xff) //If button is pressed
begin
tempkey=PINA;
PushState=Maybe; //Go to Maybe state
end
else PushState=Release; //Go back to Release state
end
break;
case Maybe:
begin
if (tempkey==PINA) //If the key is still pressing
begin
buttonpress=1; //Confirm button is pressed
PushState=StillPressed; //Go to StillPressed
end
else PushState=Release; //Go to Release state
end
break;
case StillPressed:
begin
if (tempkey==PINA) PushState=StillPressed; //Button still pressed, stay here
else PushState=DebounceRel; //Else go to DebounceRel
end
break;
case DebounceRel:
begin
buttonpress=0;
if (tempkey==PINA) PushState=StillPressed; //Still pressed? Go to StillPressed
else PushState=Release; //Go to Release if button is released
end
break;
end
end
//================================================================================================
void Operation(void)
begin
time3=t3;
if (buttonpress==1) //If button is pressed
begin
if (PINA.6==0) //If the light button is pressed
begin
if (PORTD.2==0) PORTD.2=1; //Turn on the LEDs
else PORTD.2=0; //Turn them off
end
switch (Function)
begin
case OperationStart:
begin
if (buttonpress==1) //If button is pressed
begin
if (PINA.3==0) //If the 12HR/24HR button is pressed
begin
lcd_clear();
CurrTime();
Function=HourSwitch;
end
else if ((PINA.0==0)) //If the Set button is pressed
begin
LCDcheck=0;
CurrTime();
Function=SetHour;
end
else if (PINA.1==0) //If the Alarm Set button is pressed
begin
AlarmhrFlag=hrFlag; //Telling the alarm mode whether it is
//in 12HR or 24HR mode
LCDcheck=2; //Change LCD display mode
CurrTime();
Function=AlarmSetHour;
end
else if ((PINA.4==0)||(PINA.5==0)) //If the Alarm on/off button
//is pressed/ voice is recog.
begin
if (Alarmbutton==0) Alarmbutton=1; //Alram off, turn it on
else if (Alarmbutton==1) //Alarm on, turn it off
begin
CurrTime();
OnFlag=0; //Turn off the alarm
Alarmbutton=0;
end
end
end
else Function=OperationStart; //Go back to OperationStart
end
break;
case HourSwitch: //Changing between 12HR / 24HR
begin
lcd_clear();
CurrTime();
if (hrFlag==0)
begin
hrFlag=1;
if ((temphour>12)||(temphour==0)) hour=temphour;
end
else
begin
hrFlag=0;
if ((temphour>12)&&(temphour<24)) hour=temphour-12;
else if (temphour==0) hour=12;
end
Function=OperationStart;
end
break;
case SetHour: //Time Setting (Hour Setting)
begin
if ((PINA.1==0)) //If the increment button is pressed
begin
if (hrFlag==0) //If it is now in 12HR mode
begin
temphour++; //Increment hour
if (temphour>12) hour=temphour-12;
else hour=temphour;
if (temphour>=12) //If it is now 12:00pm noon
begin
AMFlag=0; //PM
PMFlag=1;
end
else
begin
AMFlag=1; //else AM
PMFlag=0;
end
if (temphour==24) //If it is now 12:00am midnight
begin
temphour=0; //Resetting temphour=0
AMFlag=1; //AM
PMFlag=0;
end
end
else
begin //If it is now in 24HR mode
temphour++;
if (temphour == 24) //Resetting temphour if it is 12:00am
begin
temphour = 0;
hour=0;
end
else hour=temphour;
if(temphour>=12) //If it is now 12:00pm
begin
PMFlag=1; //PM
AMFlag=0;
end
else if (temphour==0) //If it is now 12:00am
begin
PMFlag=0; //AM
AMFlag=1;
end
end
Function=SetHour; //Go back to SetHour
end
else if (PINA.0==0) Function=SetMin; //If Set button is pressed, go to SetMin
else Function=SetHour; //Go to SetHour
end
break;
case SetMin: //Clock setting (Minute set)
begin
if (PINA.1==0) //If increment button is pressed, add minute
begin
minute++;
if (minute > 59) minute=0;
Function=SetMin;
end
else if (PINA.2==0) //If decrement button is pressed, decrement minute
begin
minute--;
if (minute == -1) minute=59;
Function=SetMin;
end
else if (PINA.0==0) //If Set button is pressed, go to DaySet
begin
LCDcheck=1;
Function=DaySet;
end
else Function=SetMin;
end
break;
case DaySet: //Calender, setting the day of month
begin
if (PINA.1==0) //If increment button is pressed, increment Day
begin
Day++;
if (Day>31) Day=1;
end
else if (PINA.2==0) //If decrement button is pressed, decrement Day
begin
Day--;
if (Day<1) Day=31;
end
else if (PINA.0==0) //If Set button is pressed, go to MonthSet
begin
LCDcheck=1;
lcd_clear();
CurrTime();
Function=MonthSet;
end
else Function=DaySet; //Go to DaySet
end
break;
case MonthSet: //Calender, setting the month of the year
begin
if (PINA.1==0) //Incrememnt Month when increment button is pressed
begin
Month++;
if (Month>12) Month=1;
end
else if (PINA.0==0) Function=YearSet; //If pressed Set, go to YearSet
else Function=MonthSet;
end
break;
case YearSet: //Calender, setting the year
begin
if (PINA.1==0) Year++; //Increment year if increment button is pressed
else if (PINA.2==0) Year--; //Decrement year if decrement button is pressed
else if (PINA.0==0) //Go to WeekSet if Set button is pressed
begin
LCDcheck=1;
lcd_clear();
CurrTime();
Function=WeekSet;
end
else Function=YearSet;
end
break;
case WeekSet: //Calender, setting day of the week
begin
if (PINA.1==0) //Increment day of the week if increment button is pressed
begin
Weekday++;
if (Weekday>7) Weekday=1;
end
else if (PINA.2==0) //Decrement day of the week if decrement button is pressed
begin
Weekday--;
if (Weekday<1) Weekday=7;
end
else if (PINA.0==0) //Go to OperationStart if Set is pressed
begin
LCDcheck=1;
lcd_clear();
CurrTime();
Function=OperationStart;
end
else Function=WeekSet; //Go to WeekSet
end
break;
//===================================================================================
//Alarm setting part, it works basically the same as SetHour and SetMin
case AlarmSetHour: //Setting Alarm hour
begin
if ((PINA.1==0)) //If increment button is pressed
begin
if (AlarmhrFlag==0) //If it is in 12HR mode
begin
Alarmtemphour++;
if (Alarmtemphour>12) Alarmhour=Alarmtemphour-12;
else Alarmhour=Alarmtemphour;
if (Alarmtemphour>=12)
begin
AlarmAMFlag=0;
AlarmPMFlag=1;
end
else
begin
AlarmAMFlag=1;
AlarmPMFlag=0;
end
if (Alarmtemphour==24)
begin
Alarmtemphour=0;
AlarmAMFlag=1;
AlarmPMFlag=0;
end
end
else
begin //If it is in 24HR mode
Alarmtemphour++;
if (Alarmtemphour == 24)
begin
Alarmtemphour = 0;
Alarmhour=0;
end
else Alarmhour=Alarmtemphour;
if(Alarmtemphour>=12)
begin
AlarmPMFlag=1;
AlarmAMFlag=0;
end
else if (Alarmtemphour==0)
begin
AlarmPMFlag=0;
AlarmAMFlag=1;
end
end
Function=AlarmSetHour;
end
else if (PINA.0==0) Function=AlarmSetMin; //Go to AlarmSetMin
else Function=AlarmSetHour; //Go to AlarmSetHour
end
break;
case AlarmSetMin: //Setting the Alarm minute
begin
if ((PINA.1==0)) //Increment minute if increment is pressed
begin
Alarmsettempmin++;
if (Alarmsettempmin > 59) Alarmsettempmin=0;
end
else if ((PINA.2==0)) //Decrement minute if decrement is pressed
begin
Alarmsettempmin--;
if (Alarmsettempmin == -1) Alarmsettempmin=59;
end
else if ((PINA.0==0)) //Go to OperationStart if Set button is pressed
begin
LCDcheck=1;
lcd_clear();
CurrTime();
Function=OperationStart;
end
else Function=AlarmSetMin;
end
break;
end
end
if (Function==HourSwitch) buttonpress=1;
else buttonpress=0; //This forces the statemachine to stop running unless a button is pressed
//as buttonpress is set to 1 in StateMachine
end
//================================================================================================
//=================================================================================================
void CurrTime(void) //Outputting the Month, Day of the week.
//Outputting the format of Day, Month, Year and Day of the month if in
//setting mode
begin
lcd_clear();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%01d",Day);
lcd_puts(lcd_buffer);
lcd_gotoxy(3,0);
if (Month==1) lcd_putsf("Jan");
if (Month==2) lcd_putsf("Feb");
if (Month==3) lcd_putsf("Mar");
if (Month==4) lcd_putsf("Apr");
if (Month==5) lcd_putsf("May");
if (Month==6) lcd_putsf("Jun");
if (Month==7) lcd_putsf("Jul");
if (Month==8) lcd_putsf("Aug");
if (Month==9) lcd_putsf("Sep");
if (Month==10) lcd_putsf("Oct");
if (Month==11) lcd_putsf("Nov");
if (Month==12) lcd_putsf("Dec");
lcd_gotoxy(7,0);
sprintf(lcd_buffer,"%01d",Year);
lcd_puts(lcd_buffer);
lcd_gotoxy(12,0);
if (Weekday==1) lcd_putsf("Mon");
if (Weekday==2) lcd_putsf("Tue");
if (Weekday==3) lcd_putsf("Wed");
if (Weekday==4) lcd_putsf("Thr");
if (Weekday==5) lcd_putsf("Fri");
if (Weekday==6) lcd_putsf("Sat");
if (Weekday==7) lcd_putsf("Sun");
if ((Function==DaySet)||(Function==MonthSet)||(Function==YearSet)||(Function==WeekSet))
begin
lcd_gotoxy(0,1);
if (Function==DaySet) lcd_putsf("Day?");
else if (Function==MonthSet) lcd_putsf("Month?");
else if (Function==YearSet) lcd_putsf("Year?");
else if (Function==WeekSet) lcd_putsf("Day of week?");
end
end
//================================================================================================
void LCD(void) //Normal LCD display
begin
time1=t1;
if ((Function==DaySet)||(Function==MonthSet)||(Function==YearSet)||(Function==WeekSet)) CurrTime();
else
begin
CurrTime();
lcd_gotoxy(0,1);
if (hour < 10) //Outputting Hour
begin
sprintf(lcd_buffer,"%02d",hour); //If hour < 10, add a 0 in front
lcd_puts(lcd_buffer);
end
else //If hour > 10, no 0 in front
begin
sprintf(lcd_buffer,"%01d",hour);
lcd_puts(lcd_buffer);
end
lcd_gotoxy(3,1);
if (minute < 10)
begin
sprintf(lcd_buffer,"%02d",minute); //If minute < 10, add a 0 in front
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%1d",minute); //If minute > 10, no 0 in front
lcd_puts(lcd_buffer);
end
lcd_gotoxy(6,1);
if (second < 10)
begin
sprintf(lcd_buffer,"%02d",second); //If second < 10, add a 0 in front
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%01d",second); //If second > 10, no 0 in front
lcd_puts(lcd_buffer);
end
lcd_gotoxy(9,1);
if ((AMFlag == 1) && (hrFlag == 0)) lcd_putsf("AM"); //Output AM/PM/24hr
else if ((PMFlag == 1) && (hrFlag == 0)) lcd_putsf("PM");
else if (hrFlag == 1) lcd_putsf("24hr");
if (Alarmbutton==1) //Output letter A if alarm button is on
begin
lcd_gotoxy(12,1);
lcd_putsf("A");
end
if (secondcounter==0) //Outputting the flashing dots, syncronize with second
begin
lcd_gotoxy(2,1);
lcd_putsf(":");
lcd_gotoxy(5,1);
lcd_putsf(":");
end
else
begin
lcd_gotoxy(2,1);
lcd_putsf(" ");
lcd_gotoxy(5,1);
lcd_putsf(" ");
end
end
end
//=================================================================================================
void clocksetLCD(void) //LCD format in the clock setting mode
begin
lcd_gotoxy(2,1);
lcd_putsf(":");
lcd_gotoxy(0,0);
if (Function==SetHour) lcd_putsf("Hours ");
else if (Function=SetMin) lcd_putsf("Minutes");
lcd_gotoxy(0,1);
if (hour < 10)
begin
sprintf(lcd_buffer,"%02d",hour);
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%01d",hour);
lcd_puts(lcd_buffer);
end
lcd_gotoxy(3,1);
if (minute < 10)
begin
sprintf(lcd_buffer,"%02d",minute);
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%01d",minute);
lcd_puts(lcd_buffer);
end
lcd_gotoxy(9,1);
if ((AMFlag == 1) && (hrFlag == 0)) lcd_putsf("AM");
else if ((PMFlag == 1) && (hrFlag == 0)) lcd_putsf("PM");
end
//========================================================================================
void alarmLCD(void) //LCD format in Alarm setting mode
begin
lcd_gotoxy(2,1);
lcd_putsf(":");
lcd_gotoxy(0,0);
if (Function==AlarmSetHour) lcd_putsf("Alarm Hours ");
else if (Function=AlarmSetMin) lcd_putsf("Alarm Minutes");
lcd_gotoxy(0,1);
if (Alarmhour < 10)
begin
sprintf(lcd_buffer,"%02d",Alarmhour);
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%01d",Alarmhour);
lcd_puts(lcd_buffer);
end
lcd_gotoxy(3,1);
if (Alarmsettempmin < 10)
begin
sprintf(lcd_buffer,"%02d",Alarmsettempmin);
lcd_puts(lcd_buffer);
end
else
begin
sprintf(lcd_buffer,"%01d",Alarmsettempmin);
lcd_puts(lcd_buffer);
end
lcd_gotoxy(9,1);
if ((AlarmAMFlag == 1) && (AlarmhrFlag == 0)) lcd_putsf("AM");
else if ((AlarmPMFlag == 1) && (AlarmhrFlag == 0)) lcd_putsf("PM");
end
//=====================================================================================================
void Alarm(void) //To see if the Set Alarm time matches with the current time
begin
time4=t4;
if ((Alarmtemphour==temphour)&&(Alarmsettempmin==minute)&&(Alarmbutton==1)) OnFlag=1;
if ((OnFlag==1)) //Turn on the alarm if the OnFlag == 1
begin
PORTB=~PORTB;
lcd_gotoxy(0,0);
lcd_putsf("Sound Alarm ");
end
else PORTB=0xff;
end
//=====================================================================================================
void Trigger(void) //Noticing the voice kit to be in listening mode, the port pin goes on and
//off simultaneously
begin
time5=t5;
if (TriggerCounter<=30)
begin
TriggerCounter++;
PORTD.3=1;
end
else if ((TriggerCounter>30)&&(TriggerCounter<60) )
begin
PORTD.3=0;
TriggerCounter++;
end
else TriggerCounter=0;
end
//====================================================================================================
void initialize(void)
begin
//set up the ports
DDRA=0x00; // PORT A is an input
DDRB=0xff; //PORT B is an output
DDRC=0xff; // PORT C is an ouput
DDRD=0xff;
PORTA=0xff;
PORTB=0;
UBRR = 51;
//================================================================================================
//set up timer 0
//62.5 x (64x.25) microSec = 1.0 mSec, so prescale 64, and count 62 times.
reload=256-62; //value for 1 Msec, we are using 4 MHz clock
TCNT0=reload; //preload timer 1 so that is interrupts after 1 mSec.
TCCR0=3; //prescalar to 64
TIMSK=2; //turn on timer 0 overflow ISR
//================================================================================================
//set up timer 1
TIMSK = TIMSK | 0x40; //turn on timer 1 compare match interrupt
TCCR1B = 9;
OCR1A= 8000;
TCNT1 = 0; //and zero the timer
//==init the task timers============
time1=t1;
time2=t2;
time3=t3;
time4=t4;
time5=t5;
time6=t6;
//==init variables==================
second=45;
minute=0;
hour=12;
temphour=0;
settemphour=0;
changinghour=0;
counter=0;
hrFlag=0;
AMFlag=1;
PMFlag=0;
//==Alarm=============================
AlarmhrFlag=hrFlag;
AlarmAMFlag=1;
AlarmPMFlag=0;
Alarmtemphour=0;
Alarmhour=12;
Alarmsettempmin=0;
Alarmcounter=0;
OnFlag=0;
Alarmbutton=0;
//==Calender============================
Day=1;
Weekday=1;
Month=1;
Year=2000;
//======================================
TriggerCounter=0;
secondcounter=0;
buttonpress=0;
LCDcheck=1;
PushState=Start;
Function=OperationStart;
States=EnterCal;
lcd_init(LCDwidth);
CurrTime();
//crank up the ISRs
#asm
sei
#endasm
end
Schematics:
LCD, Buttons, and MCU schematic
Schematic for VoiceDirectTM 364
Pictures of our final product:
0 comments:
Post a Comment