Simple Home Security System
Source Code
Source Code
/*
*final project: home security system
*
* Created:
* Author: MD Fahim Anjum
*/
#define F_CPU 8000000UL
#define DS1621 0x90 // device address of DS1621, see data sheet
//defines the data direction (reading from I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_READ 1
//defines the data direction (writing to I2C device) in i2c_start(),i2c_rep_start() */
#define I2C_WRITE 0
#include <avr/io.h>
#include "lcd.h"
#include <avr/interrupt.h>
#include "i2cmaster.h"
#include <util/delay.h>
char testid[4]="3055";
//for ds1621
char TempH;
char TempL;
char T[6];
// for adc
char r [10];// analog
float analog_data;
// for check
char match=1;
//user id and pin
char ID[4];
//flags
char pin=0;
char card=0;
char validc=0;
char validp=0;
char lock=0;
// for keypad
int ID_position=0;
int numb=0;
//for card read
unsigned char next_bit;
unsigned char ch=0x00;
char state=0;
int counter=0;
unsigned char next_state=0;
void ADCinit(void)
{
// AREF = AVcc and select channel 1
ADMUX = (1<<REFS0)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);
// ADC Enable and prescaler of 128
// 8000000/128 = 62500
ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}
uint16_t ADCconvert(void)
{
//Write a one to the status register to start conversion port C0/ ADC0
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC))
{
}
return(ADC);
}
void analog_read(void)
{
uint16_t t ;
double f,temf;
int i;
int tmi;
t =ADCconvert(); // read
f=5*(double)t/1024;//scale adc
//scale for 100%
f=4.6-f;
f=f/4.6*10;
analog_data=f*10;// get data
// record in a string of value of analog data=f
//for rest
for(i=0;i<4;i++){
if(i==2) r[i]='.';
else{
temf=f;
tmi=temf; // get digit
f=f-(double)tmi; // rid digit
f=f*10; // next digit
r[i]=tmi+48;
}
}
r[i]=37; // end
r[i+1]='\0'; // end
}
void check(char *a,char *b, char i){ // checks a and b to i-th element and set match 1(same)/ 0
char j=0;
match=1;
for (j=0;j<i;j++)
if(a[j]!=b[j]) match=0;
}
void Wait1s()
{
//Stop the Timer
char tmp;
TCCR1B = TCCR1B & 0x00;
//Clear Over Flow Flag
TIFR1 = TIFR1 & ~(TOV1);
//Load the count
TCNT1H = 0xff - 0x1e;
TCNT1L = 0xff - 0x84;
//start the timer
TCCR1B = TCCR1B | 0x05;
//While no overflow occuring it keeps looping
do
{
tmp = TIFR1;
tmp = tmp & (1 << TOV1);
} while (!tmp);
}
void wait_10ms()
{
//first stop timer to load prescaler
TCCR2B = TCCR2B & 0x00;
//clear overflow flag
TIFR2 = TIFR2 & ~(TOV1);
//load count
TCNT2 = 0xFF - 0x4E;
//start timer, prescaled by 1024
TCCR2B = TCCR2B | 0x07;
char tmp;
//check overflow flag
do
{
tmp = TIFR2;
tmp = tmp & (1<<TOV2);
} while (!tmp);
}
void wait_5ms()
{
//first stop timer to load prescaler
TCCR2B = TCCR2B & 0x00;
//clear overflow flag
TIFR2 = TIFR2 & ~(TOV1);
//load count
TCNT2 = 0xFF - 0x27;
//start timer, prescaled by 1024
TCCR2B = TCCR2B | 0x07;
char tmp;
//check overflow flag
do
{
tmp = TIFR2;
tmp = tmp & (1<<TOV2);
} while (!tmp);
}
void check_for_button()
{
//Configure Outputs for Pin Pad
DDRB = DDRB | 0x38; //Set B3, B4, B5 as Outputs and set to low voltage
PORTB = PORTB & !(0x38);
//Configure Inputs for Pin Pad
DDRB = DDRB & ~(0x07); //Set B0, B1, B2 as Inputs
PORTB = PORTB | 0x07; //Enable Pull up resistors
DDRD = DDRD & ~(1 << PORTD7); //Set up D7 as input
PORTD = PORTD | (1 << PORTD7); //Enable Pull up resistors on D7
char tmp;
if(ID_position<4 && pin==0){ //check for total input ID
tmp = PINB;
tmp = tmp & 0x01;
if (!tmp) //B0 is pressed
{
pressed(1);
}
tmp = PINB;
tmp = tmp & 0x02;
if (!tmp)
{
//B1 has been pressed
pressed(2);
}
tmp = PINB;
tmp = tmp & 0x04;
if (!tmp)
{
//B2 has been pressed
pressed(3);
}
tmp = PIND;
tmp = tmp & 0x80;
if (!tmp)
{
//D7 has been pressed
pressed(4);
}
wait_10ms();
}
else { //reset after 4 pin read
ID_position=0;
pin=1;
}
}
void pressed(int row)
{
char tmp;
int r=row-1;
r=r*3;
PORTB = PORTB | 0x38;
for(int j = 3; j<6; j++)
{
PORTB = PORTB & ~(1 << j);
switch (row)
{
case 1:
tmp = PINB;
tmp = tmp & 0x01; //B0
if (!tmp)
{
if(DebounPin(0))
{
lcd_putc ( '*' ) ;
numb=(3-j)+ r+3;
if(numb==10) numb=-6;
else if(numb==11) numb=0;
else if(numb==12) numb=-13;
ID[ID_position]=numb+48;
ID_position++;
}
}
break;
case 2:
//Row 2
tmp = PINB;
tmp = tmp & 0x02;
if (!tmp)
{
if (DebounPin(1))
{
lcd_putc ( '*' ) ;
numb=(3-j)+ r+3;
if(numb==10) numb=-6; // 10th key is * so ascii is 42
else if(numb==11) numb=0;// 11th is 0 so acii 48
else if(numb==12) numb=-13;// 12th os # so ascii is 35
ID[ID_position]=numb+48;
ID_position++;
}
}
break;
case 3:
//Row 3
tmp = PINB;
tmp = tmp & 0x04;
if (!tmp)
{
if (DebounPin(2))
{
lcd_putc ( '*' ) ;
numb=(3-j)+ r+3;
if(numb==10) numb=-6;
else if(numb==11) numb=0;
else if(numb==12) numb=-13;
ID[ID_position]=numb+48;
ID_position++;
}
}
break;
case 4:
//Row 4
tmp = PIND;
tmp = tmp & 0x80;
if (!tmp)
{
if (DebounPin(3))
{
lcd_putc ( '*' ) ;
numb=(3-j)+ r+3;
if(numb==10) numb=-6;
else if(numb==11) numb=0;
else if(numb==12) numb=-13;
ID[ID_position]=numb+48;
ID_position++;
}
}
break;
}
PORTB = PORTB | (1 << j); // reset port
}
}
int DebounPin(int c)
{
wait_5ms();
int ifpressed = 0;
char tmp;
switch (c)
{
case 0:
tmp = PINB;
tmp = tmp & 0x01;
if (!tmp)
{
ifpressed = 1;
while (!tmp)
{
tmp = PINB;
tmp = tmp & 0x01;
}
}
break;
case 1:
//Row 2
tmp = PINB;
tmp = tmp & 0x02;
if (!tmp)
{
ifpressed = 1;
while (!tmp)
{
tmp = PINB;
tmp = tmp & 0x02;
}
}
break;
case 2:
//Row 3
tmp = PINB;
tmp = tmp & 0x04;
if (!tmp)
{
ifpressed = 1;
while (!tmp)
{
tmp = PINB;
tmp = tmp & 0x04;
}
}
break;
case 3:
//Row 4
tmp = PIND;
tmp = tmp & 0x80;
if (!tmp)
{
ifpressed= 1;
while (!tmp)
{
tmp = PIND;
tmp = tmp & 0x80;
}
}
break;
}
return ifpressed;
}
int main(void)
{
// i2c
i2c_init(); // initialize I2C library
i2c_start_wait(DS1621+I2C_WRITE); // set device address and write mode 0x90
i2c_write(0xAC); //command config resigter
i2c_write(0x02); // write to config
i2c_rep_start(DS1621+I2C_WRITE); // set device address and write mode 0x90
i2c_write(0xEE); // command write for conversions
i2c_stop();
//adc
ADCinit();
//lcd
lcd_init(LCD_DISP_ON) ;
/*
a:
if(card==0 && pin==0) // Idle condition
{
PORTD=PORTD & ~0x20; // setting PD5 low
*/
lcd_clrscr();
lcd_puts("System active");
//}
while(1)
{
// main part
lcd_clrscr();
if(pin==0) ; //ask pin
else if(pin==1) { pin=0; }
//unlock mode
while(!pin) // check for keypad
{
if(ID_position==0){
//todo: read adc
analog_read();
//todo: read temp
i2c_rep_start(DS1621+I2C_WRITE); // set device address and write mode 0x90
i2c_write(0xAA); // command write for conversions
i2c_rep_start(DS1621+I2C_READ); // set device address and read mode
TempH = i2c_readAck (); // read one byte from EEPROM
TempL=i2c_readNak( );
i2c_stop();
// convert into string
T[1]=TempH%10+48;
T[0]=(TempH-(TempH%10))/10+48;
T[2]='.';
if(TempL) T[3]='5';
else T[3]='0';
T[4]=223;
T[5]='C';
// display
lcd_clrscr();
// display analog
lcd_gotoxy(0,0);
lcd_puts(r); //display value
lcd_puts(" ");// seperator
//display temp
lcd_puts(T); //display value
// display lock /unlock
lcd_gotoxy(0,1); // go to 2nd line
if(lock==0) lcd_puts("UNLOCK "); // lock unlock stts display
else if (lock==1) lcd_puts("LOCKED ");
lcd_puts("PIN:");
//todo: buzz
if((lock==1) && ((analog_data<50)||(TempH>35)) ){ // CONDITIONS for alarm
//light----
PORTC=PORTC | 0x02; // setting Pc0 high
}
if (lock==0) //light----
PORTC=PORTC & 0xFD; // setting Pc0 low
_delay_ms(10); // need this for stable display
}
check_for_button();
}
//check for pin
check(ID,testid,4); // match pin
//display massage
lcd_clrscr();
lcd_puts("PIN Entered:");
lcd_puts(ID); // display entered pin
lcd_gotoxy(0,1); // nesst line
if (match==0) lcd_puts("Wrong PIN !");
else if(match==1) {
lcd_puts("PIN Granted !");
//swap lock
if(lock==0)lock=1;
else if(lock==1)lock=0;
}
pin=0;// may be flag for external add ons in the system ??for now it always 1 after checking keypads
Wait1s();
//
}
}