3X4 membrane keypad

General discussion on mikroBasic.
Post Reply
Author
Message
igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

3X4 membrane keypad

#1 Post by igeorge » 12 Aug 2020 23:16

Hello,
I need some help to read a membrane keypad.
I read a lot, but most of them are on C
My CPU it is a PIC18F46K22
Please help.
Thank you
Experience is something you don't get until just after you need it

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#2 Post by hexreader » 12 Aug 2020 23:53

If membrane keyboard is the same thing as 4x4 keyboard (with one row or column unused) then there is an example BASIC program available for PIC18F45K22.

Go to start page - Examples - Extra Boards - Keypad 4x4
Start every day with a smile...... (get it over with) :)

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#3 Post by igeorge » 13 Aug 2020 00:04

Thank you hexreader
I will try it.
Experience is something you don't get until just after you need it

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#4 Post by igeorge » 13 Aug 2020 00:21

I still have a problem hexreader.
my board is EasyPic V7
The chip i use is PIC18F46K22
Unfortunately, D6 light stay always ON and is not from the switch on the board.
I cannot use the soft until i turn that D6 OFF, and believe me i read the data sheet but i do not know what to do.
Any suggestion
Here is the code. It is just a simple RFID reader, and i want to add as secutity a keypad entry.
So RFID card is OK and Keypad code is OK, will open the door.

Code: Select all

program RFID_4620
' receive 16 bytes
' byte00, $02
' byte01, dig0
' byte02, dig1
' byte03, dig2
' byte04, dig3
' byte05, dig4
' byte06, dig5
' byte07, dig6
' byte08, dig7
' byte09, dig8
' byte10, dig9
' byte11, Check sum
' byte12, Check sum
' byte13, $03

include pic_additional_string_library


symbol Clear_Card   = PORTE.0   'Clear store bit

symbol Error       = PORTE.1    'CRC WRONG OR WRONG CARD
symbol Card_Match  = PORTE.0   'Card match
symbol CPU_Led     = PORTE.2      'Flash to show that CPU is OK


dim LCD_RS as sbit at LATB4_bit
dim LCD_EN as sbit at LATB5_bit
dim LCD_D4 as sbit at LATB0_bit
dim LCD_D5 as sbit at LATB1_bit
dim LCD_D6 as sbit at LATB2_bit
dim LCD_D7 as sbit at LATB3_bit
dim LCD_RS_Direction as sbit at TRISB4_bit
dim LCD_EN_Direction as sbit at TRISB5_bit
dim LCD_D4_Direction as sbit at TRISB0_bit
dim LCD_D5_Direction as sbit at TRISB1_bit
dim LCD_D6_Direction as sbit at TRISB2_bit
dim LCD_D7_Direction as sbit at TRISB3_bit

dim data_available as boolean
    cnt,ovlf as byte
    data_rec,data_buf,DATA_EE as byte[16]
    CRC_data, CRC_rec as byte
    cc_500,cc_500L as word
    my_string as string[16]
    dig0,dig1,dig2,dig3,dig4 as byte
dim txt as string[4]
dim OK_Led as byte
dim Card_Storred as byte[16]
dim DataEE1 as byte
dim DataEE2 as byte
dim DataEE3 as byte
dim DataEE4 as byte
dim DataEE5 as byte
dim DataEE6 as byte
dim DataEE7 as byte
dim DataEE8 as byte
dim DataEE9 as byte
dim DataEE10 as byte
dim CRC_error,Wrong_card as byte


sub procedure interrupt
  if PIR1.RCIF = 1 then             ' Uart Interrupt
    if cnt > 16 then cnt = 16 end if  '
    data_buf[cnt] = Uart1_Read
    inc(cnt)
    ovlf = 0
  end if
  if PIR1.TMR2IF = 1 then           ' 1ms interrupt
    PIR1.TMR2IF = 0
    inc(cc_500)
    if inc(ovlf) > 19 then          ' 20ms without receiving data
      if (cnt > 13) and (data_available = false) then ' 14 bytes in buffer
        data_rec[0] = data_buf[0]     ' 02 first byte
        data_rec[1] = data_buf[1]     ' data 0
        data_rec[2] = data_buf[2]     ' data 1
        data_rec[3] = data_buf[3]     ' data 2
        data_rec[4] = data_buf[4]     ' data 3
        data_rec[5] = data_buf[5]     ' data 4
        data_rec[6] = data_buf[6]     ' data 5
        data_rec[7] = data_buf[7]     ' data 6
        data_rec[8] = data_buf[8]     ' data 7
        data_rec[9] = data_buf[9]     ' data 8
        data_rec[10] = data_buf[10]   ' data 9
        data_rec[11] = data_buf[11]   ' CRC byte 0
        data_rec[12] = data_buf[12]   ' CRC byte 1
        data_rec[13] = data_buf[13]   ' 03 last byte
        data_available = true
      end if
      cnt = 0
      ovlf = 0
    end if
  end if
