• Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
Resource icon

Keypad-Based Vehicle Engine Immobilizer 2015-04-19

Keypad-Based Vehicle Engine Immobilizer

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;
         }
      }
   }
}
Likes: faysalcng
Author
MCU88
First release
Last update
Rating
0.00 star(s) 0 ratings

More resources from MCU88

Latest threads

EE World Online Articles

Loading

 
Top