4x4 Keyboard decoder conversion from serial output to parralel strobed output...

rocketdoc

New Member
Here is the original code someone wrote, and it used the ser out.

I want to change this to a 4 bit output, that I can latch into a 4-bit latch, or another picaxe chip awaiting data from it.

I know I need to change the SERTXD instruction to another table operation, to use C.0 - C.3 outputs, and the C.4 output as a strobe to signal a valid data byte to the receiving component... BUT... I am not sure exactly how to do this without using some really long and inefficient code...

What needs to be changed here to do so, and is this the most efficient use of memory space to do so??
This is a really good learning experience, so I thank you all in advance!!!

The code is as follows -
Code:
**************************************************************************************



#Picaxe 20X2
#Terminal 38400
#No_Data


'
'   I want to change from this:
'
'
'
'.........................20X2
'........................--__--.               
'.......................|+V    0V|   
'.......................|SI    SO|----------------------> TXD        
'.......................|C7    B0|<------------
'.......................|C6    B1|<---------.  |
'.......................|C5    B2|----> * * * *     1x1 through 4x4
'.......................|C4    B3|----> * * * *      Matrix Keypad
'.......................|C3    B4|----> * * * *        No Diodes
'.......................|C2    B5|----> * * * *      No Resistors   
'.......................|C1    B6|<-----'   |
'.......................|C0    B7|<--------'
'......................`------'
'
'
'
'  To THIS:
'
'
'........................20X2
'........................--__--.               
'.......................|+V    0V|   
'.......................|SI    SO|        
'.......................|C7    B0|<-----------.
'.......................|C6    B1|<---------.   |
'.......................|C5    B2|----> * * * *     1x1 through 4x4
'...Data Valid<== |C4    B3|----> * * * *      Matrix Keypad
'.............B3<== |C3    B4|----> * * * *        No Diodes
'.............B2<== |C2    B5|----> * * * *      No Resistors   
'.............B1<== |C1    B6|<-----'  |
'.............B0<== |C0    B7|<-------'
'......................`------'
'
'
'
'

Symbol DIR_X        = %00111100
Symbol MSK_X        = %11000011
Symbol XOR_X        = MSK_X 

Symbol DIR_1        = %00100000
Symbol MSK_1        = MSK_X
Symbol XOR_1        = MSK_X | DIR_1

Symbol DIR_2        = %00010000
Symbol MSK_2        = MSK_X
Symbol XOR_2        = MSK_X | DIR_2

Symbol DIR_3        = %00001000
Symbol MSK_3        = MSK_X
Symbol XOR_3        = MSK_X | DIR_3

Symbol DIR_4        = %00000100
Symbol MSK_4        = MSK_X
Symbol XOR_4        = MSK_X | DIR_4

Symbol keyPress     = b2
Symbol lastKeyPress = b3

; =====================================================================================

SetFreq M32

PullUp %11011000

lastKeyPress = $FF

