//CORNELL ECE 476 Project //Home Security System //Chun-Pai Jimmy Hsieh & Yang Cao /* Port Detail A0 - Temp sensor analog input A1 - Motion sensor analog input A2 - Smoke detector analog input A3 - Magnetic contact analog input - A4 - Status LED (GREEN if system enabled) A5 - Status LED (blinking RED if something wrong) A6 - PLAYL output for SD1420 chip output A7 - Buzz Speaker Output B0 .. B7 - Address bit for SD1420 chip C0 .. C7 - LCD connection D1 .. D7 - Keypad connection */ #include #include #include #include //timeout values for each task #define t1 100 //task_maneticSwitch #define t2 120 //task_keypad #define t3 250 //task_led #define t4 200 //task_voice #define t5 200 //task_lcd #define t6 1 //task_buzz //LCD stuff #define LCDwidth 16 //characters /* Use an 1x16 alphanumeric LCD connected to PORTC as follows: [LCD] [Mega32 pin] 1 GND- GND 2 +5V- VCC 3 VLC 10k trimpot wiper (trimpot ends go to +5 and gnd) 4 RS - PC0 5 RD - PC1 6 EN - PC2 11 D4 - PC4 12 D5 - PC5 13 D6 - PC6 14 D7 - PC7 */ #asm .equ __lcd_port=0x15 #endasm #include // LCD driver routines //functions void initialize(void); void task_magneticSwitch(void); void task_keypad(void); void getKey(void); char mapKey(int myNum); void task_led(void); void task_lcd(void); void task_voice(void); void task_buzz(void); //variables unsigned char time1, time2, time3, time4, time5, time6; signed char securityEnabled, tempEnabled, motionEnabled, smokeEnabled, magneticEnabled; char tempError, motionError, smokeError, magneticError; char voiceEnabled, buzzEnabled; char securityCode[4]; char tempCode[4]; char adc_ch, currMenu, currKey, numDigEntered, desireTemp; char voiceStage, voiceSayError, voiceStage5Sec, secBeforeVoice, secBeforeVoiceC; char buzzFreq, buzzSkim; char currTemp; //keypad char butnum, key, prvbutnum; char lcd_buffer[5]; // LCD display buffer flash unsigned char keytbl[16]={0xee, 0xde, 0xbe, 0x7e, 0xed, 0xdd, 0xbd, 0x7d, 0xeb, 0xdb, 0xbb, 0x7b, 0xe7, 0xd7, 0xb7, 0x77}; int i; int buzzCounter; int currMotion; //********************************************************** //timer 0 compare ISR interrupt [TIM0_COMP] void timer0_compare(void) { //Executed every 0.001 second if (time1>0) --time1; if (time2>0) --time2; if (time3>0) --time3; if (time4>0) --time4; if (time5>0) --time5; if (time6>0) {--time6; buzzCounter ++; if(buzzCounter == 8000) buzzCounter = 0;} } //********************************************************** //timer 1 compare ISR interrupt [TIM1_COMPA] void timer1_compa_isr(void) { OCR1A = OCR1A + 31250; if(voiceStage5Sec == 0) { PORTA.6 = 1; delay_ms(10); } if(voiceSayError == 1 && securityEnabled == 1) { //user get to choose how long before the voice alarms go off after any sensor triggered if(secBeforeVoiceC != 0) { secBeforeVoiceC--; return; } //Temp sensor goes off if(voiceStage == 1) { voiceStage++; if(tempError == 1) { PORTB = 0x00; delay_ms(10); PORTA.6 = 0; return; } } //motion sensor goes off if(voiceStage == 2) { voiceStage++; if(motionError == 1) { PORTB = 0x10; delay_ms(10); PORTA.6 = 0; return; } } //smoke sensor goes off if(voiceStage == 3) { voiceStage++; if(smokeError == 1) { PORTB = 0x20; delay_ms(10); PORTA.6 = 0; return; } } //door or window opened if(voiceStage == 4) { voiceStage++; if(magneticError == 1) { PORTB = 0x30; delay_ms(10); PORTA.6 = 0; return; } } if(voiceStage == 5) { if(voiceStage5Sec == 0) { PORTB = 0x40; delay_ms(10); PORTA.6 = 0; } voiceStage5Sec++; } if(voiceStage5Sec == 4) { PORTA.6 = 1; voiceStage = 1; voiceStage5Sec = 0; } } } //********************************************************** //ADC input ISR interrupt [ADC_INT] void adc_isr(void) { unsigned int adc_data; adc_data = ADCW; if(adc_ch == 0xC0) //temp sensor { currTemp = adc_data*0.125; /* AREF = internal 2.56V 0.020V for 1 degree F after 2x op-amp output 0V = -50 degree F 1 bit in ADC = 2.56/1024 = 0.0025V 0.0025/0.020 = 0.125 degree F per 1 bit */ if(tempEnabled == 1) { if(currTemp > desireTemp) tempError = 1; else tempError = 0 | tempError; } else tempError = 0; ADMUX = 0xC1; } if(adc_ch == 0xC1) //motion sensor { currMotion = adc_data; if(motionEnabled == 1) { if(adc_data > 250) motionError = 1; else motionError = 0 | motionError; } else motionError = 0; ADMUX = 0xC2; } if(adc_ch == 0xC2) //smoke detector { if(smokeEnabled == 1) { if(adc_data > 500) smokeError = 1; else smokeError = 0 | smokeError; } else smokeError = 0; ADMUX = 0xC0; ADMUX = ADMUX | 0x40; } adc_ch = ADMUX; ADCSRA = ADCSRA | 0x40; } //********************************************************** //Magnetic Contact Switch Detection void task_magneticSwitch(void) { if(magneticEnabled == 1) { if(PINA.3 != 0) magneticError = 1; else magneticError = 0 | magneticError; } else magneticError = 0; } //*********************************************** //update LCD screen void task_lcd(void) { time5 = t5; if(securityEnabled == 1) { if(tempError == 1 || motionError == 1 || smokeError == 1|| magneticError == 1) { lcd_clear(); lcd_gotoxy(0,0); lcd_putsf(" WARNING! "); lcd_gotoxy(0,1); if(tempError == 1) //temp error { lcd_gotoxy(0,1); lcd_putsf("T"); } if(motionError == 1) //motion error { lcd_gotoxy(2,1); lcd_putsf("M"); } if(smokeError == 1) //smoke error { lcd_gotoxy(4,1); lcd_putsf("S"); } if(magneticError == 1) //magnetic error { lcd_gotoxy(6,1); lcd_putsf("D"); } lcd_gotoxy(8,1); lcd_putsf("CODE"); for(i=0; i 4000 || //beeps every sec buzzSkim == 4 && buzzCounter < 2000) //beeps every 3 sec PORTA.7 = !PORTA.7; else PORTA.7 = 0; } } else PORTA.7 = 0; } //*********************************************** //track and keypad and take action void task_keypad(void) { time2 = t2; if(securityEnabled == 1) { getKey(); if(butnum != 0) { if(mapKey(butnum) == 'S') { if(numDigEntered > 0) numDigEntered--; else return; } else { tempCode[numDigEntered] = mapKey(butnum); numDigEntered++; } } if(numDigEntered == 4) { if(tempCode[0] == securityCode[0] && tempCode[1] == securityCode[1] && tempCode[2] == securityCode[2] && tempCode[3] == securityCode[3]) { securityEnabled = 0; tempError = 0; motionError = 0; smokeError = 0; magneticError = 0; currMenu = 0; voiceSayError = 0; voiceStage = 0; PORTA.6 = 1; } numDigEntered = 0; } return; } if(securityEnabled == -1) //new pswd enter mode { getKey(); if(butnum != 0) { if(mapKey(butnum) == 'S') { if(numDigEntered > 0) numDigEntered--; else return; } else { securityCode[numDigEntered] = mapKey(butnum); numDigEntered++; } } if(numDigEntered == 4) { securityEnabled = 0; currMenu = 0; numDigEntered = 0; } return; } if(securityEnabled == 0) { if(currMenu == 0) { getKey(); currKey = mapKey(butnum); if(currKey == 'U') currMenu = 12; if(currKey == 'D') currMenu = 1; return; } if(currMenu == 1) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { securityEnabled = 1; tempError = 0; motionError = 0; smokeError = 0; magneticError = 0; voiceStage = 1; voiceStage5Sec = 0; secBeforeVoiceC = secBeforeVoice; } if(currKey == 'U') currMenu = 12; if(currKey == 'D') currMenu = 2; return; } if(currMenu == 2) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(tempEnabled == 0) tempEnabled = 1; else tempEnabled = 0; } if(currKey == 'U') currMenu = 1; if(currKey == 'D') currMenu = 3; return; } if(currMenu == 3) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(motionEnabled == 0) motionEnabled = 1; else motionEnabled = 0; } if(currKey == 'U') currMenu = 2; if(currKey == 'D') currMenu = 4; return; } if(currMenu == 4) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(smokeEnabled == 0) smokeEnabled = 1; else smokeEnabled = 0; } if(currKey == 'U') currMenu = 3; if(currKey == 'D') currMenu = 5; return; } if(currMenu == 5) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(magneticEnabled == 0) magneticEnabled = 1; else magneticEnabled = 0; } if(currKey == 'U') currMenu = 4; if(currKey == 'D') currMenu = 6; return; } if(currMenu == 6) { getKey(); currKey = mapKey(butnum); if(currKey == '*') { if(desireTemp > 70) desireTemp--; } if(currKey == '#') { if(desireTemp < 125) desireTemp++; } if(currKey == 'U') currMenu = 5; if(currKey == 'D') currMenu = 7; return; } if(currMenu == 7) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(voiceEnabled == 0) voiceEnabled = 1; else voiceEnabled = 0; } if(currKey == 'U') currMenu = 6; if(currKey == 'D') currMenu = 8; return; } if(currMenu == 8) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { if(buzzEnabled == 0) buzzEnabled = 1; else buzzEnabled = 0; } if(currKey == 'U') currMenu = 7; if(currKey == 'D') currMenu = 9; return; } if(currMenu == 9) { getKey(); currKey = mapKey(butnum); if(currKey == 'E') { securityEnabled = -1; } if(currKey == 'U') currMenu = 8; if(currKey == 'D') currMenu = 10; return; } if(currMenu == 10) { getKey(); currKey = mapKey(butnum); if(currKey == '*') { if(buzzFreq > 1) buzzFreq--; } if(currKey == '#') { if(buzzFreq < 9) buzzFreq++; } if(currKey == 'U') currMenu = 9; if(currKey == 'D') currMenu = 11; return; } if(currMenu == 11) { getKey(); currKey = mapKey(butnum); if(currKey == '*') { if(buzzSkim > 1) buzzSkim--; } if(currKey == '#') { if(buzzSkim < 4) buzzSkim++; } if(currKey == 'U') currMenu = 10; if(currKey == 'D') currMenu = 12; return; } if(currMenu == 12) { getKey(); currKey = mapKey(butnum); if(currKey == '*') { if(secBeforeVoice > 0) secBeforeVoice--; } if(currKey == '#') { if(secBeforeVoice < 15) secBeforeVoice++; } if(currKey == 'U') currMenu = 11; if(currKey == 'D') currMenu = 1; return; } } } //*********************************************** //decode button pressed void getKey(void) { //get lower nibble DDRD = 0x0f; PORTD = 0xf0; delay_us(5); key = PIND; //get uppwer nibble DDRD = 0xf0; PORTD = 0x0f; delay_us(5); key = key | PIND; //find matching keycode in keytbl if (key != 0xff) //so we got something! { for (butnum=0; butnum<16; butnum++) if(keytbl[butnum] == key) break; if(butnum == 16) butnum = 0; else butnum++; //adjust by one to make range 1-16 } else butnum = 0; //button debounce scheme //if a button is still pressed if(prvbutnum != 0 && butnum != 0) { butnum = 0; return; } //if a button just pressed if(prvbutnum == 0 && butnum != 0) { prvbutnum = butnum; return; } //if a button just released if(prvbutnum != 0 && butnum == 0) { prvbutnum = 0; return; } } char mapKey(int myNum) { switch(myNum) { case 1: return '1'; case 2: return '2'; case 3: return '3'; case 4: return 'U'; case 5: return '4'; case 6: return '5'; case 7: return '6'; case 8: return 'D'; case 9: return '7'; case 10: return '8'; case 11: return '9'; case 12: return 'S'; case 13: return '*'; case 14: return '0'; case 15: return '#'; case 16: return 'E'; default: return '0'; } } //*********************************************** //Usual initialization stuff void initialize(void) { //PORTA: 0-3 input, 4-7 output; DDRA = 0xF0; PORTA = PORTA | 0x40; //PORTB: address output DDRB = 0xff; //all output PORTB = 0x00; //PORTC: LCD //PORTD: keypad DDRD = 0xff; PORTC = 0; //set up timer 0 TIMSK = 0x02; OCR0 = 125; TCCR0=0b00001011; //prescaler 64, clear on match //set up timer 1 TCCR1A = 0x40; TCCR1B = 0x05; TIMSK = TIMSK | 0x10; //init the task timers time1 = t1; time2 = t2; time3 = t3; time4 = t4; time5 = t5; //init ADC ADMUX = 0; ADMUX = ADMUX | 0xC0; adc_ch = 0; ADCSRA = 0xCF; //ADC on, /128, interrupt unmasked, and started //init lcd lcd_init(LCDwidth); //initialize the display lcd_clear(); //clear the display //init variables securityEnabled = 0; tempEnabled = 1; motionEnabled = 0; smokeEnabled = 0; magneticEnabled = 1; tempError = 0; motionError = 0; smokeError = 0; magneticError = 0; voiceEnabled = 1; voiceStage = 1; buzzEnabled = 0; buzzFreq = 7; buzzSkim = 3; buzzCounter = 0; secBeforeVoice = 5; for(i=0; i<4; i++) securityCode[i] = i+0x31; currMenu = 0; voiceSayError = 0; numDigEntered = 0; desireTemp = 80; //crank up the ISRs #asm("sei") } void main(void) { initialize(); while(1) { if(time1 == 0) task_magneticSwitch(); if(time2 == 0) task_keypad(); if(time3 == 0) task_led(); if(time4 == 0) task_voice(); if(time5 == 0) task_lcd(); if(time6 == 0) task_buzz(); } }