end sub

sub procedure CRC_check
  txt[0] = data_rec[1]
  txt[1] = data_rec[2]
  txt[2] = 0
  CRC_data = Hex2Byte(txt)
  
  txt[0] = data_rec[3]
  txt[1] = data_rec[4]
  txt[2] = 0
  CRC_data = CRC_data xor Hex2Byte(txt)
  
  txt[0] = data_rec[5]
  txt[1] = data_rec[6]
  txt[2] = 0
  CRC_data = CRC_data xor Hex2Byte(txt)
  
  txt[0] = data_rec[7]
  txt[1] = data_rec[8]
  txt[2] = 0
  CRC_data = CRC_data xor Hex2Byte(txt)
  
  txt[0] = data_rec[9]
  txt[1] = data_rec[10]
  txt[2] = 0
  CRC_data = CRC_data xor Hex2Byte(txt)
  
  txt[0] = data_rec[11]
  txt[1] = data_rec[12]
  txt[2] = 0
  CRC_rec = Hex2Byte(txt)
  
  lcd_out(3,1,"CRC Result   =")
  lcd_chr(3,16,txt[0])
  lcd_chr(3,17,txt[1])
end sub

sub procedure Write_ee
  if eeprom_read($10) <> $75 then
    eeprom_write($00,data_rec[1])
    eeprom_write($01,data_rec[2])
    eeprom_write($02,data_rec[3])
    eeprom_write($03,data_rec[4])
    eeprom_write($04,data_rec[5])
    eeprom_write($05,data_rec[6])
    eeprom_write($06,data_rec[7])
    eeprom_write($07,data_rec[8])
    eeprom_write($08,data_rec[9])
    eeprom_write($09,data_rec[10])
    eeprom_write($0A,data_rec[11])
    eeprom_write($0B,data_rec[12])
    eeprom_write($10,$75)
  end if

end sub

sub procedure Card_Compare
  DATA_EE[1]  = eeprom_read($00)
  DATA_EE[2]  = eeprom_read($01)
  DATA_EE[3]  = eeprom_read($02)
  DATA_EE[4]  = eeprom_read($03)
  DATA_EE[5]  = eeprom_read($04)
  DATA_EE[6]  = eeprom_read($05)
  DATA_EE[7]  = eeprom_read($06)
  DATA_EE[8]  = eeprom_read($07)
  DATA_EE[9]  = eeprom_read($08)
  DATA_EE[10] = eeprom_read($09)

  if DATA_EE[1] = data_rec[1] then
    if DATA_EE[2] = data_rec[2] then
      if DATA_EE[3] = data_rec[3] then
        if DATA_EE[4] = data_rec[4] then
          if DATA_EE[5] = data_rec[5] then
            if DATA_EE[6] = data_rec[6] then
              if DATA_EE[7] = data_rec[7] then
                if DATA_EE[8] = data_rec[8] then
                  if DATA_EE[9] = data_rec[9] then
                    if DATA_EE[10] = data_rec[10] then
                      Lcd_Out(4, 1, "     Card Match     ")
                      Card_Match = 1
                      ERROR      = 0
                    end if
                  end if
                end if
              end if
            end if
          end if
        end if
      end if
    end if
  end if
end sub

sub procedure Clear_Card_EE
  eeprom_write($01,$FF)
  eeprom_write($02,$FF)
  eeprom_write($03,$FF)
  eeprom_write($04,$FF)
  eeprom_write($05,$FF)
  eeprom_write($06,$FF)
  eeprom_write($07,$FF)
  eeprom_write($08,$FF)
  eeprom_write($09,$FF)
  eeprom_write($0A,$FF)
  eeprom_write($0B,$FF)
  eeprom_write($0C,$FF)
  eeprom_write($10,$FF)
  while PortE.0 = 1
    nop
  wend
end sub




