Keypad-Based Vehicle Engine Immobilizer
Features …
:: Electrical Schematic ::
:: MikroC Source Code ::
Features …
- Low cost, easy-to-build compact design
- 2-points of circuit immobilization …
- Concealable main circuitry, keypad & relays fully isolated
- 10,000 possible 4-digit codes …
- Code set / quickly changeable via keypad buttons
- Flashing LED when armed …
:: Electrical Schematic ::
:: MikroC Source Code ::
Code:
/*
* PROJECT:
DIY Keypad-based car engine security system ...
Copyright ©2010 Trent Jackson all rights reserved
* MCU:
PIC16F628a @4MHz
*/
// :: Global scope variables :: //
unsigned short scan = 0;
unsigned short userCode[6];
unsigned short user[6];
unsigned short keyDown = 0;
unsigned short active = 1;
unsigned short tmrLED = 0;
unsigned short progMode = 0;
unsigned short codeCorrect = 0;
unsigned short hashPressed = 0;
unsigned short ukeyPointer = 0;
unsigned short Pinattempts = 0;
unsigned short i = 0;
unsigned short j = 0;
unsigned int timeout = 0;
unsigned int tmrIgnit = 0;
// :: Defines :: //
// Keypad rows ...
#define rowA PORTB.F0
#define rowB PORTB.F1
#define rowC PORTB.F2
#define rowD PORTB.F3
// Keypad columns
#define colA PORTB.F4
#define colB PORTB.F5
#define colC PORTB.F6
// LEDs ...
#define LEDa PORTA.F3
#define LEDb PORTB.F7
// Relays
#define relayA PORTA.F0
#define relayB PORTA.F1
// Ignition
#define ignit PORTA.F4
void interrupt()
{
tmrLED++;
tmrIgnit++;
TMR0 = 96;
INTCON = 0x20;
}
void flashLEDa()
{
LEDa = ~LEDa;
}
void flashLEDb()
{
LEDb = ~LEDb;
}
void playValidSND()
{
for (i = 0; i < 5; i++)
{
Sound_Play(2000, 25);
Delay_ms(100);
}
}
void playErrorSND()
{
for (i = 0; i < 5; i++)
{
Sound_Play(250, 50);
Delay_ms(100);
}
}
void rstUser()
{
ukeyPointer = 0;
codeCorrect = 0;
hashPressed = 0;
for (i = 0; i < 5; i++)
{
user[i] = 255;
}
}
unsigned short getKey()
{
/*
:: Multiplex 4x3 keypad function ::
1. Cycle through rows and check for corresponding column being set ...
2. Return the key if col is set (active high)
3. Protocol implementation(s) / limitation(s):
a. No simultaneous key sequences
b. Key detect on release ...
c. Very responsive with zero bounce
*/
switch (scan)
{
case 0: // :: First col (1, 4, 7, *) :: //
// Set cols
colA = 1;
colB = 0;
colC = 0;
// 5mS delay allow port to settle
Delay_ms(5);
// Check for button press ...
if (rowA == 1)
{
return 1;
}
else if (rowB == 1)
{
return 4;
}
else if (rowC == 1)
{
return 7;
}
else if (rowD == 1)
{
return 54;
}
break;
case 1:
// Set cols
colA = 0;
colB = 1;
colC = 0;
// 5mS delay allow port to settle
Delay_ms(5);
// Check for button press ...
if (rowA == 1)
{
return 2;
}
else if (rowB == 1)
{
return 5;
}
else if (rowC == 1)
{
return 8;
}
else if (rowD == 1)
{
return 0;
}
break;
case 2:
// Set cols
colA = 0;
colB = 0;
colC = 1;
// 5mS delay allow port to settle
Delay_ms(5);
// Check for button press ...
if (rowA == 1)
{
return 3;
}
else if (rowB == 1)
{
return 6;
}
else if (rowC == 1)
{
return 9;
}
else if (rowD == 1)
{
return 55;
}
break;
}
// Inc to next col ...
scan ++;
// Reset after last row
if (scan == 3)
{
scan = 0;
}
// Nothing pressed, 255 denotes this
return 255;
}
void main()
{
CMCON = 7; // Disable analog comparators
OPTION_REG = 0x84; // Assign prescaler to TMR0
TMR0 = 96; // Timer0 initial value
INTCON = 0xA0; // Enable TMRO interrupt
TRISA = 0x10; // PortA as output ...
PORTA = 0x00; // Init port, all pins low
TRISB = 0x0F; // 4 inputs & 4 outputs
// Using snd lib for short beep on key press
Sound_Init(&PORTA, 2);
// Leds both off
LEDa = 0;
LEDb = 0;
// Relays off
relayA = 0;
relayB = 0;
// Cols off ...
colA = 0;
colB = 0;
colC = 0;
// Null user vars
rstUser();
// Fetch 4-digit code from EEPROM
for (i = 0; i < 4; i++)
{
Delay_ms(50);
userCode[i] = EEPROM_Read(i);
}
// Load default code
if(userCode[0] == 0xFF)
{
userCode[0] = 1;
userCode[1] = 2;
userCode[2] = 4;
userCode[3] = 8;
}
// :: Infinite program loop :: //
while(1)
{
// :: Armed flash red deterrent led @~2Hz :: //
if (pinAttempts < 3)
{
if (active == 1)
{
if (tmrLED >= 100)
{
flashLEDa();
tmrLED = 0;
}
}
else // Not armed
{
if (progMode == 1)
{
if (tmrLED >= 100)
{
flashLEDb();
tmrLED = 0;
}
}
else if (ignit == 1)
{
LEDb = 1;
relayA = 1;
relayB = 1;
tmrIgnit = 0;
}
else // Grn led + rlys off when no ignition
{
if (tmrIgnit == 1000)
{
LEDb = 0;
relayA = 0;
relayB = 0;
tmrIgnit = 0;
}
}
}
// :: Fetch keys :: //
if (keyDown != 1)
{
user[ukeyPointer] = getKey();
if(user[ukeyPointer] != 255)
{
// Flag set ...
keyDown = 1;
// Play tone
Sound_Play(888, 25);
// 50mS debounce
Delay_ms(50);
// Inc pos in array
ukeyPointer++;
// Reset after 5 keys
if (ukeyPointer == 5)
{
ukeyPointer = 0;
}
}
}
else // Wait for key release
{
if (rowA == 0)
{
if (rowB == 0)
{
if (rowC == 0)
{
if (rowD == 0)
{
// Flag off ...
keyDown = 0;
}
}
}
}
}
// :: See if user has entered in the right pin :: //
if(user[0] == userCode[0])
{
if(user[1] == userCode[1])
{
if(user[2] == userCode[2])
{
if(user[3] == userCode[3])
{
codeCorrect = 1;
pinAttempts = 0;
}
}
}
}
// :: Detect if hash key has been pressed :: //
for (i = 0; i < 5; i++)
{
if (user[i] == 55)
{
hashPressed = 1;
break;
}
}
// :: Hash to arm / disarm system :: //
if (progMode == 0)
{
if (hashPressed == 1)
{
if (active == 1)
{
if (codeCorrect == 1)
{
LEDa = 0;
active = 0;
playValidSND();
}
else
{
playErrorSND();
pinAttempts ++;
}
}
else // ARM if vehicle ignition is off
{
if (ignit != 1)
{
LEDb = 0;
active = 1;
relayA = 0;
relayB = 0;
}
}
rstUser();
}
// :: Star key after entering in pin to set new pin :: //
else if (user[4] == 54)
{
if (codeCorrect == 1)
{
if (active == 0)
{
if (ignit == 1)
{
progMode = 1;
}
}
}
else
{
pinAttempts ++;
}
rstUser();
}
}
else // :: User is programming in an new pin code :: //
{
if (ukeyPointer == 4)
{
// Save code to eeprom ...
for (i = 0; i < 4; i++)
{
userCode[i] = user[i];
EEPROM_Write(i, userCode[i]);
Delay_ms(20);
}
// Reset & bail
progMode = 0;
rstUser();
}
}
}
else // 3 incorrect pin attempts in a row (lock out system for a few mins)
{
if (timeout == 0)
{
LEDa = 0;
LEDb = 0;
}
if (timeout < 50)
{
playErrorSND();
flashLEDa();
flashLEDb();
timeout ++;
}
else
{
timeout = 0;
pinAttempts = 0;
LEDa = 0;
LEDb = 0;
}
}
}
}