Shop OBEX P1 Docs P2 Docs Learn Events
How do you convert INA[3..0] into a decimal value — Parallax Forums

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

idbruceidbruce Posts: 6,197
edited 2011-01-10 19:12 in Propeller 1
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:
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 AbshierJohn Abshier Posts: 1,116
    edited 2011-01-10 08:59
    From a quick look at the data sheet I think you are done. Try using one the the serial methods to print PressedKey with decimal format. You may have to change INA[3..0] to INA[0..3] depending on wiring.

    John Abshier
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 09:02
    John

    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
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 09:06
    Additional notes:

    If the value is wrong it outputs to Piezo to indicate that an incorrect key was pressed.

    Bruce
  • Heater.Heater. Posts: 21,230
    edited 2011-01-10 09:08
    What happens when PressedKey is equal to 0 or 8?

    Your main routine will exit it's repeat loop and and then exit the routine and everything stops.
  • jazzedjazzed Posts: 11,803
    edited 2011-01-10 09:12
    Do you mean you would like the ASCII decimal representation of INA[0..3]? Be more specific?
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 09:13
    Heater
    What happens when PressedKey is equal to 0 or 8? 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
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-10 09:15
    There is no such thing as "converting into a decimal value" unless you're displaying a value. Everything is a number. The Spin compiler converts your "8" into a 32-bit number. If your comparison isn't working, perhaps your wiring is wrong. I'd check that very carefully first.

    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 09:16
    Jazzed

    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
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 09:20
    Thanks for responding Mike

    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
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-10 10:10
    IF the 74C922 is wired correctly, the piezo should beep if a 1 or anything other than a 0 or 8 is pressed. The repeat loop (and the main program) should exit if a 0 or 8 is pressed.

    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?
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 10:12
    If I rearrange the code like this the piezo beeps
    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)
    
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 10:23
    And if I take it a step further to limit it to button seven like so:
    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 beeps
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 10:52
    Okay here is the code completely rearranged. The keypad is inputing data into the chip for each key and having been verified using the MonitorKeypad function. However, it appears the variables are not being updated for the Main function.
    CON
      _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)
    
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-01-10 11:43
    Since the MM7C922 has come up again I re-opened my code and think I found the error (typo in the PASM) in my buffered MM7C922 driver -- the fix is posted in your original thread.

    http://forums.parallax.com/showthread.php?128228-Snippet-needed-for-Prop-and-the-MM74C922-keypad-encoder
  • MagIO2MagIO2 Posts: 2,243
    edited 2011-01-10 11:46
    I'd try it the other way around:
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 12:14
    MagIO2 --> Thanks for the tip. I will try that.

    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
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-01-10 12:26
    The demo is just a demo -- meant to show the features of the object. You could do something like this in your main loop
    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.
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 12:30
    Thanks Jon
  • JonnyMacJonnyMac Posts: 9,235
    edited 2011-01-10 12:48
    Here's another idea -- this is designed to let you enter a decimal value from the keyboard
    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).
  • idbruceidbruce Posts: 6,197
    edited 2011-01-10 19:12
    Hello Everyone

    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
Sign In or Register to comment.