sub procedure init_uart_TMR2_8_internal ' 8MHz, internal clock
  OSCCON = %01110000   ' Set 8MHz internal clock
  data_available = false
  cnt = 0
  ovlf = 0
  Uart1_Init(9600)
  PIE1.RCIE = 1
  PIE1.TMR2IE = 1
  PR2 = 199                  ' 8MHz internal clock
  T2CON = %01001000          ' prescaler 1, postscaler 10
  TMR2 = 0
  T2CON.TMR2ON = 1           ' start TMR2
  INTCON.6 = 1
  INTCON.7 = 1
end sub


sub procedure init_main
dim datat as byte
  ANSELA = 0
  ANSELB = 0
  ANSELC = 0
  ANSELD = 0
  ANSELE = 0


  TRISE.0 = 0
  TRISE.1 = 0
  TRISE.2 = 0
  PortE.0 = 0
  PortE.1 = 0
  PortE.2 = 0

  PORTD  = 0
  PORTC   = 0


  UART1_Init(9600)            ' Initialise USART communication

  UART2_Init(9600)            ' Initialise USART communication

  Delay_ms(100)

  Lcd_Init()                   ' Initialize Lcd
  Lcd_Cmd(_LCD_CLEAR)          ' Clear display
  Delay_ms(100)                                                      ' Wait for keyboard to finish
  Lcd_Out(1, 1, "     Start!     ")
  Lcd_Cmd(_LCD_CURSOR_OFF)          ' Clear display
  Wrong_card = 0
  CRC_error = 0
  datat = $AC
end sub

sub procedure process_uart
  if data_available = true then

     if (data_rec[0] = $02) and (data_rec[13] = $03) then   'WORKS LIKE THAT
         Card_Match = 0
         Wrong_card = 0
         Lcd_out(4,1,"Must Be = ")
         dataee1  = eeprom_read($0)
         dataee2  = eeprom_read($1)
         dataee3  = eeprom_read($2)
         dataee4  = eeprom_read($3)
         dataee5  = eeprom_read($4)
         dataee6  = eeprom_read($5)
         dataee7  = eeprom_read($6)
         dataee8  = eeprom_read($7)
         dataee9  = eeprom_read($8)
         dataee10 = eeprom_read($9)

         lcd_chr(4,11,dataee1)
         lcd_chr(4,12,dataee2)
         lcd_chr(4,13,dataee3)
         lcd_chr(4,14,dataee4)
         lcd_chr(4,15,dataee5)
         lcd_chr(4,16,dataee6)
         lcd_chr(4,17,dataee7)
         lcd_chr(4,18,dataee8)
         lcd_chr(4,19,dataee9)
         lcd_chr(4,20,dataee10)


         UART1_Write(data_rec[0])
         UART1_Write(data_rec[1])
         UART1_Write(data_rec[2])
         UART1_Write(data_rec[3])
         UART1_Write(data_rec[4])
         UART1_Write(data_rec[5])
         UART1_Write(data_rec[6])
         UART1_Write(data_rec[7])
         UART1_Write(data_rec[8])
         UART1_Write(data_rec[9])
         UART1_Write(data_rec[10])
         UART1_Write(data_rec[11])
         UART1_Write(data_rec[12])
         UART1_Write(data_rec[13])

         delay_ms(300)




         CRC_check()
         if (CRC_data  = CRC_rec) then Lcd_Out(1,19, "OK") CRC_ERROR = 0 Write_EE() Card_Compare() end if
         if (CRC_data <> CRC_rec) then Lcd_Out(1,19, "ER") CRC_ERROR = 1   end if

         Lcd_Out(1,1, "Card#=")
         lcd_chr(1,7,data_rec[1])
         lcd_chr(1,8,data_rec[2])
         lcd_chr(1,9,data_rec[3])
         lcd_chr(1,10,data_rec[4])
         lcd_chr(1,11,data_rec[5])
         lcd_chr(1,12,data_rec[6])
         lcd_chr(1,13,data_rec[7])
         lcd_chr(1,14,data_rec[8])
         lcd_chr(1,15,data_rec[9])
         lcd_chr(1,16,data_rec[10])

         lcd_out(2,1,"CRC Received =")
         lcd_chr(2,16,data_rec[11])
         lcd_chr(2,17,data_rec[12])
     end if
      data_available = false
  end if
end sub

