Shop OBEX P1 Docs P2 Docs Learn Events
Better way to drive button matrix? — Parallax Forums

Better way to drive button matrix?

I'm making a button matrix board that will hook up something like this image from https://www.embeddedrelated.com/showarticle/519.php

This article describes what I guess is the usual way for doing this...
Drive one of the rows and then scan the columns.

Am thinking about if there's any magic on the P2 smartpins that could automate this...
Haven't come up with anything yet...

654 x 697 - 53K

Comments

  • Chip made that "5 buttons on one pin" example where it uses the ADC to read multiple buttons from just one pin (included with PNut). You could do that on multiple pins at once, which would be actually be more efficient than a matrix for low pin counts...

    P2 Pins Matrix size Matrix Buttons ADC buttons (5x)
    4 2x2 4 20
    5 2x3 6 25
    6 3x3 9 30
    7 3x4 12 35
    8 4x4 16 40
    9 4x5 20 45
    10 5x5 25 50
    11 5x6 30 55
    12 6x6 36 60
    13 6x7 42 65
    14 7x7 49 70
    15 7x8 56 75
    16 8x8 64 80
    17 8x9 72 85
    18 9x9 81 90
    19 9x10 90 95
    20 10x10 100 100
    21 10x11 110 105
    22 11x11 121 110

    etc.

  • RaymanRayman Posts: 14,745

    Array I'm looking at is 5x6. But, saving pins doesn't help in my case.
    Would like to find a way to not use a cog to save battery life though.
    Looking at making a calculator...

    Actually, maybe the regular way is just fine.
    Guess can't do math and check buttons at same time, but maybe math is so fast it doesn't matter...

  • RaymanRayman Posts: 14,745

    Here's photo of current mock up to give an idea of what this is about...

    Want to power by LiPo...

    640 x 480 - 112K
  • RaymanRayman Posts: 14,745

    Wiring up the buttons now in Eagle.
    Guess good thing is can at least use internal pullups/pulldowns so don't need any resistors.

    1590 x 531 - 15K
  • Since when would you need a cog, anyways? A passive matrix like that can respond pretty fast (esp. if instead of relying on pullup/down, you drive the columns to their unpressed state in-between rows), so reading it shouldn't take much time at all.

  • JonnyMacJonnyMac Posts: 9,158
    edited 2023-04-19 16:06

    To Ada's point about speed -- and this is in Propeller Tool (PNut) using safe, simplistic code.

    con
    
      KBD_COLS = 0 addpins 5
      KBD_ROW0 = 6
      KBD_ROW4 = KBD_ROW0 + 4
    
    
    pub setup_kbd()                                                 ' ~2.4us
    
      pinfloat(KBD_COLS)
      pinfloat(KBD_ROW0 addpins 4)    
    
      wrpin(KBD_COLS, P_LOW_15K | P_FILT2_AB)                       ' select 15K pull-downs 
      pinlow(KBD_COLS)                                              ' activate pull-downs
    
      wrpin(KBD_ROW0 addpins 4, P_HIGH_1K5)                         ' drive high through 1.5K
    
    
    pub scan_kbd() : result | r                                     ' ~10.3us
    
      repeat r from KBD_ROW4 to KBD_ROW0
        pinhigh(r)
        result := (result << 6) | pinread(KBD_COLS)
        pinfloat(r) 
    

    Edit: Made row drive through 1.5K
    Edit: Added Evan's filter suggestion

  • evanhevanh Posts: 16,027

    None of the smartpin modes will help. But you'll want to use the debounce hardware in front of each smartpin. I'd use the maximum of 8 samples spread over maybe a few milliseconds. The default for "filt3" I feel is too sluggish.

    Of course, once the debounce is in use, then you'll want to setup a regular sampling interval where you read the inputs just before changing the outputs. Pretty small overhead but has to be the Cog doing this really.

  • RaymanRayman Posts: 14,745

    Thinking more about smartpins for this... Maybe rows can be set up in a slow NCO mode with each giving a staggered pulse so that only one is on at a time. Then, use an interrupt to go off whenever a high is detected on a col pin. Hopefully, with some smartpin filtering on the col inputs...

Sign In or Register to comment.