Microcontroller based Electronic Lock

Printer-friendly versionPDF version

Microcontroller based Electronic Lock from Priyank Bolia on Vimeo.

/*----------------------------------------------------------------
-------------------------- HEADER FILES --------------------------
-----------------------------------------------------------------*/


#include <avr/io.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/delay.h>

/*----------------------------------------------------------------
------------------- DEFINITIONS ----------------------------------
-----------------------------------------------------------------*/


#define DATA_DDR             DDRA    // ENTER THE PORT WHICH CONTROLS
#define DATA_PORT            PORTA   // THE DATA PINS D0 TO D7


#define CONTROL_DDR          DDRD    // ENTER THE PORT WHICH CONTROLS
#define CONTROL_PORT         PORTD   // THE CONTROL PINS
#define Enable               2       // CoNNECTION OF ENABLE TO PIN OF ABOVE PORT
#define RS                   0       // CoNNECTION OF RegisterSelect TO PIN OF ABOVE PORT
#define RW                   1       // CoNNECTION OF Read/~Write TO PIN OF ABOVE PORT
#define CONTROL_MASK         0X07    // CHANGE THIS VALUE CONSIDERING THE PINS ABOVE AS HIGH

#define KB_PORT_OUT PORTB       //Keypad Port
#define KB_PORT_DDR DDRB        //Data Direction Register
#define KB_PORT_IN PINB         //Keypad Port Pins

#define col1 PB0                //Column1 PortA.0
#define col2 PB1                //Column2 PortA.1
#define col3 PB2                //Column3 PortA.2
#define col4 PB3                //Column4 PortA.3

#define TRUE 1
#define FALSE 0

/*----------------------------------------------------------------
----------------------CONTROL BITS OF LCD ------------------------
-----------------------------------------------------------------*/


#define Set_Enable                   CONTROL_PORT |=_BV(Enable)   // THE MACROS HERE ARE
#define Clear_Enable                 CONTROL_PORT &=~_BV(Enable)  // SELF EXPLANATORY
#define Write_Lcd                    CONTROL_PORT &=~_BV(RW)      //
#define Read_Lcd                     CONTROL_PORT |=_BV(RW)       //
#define Select_InstructionRegister   CONTROL_PORT &=~_BV(RS)      //
#define Select_DataRegister          CONTROL_PORT |=_BV(RS)       //
#define Data_Lcd(b)                  DATA_PORT=b                  //
#define delay(b)                     _delay_ms(b)                 //



/*----------------------------------------------------------------
----------------------FUNCTION DECLARATIONS ----------------------
-----------------------------------------------------------------*/


void Init_Ports(void);    // Initialize Ports, for selecting input output pins in the MCU
void Init_Lcd(void);      // Initialize LCD,   for starting and clearing LCD screen
void Lcd_Send(unsigned char a);// For sending a character to the LCD                
void GotoNextLine(void);       // For printing characters on the next line in the LCD
void GotoFirstLine(void);      // For printing characters on the first line in the LCD
void ClearDisplay(void);       // For clearing LCD
void key_init();
unsigned char get_key();

/*----------------------------------------------------------------
----------------------MAIN FUNCTION-------------------------------
-----------------------------------------------------------------*/

int main()
{
    int len,len1,len2,len3,len4,len5,len6;
    char str1[] = "Welcome Priyank!";         // String to be printed in 1st line
    char str2[] = "Enter PIN: ";              // String to be printed in 2st line
    char str3[] = "This is invalid";          // String to be printed in 1st line
    char str4[] = "PIN, try again.";          // String to be printed in 2nd line
    char str5[] = "Welcome Home!";            // String to be printed in 1st line
    char str6[] = "Have a nice day.";         // String to be printed in 2nd line
    unsigned char keyval;   //A variable

    len1=strlen(str1);
    len2=strlen(str2);
    len3=strlen(str3);
    len4=strlen(str4);
    len5=strlen(str5);
    len6=strlen(str6);

    Init_Ports();                      
    Init_Lcd();
    key_init();                      

    while(1)
    {
        for (len=0;len<len1;len++)    // Printing the first string
            Lcd_Send(str1[len]);

        GotoNextLine();               // Go to new line
   
        for (len=0;len<len2;len++)    // Printing the 2nd string
            Lcd_Send(str2[len]);

        int index = 0;
        unsigned char PIN[4];
        while(index < 4)
        {
            keyval = get_key();
            if(keyval != 'X')
            {
                PIN[index] = keyval;
                Lcd_Send('*');
                index++;
            }
        }
        if(PIN[0] == '1' && PIN[1] == '5' && PIN[2] == '7' && PIN[3] == 'F')
            break;

        ClearDisplay();               // Go to new line
   
        for (len=0;len<len3;len++)    // Printing the first string
            Lcd_Send(str3[len]);

        GotoNextLine();               // Go to new line
   
        for (len=0;len<len4;len++)    // Printing the 2nd string
            Lcd_Send(str4[len]);

        delay(1000);

        ClearDisplay();               // Go to new line
    }

    ClearDisplay();                   // Go to new line

    for (len=0;len<len5;len++)        // Printing the first string
        Lcd_Send(str5[len]);

    GotoNextLine();                   // Go to new line

    for (len=0;len<len6;len++)        // Printing the 2nd string
        Lcd_Send(str6[len]);

    DDRC = 0xFF;  //Key-board port, higher nibble - input, lower nibble - output
    PORTC = 0xFF; //pull-up enabled for higher nibble
}

/*----------------------------------------------------------------
------------------SEND A CHARACTER TO LCD-------------------------
-----------------------------------------------------------------*/