main:
  init_main
  init_uart_TMR2_8_internal
  while true
      if cc_500 > 499 then
         cc_500 = 0
         CPU_Led = not CPU_Led
      end if
    process_uart()

    if Clear_Card = 1 then
      Clear_card_EE()
    end if
    if Card_Match = 0 then Wrong_card = 1 end if
    if ((CRC_error = 1) or (Wrong_card = 1)) then Error = 1 end if
    if ((CRC_error = 0) and (Wrong_card = 0)) then Error = 0 end if

  wend
end.
Experience is something you don't get until just after you need it

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#5 Post by hexreader » 13 Aug 2020 00:50

You can work out for yourself if you want to....

Use the debugger and step through code one line at a time until D6 goes high - see what instruction causes it.

Or if you prefer, I could just tell you why D6 goes high - just ask
Start every day with a smile...... (get it over with) :)

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#6 Post by igeorge » 13 Aug 2020 00:55

Please tell me hexreader.
It drive me crazy, and now i cannot use the keypad.
Please be so kind and tell me.
Thank you
Experience is something you don't get until just after you need it

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#7 Post by hexreader » 13 Aug 2020 01:00

UART 2 transmits on RD6.

Remove the line with "UART2_Init()" in it.

Table-2 of datasheet shows that RD6 is Tx2 in the EUSART column
Start every day with a smile...... (get it over with) :)

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#8 Post by igeorge » 13 Aug 2020 01:05

Which proves that i did not read datasheet properly, and also i did not go through my program in deep.
Thank you 1000 times hexreader.
Experience is something you don't get until just after you need it

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#9 Post by igeorge » 13 Aug 2020 20:41

Thank you very much hexreader.
I works like a charm on my 3X4 membrane keypad.
Experience is something you don't get until just after you need it

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#10 Post by hexreader » 13 Aug 2020 22:04

Glad I could help, it was fun.

If you want further help just ask, though I am limited as I only have demo mikroBASIC and no card-reader of your kind.
Start every day with a smile...... (get it over with) :)

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#11 Post by igeorge » 16 Aug 2020 16:51

Hello hexreader,
I have one more question for you as you know this program.
From where Mikroe come up with the kp value ?
What is the algorithm to find the value ?
Second question is about character # displayed twice in the code for case 12 at start and case 15 at the end.

Code: Select all

    select case kp
      case 12 kp = 35   ' "#"
      default: kp = 48

    case 1
      kp = 49  ' 1
    case 2
      kp = 50  ' 2
    case 3
      kp = 51  ' 3
    case 5
      kp = 52  ' 4
    case 6
      kp = 53  ' 5
    case 7
      kp = 54  ' 6
    case 9
      kp = 55  ' 7
    case 10
      kp = 56  ' 8
    case 11
      kp = 57  ' 9
    case 13
      kp = 42  ' *
    case 14
      kp = 48  ' 0
    case 15
      kp = 35  ' #

    end select
Please help me again to understand if you have a minute.
Using a code which works, but not having a clue how it works it is not a good solution for me.
Mikroe does not explain how they calculate the value of KP.
Thank you
Experience is something you don't get until just after you need it

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#12 Post by hexreader » 16 Aug 2020 17:30

1) Open mikroBASIC IDE
2) select tools - Ascii Chart
3) observe that the grey numbers are the decimal numbers for each ASCII chacter - e.g. '1' is character 49

4) Click on "library manager tab - over to the right
5) Double click on 4x4 keypad library to bring up help
6) select Keypad_Key_Press
7) scroll up to the top of the help page and read the help available
Start every day with a smile...... (get it over with) :)

hexreader
Posts: 1784
Joined: 27 Jun 2010 12:07
Location: England

Re: 3X4 membrane keypad

#13 Post by hexreader » 16 Aug 2020 17:34

Alternatively: within your code - put the cursor anywhere within the word "Keypad_Key_Press" and press f1
Start every day with a smile...... (get it over with) :)

igeorge
Posts: 593
Joined: 28 Dec 2005 09:15

Re: 3X4 membrane keypad

#14 Post by igeorge » 16 Aug 2020 18:06

Thank you for help but does not explain.
Do not bother.
I will try to make a scaner for me and at least i know from where i get the value.
One column high , then scan the rows.
Then next column and so on.
Mikroe works, but i must know how, and i do not have access to their library.
Experience is something you don't get until just after you need it

Post Reply

Return to “mikroBasic General”