Do
  Gosub ReadKeyPress
  ReadTable keyPress, keyPress
  If keyPress <> lastKeyPress Then
    lastKeyPress = keyPress
    SerTxd ( "Key = ", #keyPress, CR, LF )   ' ?? This needs to be changed to a sub routine... but how do I do this??
    Pause 40
  End If
Loop

ReadKeyPress:

  dirsB    = DIR_X
  keyPress = MSK_X & pinsB ^ XOR_X
  If keyPress <> 0 Then

    dirsB        = DIR_1 
    keyPress     = MSK_1 & pinsB ^ XOR_1
    If keyPress <> DIR_1 Then : Return : End If

    dirsB        = DIR_2 
    keyPress     = MSK_2 & pinsB ^ XOR_2
    If keyPress <> DIR_2 Then : Return : End If

    dirsB        = DIR_3 
    keyPress     = MSK_3 & pinsB ^ XOR_3
    If keyPress <> DIR_3 Then : Return : End If

    dirsB        = DIR_4 
    keyPress     = MSK_4 & pinsB ^ XOR_4
    If keyPress <> DIR_4 Then : Return : End If

  End If
  keyPress = 0
  Return

  Table %00000000, ( 0  )

  Table %00000101, ( 1  )
  Table %00000110, ( 2  )
  Table %00000111, ( 17 )
  Table %01000100, ( 3  )
  Table %01000101, ( 18 )
  Table %01000110, ( 19 )
  Table %01000111, ( 20 )
  Table %10000100, ( 4  )
  Table %10000101, ( 21 )
  Table %10000110, ( 22 )
  Table %10000111, ( 23 )
  Table %11000100, ( 24 )
  Table %11000101, ( 25 )
  Table %11000110, ( 26 )
  Table %11000111, ( 27 )

  Table %00001001, ( 5  )
  Table %00001010, ( 6  )
  Table %00001011, ( 28 )
  Table %01001000, ( 7  )
  Table %01001001, ( 29 )
  Table %01001010, ( 30 )
  Table %01001011, ( 31 )
  Table %10001000, ( 8  )
  Table %10001001, ( 32 )
  Table %10001010, ( 33 )
  Table %10001011, ( 34 )
  Table %11001000, ( 35 )
  Table %11001001, ( 36 )
  Table %11001010, ( 37 )
  Table %11001011, ( 38 )

  Table %00010001, ( 9  )
  Table %00010010, ( 10 )
  Table %00010011, ( 39 )
  Table %01010000, ( 11 )
  Table %01010001, ( 40 )
  Table %01010010, ( 41 )
  Table %01010011, ( 42 )
  Table %10010000, ( 12 )
  Table %10010001, ( 43 )
  Table %10010010, ( 44 )
  Table %10010011, ( 45 )
  Table %11010000, ( 46 )
  Table %11010001, ( 47 )
  Table %11010010, ( 48 )
  Table %11010011, ( 49 )

  Table %00100001, ( 13 )
  Table %00100010, ( 14 )
  Table %00100011, ( 50 )
  Table %01100000, ( 15 )
  Table %01100001, ( 51 )
  Table %01100010, ( 52 )
  Table %01100011, ( 53 )
  Table %10100000, ( 16 )
  Table %10100001, ( 54 )
  Table %10100010, ( 55 )
  Table %10100011, ( 56 )
  Table %11100000, ( 57 )
  Table %11100001, ( 58 )
  Table %11100010, ( 59 )
  Table %11100011, ( 60 )


**************************************************************************************
What needs to be added and changed to make this a parallel output?? Adding comments to the lines will help me learn what you did, and why and how it works...

Thanks for your help everyone... I am on a fast learning curve, and I am really loving this!!!


Best regards to all...

Kim
 
Last edited by a moderator:

westaust55

Moderator
The original code (http://www.picaxeforum.co.uk/archive/index.php/t-21379.html)
was transmitting via SERTXD values ranging from 0 to 60.
Your use of just 4 output pins as a 4-bit mode can only allow values from 0 to 15, so also delete the line:
ReadTable keyPress, keyPress

And the lookup table unless you want to change the values to suit the jeypad button legends..
With a 4 x 4 keypad that will work but you need to change more than just the SEROUT program line to accommodate the change to 4-bit parallel mode.
If you use the byte variable b0 for the keypress variable as in:
SYMBOL keypress = b0

then use the lines:
pinC.0 = bit0
pinC.1 = bit1
pinC.2 = bit2
pinC.3 = bit3
Pulsout C.4, 1 ; pulse the valid/strobe line &#8211; adjust value for duration to suit

It does raise the question why you need to use the 4-bit parallel mode?
Are you trying to work around Serial Input being a blocking command. There are alternative to first pule the serial input pin to indicate data is about to be sent. Have this trigger an interrupt in which the serial data can be read in then return to the main program.
Or, are ytou looping to interface to the LCD display with parallel interface as per another thread you currently have active.


Also, please use the [code] and [/code] tags around your program listing where more than a few lines of code involved - as per the sticky readmefirst at the top of the active forum section.
 

rocketdoc

New Member
`Thank you!! I will remember the code rule. I am wanting to use this for inputing data into another setup, and yes it will be used along with the LCD module. However, I am having great difficulty understanding these data tables, and how they work. Is there s tutorial, on how they actually work, how to create them, and know how they are read, and used?? I guess I am letting it confuse me, but, I am really wanting to learn the programming aspect of this and other controllers very much. Are there any tutorials, or instructional videos/books or something to help me understand why it is working, and how to make these things work?? THAT is one of the biggest reasons I want to know, so I can understand how these things work when programmed such as this keyboard program. I want to understand what it is doing...

THanks ya'll... i REALLY APPRECIATE THIS SO VERY MUCH!!
 

rocketdoc

New Member
whERE WOULD i PLACE THE CODE YOU SHOWED ME Sorry about the caps... I want to know why this does what it does...
 

westaust55

Moderator
Before you go too far with the 4-bit parallel interface you need to think about what you need.

First, &#8220;ASCII art&#8221; embedded schematic in the top of your code at post 1 shows two lines both connected to the third column from the left. B7 should go to the 2nd column.

Secondly, what are you going to do if there are multiple keys pressed at the same time?
4-bit parallel interface cannot send all those combinations so (more) unwanted codes need to be filterd out.

The original code as provided by hippy Grogster uses keypress = 0 to indicate no key is pressed.
So you may need to decode to 1 to 16 and then subtract 1 (for 0 to 15) as the valid numbers associated with a valid data pulse for transfer to the second PICAXE.

The TABLE is like a map. When scanning the 4x4 keypad, the program makes one line high and then scans the portB pins ( = pinsB) to detect which pin or pins is high.
This is not going to be a nice number like 0 to 15 but will have various combinations of bits.
The TABLE program lines are each placing a value at the table memory location to represent the desired value when a key is pressed base don the returned bit pattern from portB.

I have not tried to follow hippy's Grogster&#8217;s code right through but if the keypad is a 4x4 matrix and the table has 60 entries, then it may/will also be scanning for multiple keys pressed at the same time.
Those 60 entries are spread over almost the entire 256 bytes of table memory where many locations will just return 0 as if no key is pressed.

Why not try running hippy's Grogster&#8217;s program in the Programaming Editor simulator stepping through and see how it works.
Once you see the sequence, then change the program line:
SerTxd ( "Key = ", #keyPress, CR, LF )
to the lines I gave you and see what you see at the 4 parallel pin outputs. Don&#8217;t forget to set the 4 pins + pulse (C.0 to C.4) as outputs.


Sorry I do not have the time right now to provide you with a fully working example which initially needs you to clarify exactly what you want before code can be written for a 4-bit parallel output.
 
Last edited:

hippy

Technical Support
Staff member
I believe the code was originally mine -

http://www.picaxeforum.co.uk/showthread.php?14001-20X2-4x4-keypad-scanner

The table is used to convert the column bit which gets asserted when a row is scanned into a number representing that key. 0=None, 1-16 = one of the keys on the matrix. That 1-16 will need to be converted further to represent the digit value of key pressed. How that's done will depend on the keypad and how it's wired to the PICAXE.

Multiple keys held will assert more than one column bit when a row is scanned, these simply get looked up via the table to give a 17+ value. To only recognise single key presses simply remove any TABLE entries which return a value greater than 16.
 

rocketdoc

New Member
Thank you for the code!!! I want to convert this output to a 4 bit byte. It will be used in interfacing with many different types of applications. So exactly how would I do this, and what code would I change to do so??
 

hippy

Technical Support
Staff member
You can probably just add this after the SERTXD based on westaust55's post #2 ...

Code:
If keypress >= 1 And keypress <= 16 Then
  b0 = keypress - 1
  dirsC = $00011111
  pinC.0 = bit0
  pinC.1 = bit1
  pinC.2 = bit2
  pinC.3 = bit3
  Pulsout C.4, 1
End If
You might want to move that dirsC=%00011111 to the start of the program, might want to increase the length of the PULSOUT.
 

westaust55

Moderator
Yes.

However, why not leave the SERTXD command there initially to see what codes are determined and that they match the data on the 4-bit parallel interface.
put a semicolon in from to comment out the SERTXD once you know you have the results that you seek.
 
Top