void Lcd_Send(unsigned char a)
{
    Select_DataRegister; // Declares information that follows as data and not instruction
    Write_Lcd;           // Declared information is to be written
    Data_Lcd(a);         // Send the character passed to the function to LCD to write
    Set_Enable;          // Sets enable,
    delay(5);            // and then
    Clear_Enable;        // Clears it,
    delay(5);            // to be ready for next character.
}

/*----------------------------------------------------------------
-----------------FUNCTIONS TO INITIALIZE PORTS--------------------
-----------------------------------------------------------------*/

void Init_Ports(void)
{
    DATA_DDR=0XFF;                //  Setting data port for output
    CONTROL_DDR=CONTROL_MASK;     //   Setting selected pins of control port for output
    CONTROL_PORT&=~(_BV(Enable)|_BV(RS )|_BV(RW)); //   Setting values to 0 at start
}

/*----------------------------------------------------------------
-------------------FUNCTION TO INITIATE LCD ----------------------
-----------------------------------------------------------------*/

void Init_Lcd(void)
{
    char init[10];
    int i;
    init[0] = 0x01;           // Initializes the display
    init[1] = 0x38;           // 8 - Bit Operation, 2 Line Display,5*8 Dot Character Font
    init[2] = 0x0e;           // Turns on display and cursor
    init[3] = 0x06;           // Entry Mode Set
    init[4] = 0x80;           // Sets DDRAM address to beginning of screen

    Select_InstructionRegister;

    Write_Lcd;
    delay(15);

    for(i=0;i<5;i++)
    {
        Data_Lcd(init[i]);
        Set_Enable;
        delay(5);
        Clear_Enable;
        delay(5);
    }
}

/*----------------------------------------------------------------
-------------FUNCTION TO GOTO NEXT LINE IN LCD -------------------
-----------------------------------------------------------------*/

void GotoNextLine(void)
{
    delay(5);
    Select_InstructionRegister;   // Declares information to follow as instruction
    Data_Lcd(0xc0);               // Code to go to next line of LCD
    Set_Enable;                   //  --  Enable cycle  --
    delay(5);                     // |                    |
    Clear_Enable;                 // |                    |  
    delay(5);                     //  --                --
}

/*----------------------------------------------------------------
----------------FUNCTION TO FIRST LINE IN LCD --------------------
-----------------------------------------------------------------*/

void GotoFirstLine(void)
{
    delay(5);
    Select_InstructionRegister;    // Declares information to follow as instruction
    Data_Lcd(0x80);                // Code to go to next line of LCD
    Set_Enable;                    //  --  Enable cycle  --
    delay(5);                      // |                    |
    Clear_Enable;                  // |                    |  
    delay(5);                      //  --                --
}

/*----------------------------------------------------------------
------------------FUNCTION TO CLEAR LCD --------------------------
-----------------------------------------------------------------*/

void ClearDisplay(void)
{
    delay(5);
    Select_InstructionRegister;    // Declares information to follow as instruction
    Data_Lcd(0x01);                // Code to go to next line of LCD
    Set_Enable;                    //  --  Enable cycle  --
    delay(5);                      // |                    |
    Clear_Enable;                  // |                    |  
    delay(5);                      //  --                --
}

void key_init(){
    KB_PORT_DDR = 0x0F;
    KB_PORT_OUT = 0xFF;
    //stop errant interrupts until set up
    cli(); //disable all interrupts
    MCUCR = 0x00;
    TIMSK = 0x00; //timer interrupt sources
}

unsigned char get_key(){
    unsigned  char upperNibble, keyCode, keyPressed, i;
    while(1)
    {
        upperNibble = 0xff;

        for(i=0; i<4; i++)
        {
            delay(1);
            KB_PORT_OUT = ~(0x01 << i);
            delay(1); //delay for port o/p settling
            upperNibble = KB_PORT_IN | 0x0f;

            if (upperNibble != 0xff)
            {
                delay(20); //key debouncing delay
                upperNibble = KB_PORT_IN | 0x0f;
                if(upperNibble == 0xff) goto OUT;

                keyCode = (upperNibble & 0xf0) | (0x0f & ~(0x01 << i));

                while (upperNibble != 0xff)
                upperNibble = KB_PORT_IN | 0x0f;

                delay(20); //key debouncing delay

                switch (keyCode) //generating key character to display on LCD
                {
                    case (0xee): keyPressed = '0';
                    break;
                    case (0xde): keyPressed = '1';
                    break;
                    case (0xbe): keyPressed = '2';
                    break;
                    case (0x7e): keyPressed = '3';
                    break;
                    case (0xed): keyPressed = '4';
                    break;
                    case (0xdd): keyPressed = '5';
                    break;
                    case (0xbd): keyPressed = '6';
                    break;
                    case (0x7d): keyPressed = '7';
                    break;
                    case (0xeb): keyPressed = '8';
                    break;
                    case (0xdb): keyPressed = '9';
                    break;
                    case (0xbb): keyPressed = 'A';
                    break;
                    case (0x7b): keyPressed = 'B';
                    break;
                    case (0xe7): keyPressed = 'C';
                    break;
                    case (0xd7): keyPressed = 'D';
                    break;
                    case (0xb7): keyPressed = 'E';
                    break;
                    case (0x77): keyPressed = 'F';
                    break;
                    default : keyPressed = 'X';
                }//end of switch

                return keyPressed;

                OUT:;
            }//end of if
        }//end of for
    }//end of while(1)
}

This code is based on the examples at:

No votes yet