3

I'm trying to make an interrupt based matrix keypad reader that is loosely based off of this library. However, I'm getting some really weird effects when trying to use GPIO.add_event_detect in that:

  • Despite wanting the falling edge, I get the rising edge as well
  • In some cases, the callback continues to fire until I release the key. Weirdly, this seems to only happen on column 3 (GPIO #22) and not the others, usually.

In my code, I'm removing the callback events as soon as I enter the callback because I have to switch the columns that were inputs with callbacks to outputs so that I can read the rows and determine the key that was pressed. It always figures out the correct key, it's just that it either fires off continuously and/or gets another call back on the rising edge (key released)... I've accommodated for the rising edge issue in code but I don't get why it should happen in the first place.

Code below, please excuse my many debug print statements:

#!/usr/bin/python
import RPi.GPIO as GPIO
class keypad():
 def __init__(self):
 GPIO.setmode(GPIO.BCM)
 # CONSTANTS 
 self.KEYPAD = [
 [1,2,3],
 [4,5,6],
 [7,8,9],
 ["*",0,"#"]
 ]
 self.ROW = [18,23,24,25]
 self.COLUMN = [4,17,22]
 self.__setInterruptMode()
 def __colRise(self, channel):
 print ""
 print "Chan: " + str(channel)
 print "State: " + str(GPIO.input(channel))
 if GPIO.input(channel) > 0:
 return
 #remove interrupt temporarily
 #GPIO.remove_event_detect(channel)
 for c in range(len(self.COLUMN)):
 print "Remove: " + str(self.COLUMN[c])
 GPIO.remove_event_detect(self.COLUMN[c])
 #get column number
 colVal = -1
 for c in range(len(self.COLUMN)):
 if channel == self.COLUMN[c]:
 colVal = c
 print "ColVal: " + str(colVal)
 if colVal >=0 and colVal < len(self.COLUMN):
 #set rows as intputs
 for r in range(len(self.ROW)):
 GPIO.setup(self.ROW[r], GPIO.IN, pull_up_down=GPIO.PUD_UP)
 #set triggered column as output
 GPIO.setup(channel, GPIO.OUT)
 GPIO.output(channel, GPIO.LOW)
 # Scan rows for pushed key/button
 rowVal = -1
 for r in range(len(self.ROW)):
 tmpRead = GPIO.input(self.ROW[r])
 if tmpRead == 0:
 rowVal = r
 print "RowVal: " + str(rowVal)
 if rowVal >= 0 and rowVal <= 3:
 print str(self.KEYPAD[rowVal][colVal])
 else:
 print "Invalid Row!"
 else:
 print "Invalid Col!"
 #re-enable interrupts
 self.__setInterruptMode()
 def __setInterruptMode(self):
 #set the first row as output low
 #only first one needed as it will ground to all columns
 for r in range(len(self.ROW)):
 GPIO.setup(self.ROW[r], GPIO.OUT)
 GPIO.output(self.ROW[r], GPIO.LOW)
 #set columns as inputs and attach interrupt handlers on rising edge
 for c in range(len(self.COLUMN)):
 GPIO.setup(self.COLUMN[c], GPIO.IN, pull_up_down=GPIO.PUD_UP)
 GPIO.add_event_detect(self.COLUMN[c], GPIO.FALLING, bouncetime=500, callback=self.__colRise)
 def cleanup(self):
 GPIO.cleanup()
 print "Cleanup done!"
import time 
if __name__ == '__main__':
 key = keypad()
 try:
 while True:
 time.sleep(1)
 except KeyboardInterrupt:
 key.cleanup()
asked Mar 21, 2014 at 13:36
9
  • I have noticed my hardware sortof works like an antenna also. I dont know what your hardware looks like, but raising the high voltage or lowering the low may be worth trying. Commented Mar 21, 2014 at 15:52
  • Kinda thought the voltage was fixed at 0V or 3.3V? Commented Mar 21, 2014 at 16:04
  • depends on your resistor-usage, can you show us your hardware? Commented Mar 21, 2014 at 16:06
  • It's a standard 4x3 matrix keypad hooked directly into the GPIO pins as described in the code. The only resistors in use are the built in pull up/down resistors on the chip, also as described in the code. Not really much else to show. Commented Mar 21, 2014 at 16:07
  • ok, I don't know much about the internal resistors and how they influence the 3.3v, and if you maybe would be better off make it a pull-down, instead of pullup circuit. But I'm sure someone else has some better knowledge of this part. Commented Mar 21, 2014 at 16:16

1 Answer 1

1

I've heard of this problem before (How does python GPIO bouncetime parameter work?). I think the best solution in the end was to program around the issue, adding code to detect the extra bounces (button presses).

answered Mar 22, 2014 at 17:53

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.