How do you convert INA[3..0] into a decimal value

Hello Everyone
I am using a MM74C922 16-Key Encoder (Keypad Encoder) from Fairchild Semiconductor. This chip sets the value of pins 0 - 3 according to the truth table in the datasheet. For easy deciphering within my program, I want to convert these bits into a decimal value. Here is the scenario:
How do I convert these bits into a decimal value?
Thanks
Bruce
I am using a MM74C922 16-Key Encoder (Keypad Encoder) from Fairchild Semiconductor. This chip sets the value of pins 0 - 3 according to the truth table in the datasheet. For easy deciphering within my program, I want to convert these bits into a decimal value. Here is the scenario:
PUB Main
cognew(MonitorKeypad, @KeypadCheckStack)
REPEAT UNTIL PressedKey == 0 OR PressedKey == 8
IF KeyPressed == 1
PiezoInputError
KeyPressed := 0
PUB MonitorKeypad
DIRA[0..3]~
DIRA[5]~
REPEAT
WAITPEQ(|<5, |<5, 0)
PressedKey := INA[3..0]
KeyPressed := 1
WAITPNE(|<5, |<5, 0)
How do I convert these bits into a decimal value?
Thanks
Bruce
Comments
John Abshier
I know the value is in INA[0..3] through previous testing using FullDuplexSerialPlus, but when I use it as stated above, it fails to recognize the value.
Thanks For Responding
Bruce
If the value is wrong it outputs to Piezo to indicate that an incorrect key was pressed.
Bruce
Your main routine will exit it's repeat loop and and then exit the routine and everything stops.
That is correct for this example.
However if 1 or another wrong key is pressed then it pulses a piezo.
PUB Main cognew(MonitorKeypad, @KeypadCheckStack) REPEAT UNTIL PressedKey == 0 OR PressedKey == 8 IF KeyPressed == 1 PiezoInputError KeyPressed := 0 PUB MonitorKeypad DIRA[0..3]~ DIRA[5]~ REPEAT WAITPEQ(|<5, |<5, 0) PressedKey := INA[3..0] KeyPressed := 1 WAITPNE(|<5, |<5, 0) PUB PiezoInputError CTRA[30..26] := %00100 'NCO single-ended CTRA[5..0] := 16 ' Set APIN to PIN 16 FRQA := 112_367 ' Set frqa for 2093 Hz (C7 note) using: REPEAT 3 'Broadcast three 1/4 second beeps !DIRA[16] ' Set PIN 16 to output WAITCNT(CLKFREQ / 4 + CNT)
Thanks for responding
Bruce
If I were debugging your hardware, I'd write my main program so it would display the bits of PressedKey every time that KeyPressed changed from 0 to 1 and then would set KeyPressed back to 0.
Look at functions Main and MonitorKeypad. In MonitorKeypad I obtain the the bits from INA[3..0], and in the main I test the value.
Thanks for responding.
Bruce
The wiring should be okay, but I will double check. So then according to the code above, the piezo should beep if a 1 is pressed?
Bruce
Obviously, you haven't given your complete program. Remember that the variables are likely to be initialized to zero unless you initialize them to something else. That includes PressedKey. What happens if PressedKey is initially zero?
PUB MonitorKeypad DIRA[0..3]~ DIRA[5]~ REPEAT WAITPEQ(|<5, |<5, 0) 'Must stay this way for easy reading PressedKey := INA[3..0] CTRA[30..26] := %00100 'NCO single-ended CTRA[5..0] := 16 ' Set APIN to PIN 16 FRQA := 112_367 ' Set frqa for 2093 Hz (C7 note) using: REPEAT 3 'Broadcast three 1/4 second beeps !DIRA[16] ' Set PIN 16 to output WAITCNT(CLKFREQ + CNT) KeyPressed := 1 WAITPNE(|<5, |<5, 0)
PUB MonitorKeypad DIRA[0..3]~ DIRA[5]~ REPEAT WAITPEQ(|<5, |<5, 0) 'Must stay this way for easy reading PressedKey := INA[3..0] if PressedKey == 7 CTRA[30..26] := %00100 'NCO single-ended CTRA[5..0] := 16 ' Set APIN to PIN 16 FRQA := 112_367 ' Set frqa for 2093 Hz (C7 note) using: REPEAT 3 'Broadcast three 1/4 second beeps !DIRA[16] ' Set PIN 16 to output WAITCNT(CLKFREQ + CNT) KeyPressed := 1 WAITPNE(|<5, |<5, 0)
The piezo beepsCON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 VAR LONG KeypadCheckStack[10] LONG PressedKey LONG KeyPressed PUB Main KeyPressed := 0 cognew(MonitorKeypad, @KeypadCheckStack) REPEAT UNTIL PressedKey == 0 OR PressedKey == 8 IF KeyPressed == 1 PiezoInputError 'Piezo should beep but doesn't KeyPressed := 0 PUB MonitorKeypad DIRA[0..3]~ DIRA[5]~ REPEAT WAITPEQ(|<5, |<5, 0) PressedKey := INA[3..0] if PressedKey == 0 OR PressedKey == 8 CTRA[30..26] := %00100 CTRA[5..0] := 16 FRQA := 112_367 REPEAT 3 'Piezo beeps !DIRA[16] WAITCNT(CLKFREQ + CNT) KeyPressed := 1 WAITPNE(|<5, |<5, 0) PUB PiezoInputError CTRA[30..26] := %00100 CTRA[5..0] := 16 FRQA := 112_367 REPEAT 3 !DIRA[16] WAITCNT(CLKFREQ + CNT)
http://forums.parallax.com/showthread.php?128228-Snippet-needed-for-Prop-and-the-MM74C922-keypad-encoder
in main:
repeat until KeyPressed case PressedKey 0: ' do this 1: ' do that KeyPressed := 0
As you takeover INA very early and set KeyPressed to 1 at the end on one hand, but check PressedKey and THEN KeyPressed immediately after each other, there is a chance that the if fails because of the timing.
Jon --> I have a completely different situation now. The Proto Board is now in the machine, and I have no to the Serial Terminal. If I should attempt to use this without testing, it appears that n would indicate a value for the pressed key and that getkey returns the value of n. Is there anything else I need to know?
Bruce
k := kbd.getkey if (k <> -1) beep ' do something with k
When a valid key has been retrieved the beep method (you need to write this) is called -- you can modify this to beep on a specific key.
pub getdec(digits) | k result := 0 ' clear result repeat k := kbd.getkey ' check keyboard if (k <> -1) ' if key pressed case k 0..9: ' if digit result := result * 10 + k ' add key beep(50) 10: ' if 'backspace' result /= 10 ' remove last key beep(50) 11..15: beep(500) quit ' quit, return result pub beep(ms) ctra := (%00100 << 26) | SPKR frqa := 112_367 dira[SPKR] := 1 waitcnt((MS_001 * ms) + cnt) dira[SPKR] := 0 ctra := 0
I don't know what the non-digit key codes represent so the case structure makes those easy to deal with.
Edit: I added a beep method based on your code. It requires constants for the output (SPKR) and the number of ticks per millisecond (MS_001).
I must say that was much more difficult than I would have imagined. In the original posted code the problem was that PressedKey was never initialized so it was equal to 0 and the Main loop exited immediately. In addition to that, getting it to work the way I wanted it to was also difficult. Without explaining all the pitfalls, here is the resulting code which I am ultimately satisfied with.
CON _CLKMODE = XTAL1 + PLL16X _XINFREQ = 5_000_000 OBJ LCD : "LCD_16X2_4BIT" VAR LONG KeypadCheckStack[10] LONG PressedKey LONG KeyPressed PUB Main CTRA[30..26] := %00100 CTRA[5..0] := 16 FRQA := 112_367 DIRA[16]~~ WAITCNT(CLKFREQ / 2 + CNT) DIRA[16]~ KeyPressed := 0 cognew(MonitorKeypad, @KeypadCheckStack) RTC.Init( 13, 14, 15 ) LCD.Start LCD.Move(1,1) LCD.Str(STRING("Thank You God")) LCD.Move(1,2) LCD.Str(STRING("Thank You Mother")) WAITCNT(CLKFREQ * 5 + CNT) LCD.Clear LCD.Move(1,1) LCD.Str(STRING("Thank You Mark")) LCD.Move(1,2) LCD.Str(STRING("Thank You Riki")) WAITCNT(CLKFREQ * 5 + CNT) LCD.Clear LCD.Move(1,1) LCD.Str(STRING("Thank You")) LCD.Move(1,2) LCD.Str(STRING("Parallax Forum")) WAITCNT(CLKFREQ * 5 + CNT) LCD.Clear LCD.Move(1,1) LCD.Str(STRING("Machine Setup Mode?")) LCD.Move(1,2) LCD.Str(STRING("Press YES Or NO")) CTRA[30..26] := %00100 CTRA[5..0] := 16 FRQA := 112_367 DIRA[16]~~ WAITCNT(CLKFREQ / 2 + CNT) DIRA[16]~ REPEAT IF KeyPressed ==1 IF PressedKey == 0 OR PressedKey == 8 KeyPressed := 0 QUIT ELSE PiezoInputError KeyPressed := 0 PUB MonitorKeypad DIRA[0..3]~ DIRA[5]~ REPEAT WAITPEQ(|<5, |<5, 0) KeyPressed := 1 PressedKey := INA[3..0] WAITPNE(|<5, |<5, 0) PUB PiezoInputError CTRA[30..26] := %00100 CTRA[5..0] := 16 FRQA := 112_367 REPEAT 4 !DIRA[16] WAITCNT(CLKFREQ / 30 + CNT)
Don't try this at home unless you are ready for some aggravation
Bruce