0

I'm trying to use a python script to make a connection with my 4x4 keypad on Raspberry (RPi.GPIO). The code does not work correctly, because the first and second rows do not respond. I'm trying to use pad4pi, but in my case, this does not work.

This is the code I'm using at the moment.

(Main Control)

import RPi.GPIO as GPIO
import time
import serial
import Keypad
#import Open_CV

ROWS = 4        # number of rows of the Keypad 
COLS = 4        #number of columns of the Keypad
keys =  [   '1','2','3','A',    #key code
            '4','5','6','B',
            '7','8','9','C',
            '*','0','#','D'     ]
rowsPins = [18,22,29,31]        #connect to the row pinouts of the keypad
colsPins = [32,33,36,37]        #connect to the column pinouts of the keypad
# the pins need to be these, because the others are already in use

# Configure the use of the serial terminal and the baud rate
ser = serial.Serial(       #"/dev/ttyS0", 9600)
        port='/dev/ttyS0', #Replace ttyS0 with ttyAM0 for Pi1,Pi2,Pi0
        baudrate = 9600,
        parity=serial.PARITY_NONE,
        stopbits=serial.STOPBITS_ONE,
        bytesize=serial.EIGHTBITS,
        timeout=1)

#Configuração inicial dos terminais GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
    
# call the video method
#video("teste.mp4")


def loop():
    keypad = Keypad.Keypad(keys,rowsPins,colsPins,ROWS,COLS)    #create Keypad object
    keypad.setDebounceTime(50)      #set the debounce time


    # call the video method
    #video('/home/pi/share/teste.mp4')

    while(True):
        key = keypad.getKey()       #obtain the state of keys
        if(key != keypad.NULL):     #if there is key pressed, print its key code.
            print ("You Pressed Key : %c "%(key))
            ser.write(str.encode(key))
        time.sleep(1)

        #ret, frame = cap.read()
        #gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
 
        #cv2.imshow('frame',gray)

        #if cv2.waitKey(1) & 0xFF == ord('q'):
        #    break

    #cap.release()
    #cv2.destroyAllWindows()

if __name__ == '__main__':     #Program start from here
    print ("Program is starting ... ")
    try:
        loop()
    except KeyboardInterrupt:  #When 'Ctrl+C' is pressed, exit the program. 
        GPIO.cleanup()

(keypad functions)

#!/usr/bin/env python3
########################################################################
# Filename    : Keypad.py
# Description : The module of matrix keypad 
# Author      : freenove
# modification: 2016/07/13
########################################################################
import RPi.GPIO as GPIO 
import time
#class Key:Define some of the properties of Key
class Key(object):
  NO_KEY = '\0'
  #Defines the four states of Key
  IDLE = 0
  PRESSED = 1
  HOLD = 2
  RELEASED = 3
  #define OPEN and CLOSED
  OPEN = 0
  CLOSED =1
  #constructor
  def __init__(self):
    self.kchar = self.NO_KEY
    self.kstate = self.IDLE
    self.kcode = -1
    self.stateChanged = False

class Keypad(object):
  NULL = '\0'
  LIST_MAX = 10  #Max number of keys on the active list.
  MAPSIZE = 10  #MAPSIZE is the number of rows (times 16 columns)
  bitMap = [0]*MAPSIZE
  key = [Key()]*LIST_MAX
  holdTime = 500    #key hold time
  holdTimer = 0
  startTime = 0
  #Allows custom keymap, pin configuration, and keypad sizes.
  def __init__(self,usrKeyMap,row_Pins,col_Pins,num_Rows,num_Cols):
    GPIO.setmode(GPIO.BOARD)
    self.rowPins = row_Pins
    self.colPins = col_Pins
    self.numRows = num_Rows
    self.numCols = num_Cols
    
    self.keymap = usrKeyMap
    self.setDebounceTime(10)
  #Returns a single key only. Retained for backwards compatibility.  
  def getKey(self):
    single_key = True
    if(self.getKeys() and self.key[0].stateChanged and (self.key[0].kstate == self.key[0].PRESSED)):
      return self.key[0].kchar
    single_key = False
    return self.key[0].NO_KEY
  #Populate the key list.  
  def getKeys(self):
    keyActivity = False
    #Limit how often the keypad is scanned.
    if((time.time() - self.startTime) > self.debounceTime*0.001):
      self.scanKeys()
      keyActivity = self.updateList()
      self.startTime = time.time()
    return keyActivity
  #Hardware scan ,the result store in bitMap  
  def scanKeys(self):
    #Re-intialize the row pins. Allows sharing these pins with other hardware.
    for pin_r in self.rowPins:
      GPIO.setup(pin_r,GPIO.IN,pull_up_down = GPIO.PUD_UP)
    #bitMap stores ALL the keys that are being pressed.
    for pin_c in self.colPins:
      GPIO.setup(pin_c,GPIO.OUT)
      GPIO.output(pin_c,GPIO.LOW)
      for r in self.rowPins: #keypress is active low so invert to high.
        self.bitMap[self.rowPins.index(r)] = self.bitWrite(self.bitMap[self.rowPins.index(r)],self.colPins.index(pin_c),not GPIO.input(r))
      #Set pin to high impedance input. Effectively ends column pulse.
      GPIO.output(pin_c,GPIO.HIGH)
      GPIO.setup(pin_c,GPIO.IN)
  #Manage the list without rearranging the keys. Returns true if any keys on the list changed state.    
  def updateList(self):
    anyActivity = False
    kk = Key()
    #Delete any IDLE keys
    for i in range(self.LIST_MAX):
      if(self.key[i].kstate == kk.IDLE):
        self.key[i].kchar = kk.NO_KEY
        self.key[i].kcode = -1
        self.key[i].stateChanged = False
    # Add new keys to empty slots in the key list.
    for r in range(self.numRows):
      for c in range(self.numCols):
        button = self.bitRead(self.bitMap[r],c)
        keyChar = self.keymap[r * self.numCols +c]
        keyCode = r * self.numCols +c
        idx = self.findInList(keyCode)
        #Key is already on the list so set its next state.
        if(idx > -1):
          self.nextKeyState(idx,button)
        #Key is NOT on the list so add it.
        if((idx == -1) and button):
          for i in range(self.LIST_MAX):
            if(self.key[i].kchar == kk.NO_KEY):  #Find an empty slot or don't add key to list.
              self.key[i].kchar = keyChar
              self.key[i].kcode = keyCode
              self.key[i].kstate = kk.IDLE  #Keys NOT on the list have an initial state of IDLE.
              self.nextKeyState(i,button)
              break  #Don't fill all the empty slots with the same key.
    #Report if the user changed the state of any key.
    for i in range(self.LIST_MAX):
      if(self.key[i].stateChanged):
        anyActivity = True
    return anyActivity    
  #This function is a state machine but is also used for debouncing the keys.  
  def nextKeyState(self,idx, button):
    self.key[idx].stateChanged = False
    kk = Key()
    if(self.key[idx].kstate == kk.IDLE):
      if(button == kk.CLOSED):
        self.transitionTo(idx,kk.PRESSED)
        self.holdTimer = time.time()  #Get ready for next HOLD state.
    elif(self.key[idx].kstate == kk.PRESSED):
      if((time.time() - self.holdTimer) > self.holdTime*0.001):  #Waiting for a key HOLD...  
        self.transitionTo(idx,kk.HOLD)
      elif(button == kk.OPEN):    # or for a key to be RELEASED.
        self.transitionTo(idx,kk.RELEASED)
    elif(self.key[idx].kstate == kk.HOLD):
      if(button == kk.OPEN):
        self.transitionTo(idx,kk.RELEASED)
    elif(self.key[idx].kstate == kk.RELEASED):
      self.transitionTo(idx,kk.IDLE)
      
  def transitionTo(self,idx,nextState):
    self.key[idx].kstate = nextState
    self.key[idx].stateChanged = True
  #Search by code for a key in the list of active keys.
  #Returns -1 if not found or the index into the list of active keys.
  def findInList(self,keyCode):
    for i in range(self.LIST_MAX):
      if(self.key[i].kcode == keyCode):
        return i
    return -1
  #set Debounce Time,  The defaul29t is 50ms          
  def setDebounceTime(self,ms):
    self.debounceTime = ms
  #set HoldTime,The default is 500ms
  def setHoldTime(self,ms):
    self.holdTime = ms
  #  
  def isPressed(self, keyChar):
    for i in range(self.LIST_MAX):
      if(self.key[i].kchar == keyChar):
        if(self.key[i].kstate == self.self.key[i].PRESSED and self.key[i].stateChanged):
          return True
    return False
  #      
  def waitForKey(self):
    kk = Key()
    waitKey = kk.NO_KEY
    while(waitKey == kk.NO_KEY):
      waitKey = self.getKey()
    return waitKey
  
  def getState(self):
    return self.key[0].kstate
  #  
  def keyStateChanged(self):
    return self.key[0].stateChanged
  
  def bitWrite(self,x,n,b):
    if(b):
      x |= (1<<n)
    else:
      x &=(~(1<<n))
    return x
  def bitRead(self,x,n):
    if((x>>n)&1 == 1):
      return True
    else:
      return False
3
  • please add a clear, answerable question to your post Commented Feb 3, 2023 at 23:31
  • 1
    You've just dumped a large amount of code here, none of which appears to use pad4pi, even though you mention that. First rule of getting something like this working: start with an absolute minimum of code. I'd suggest you start with the pad4pi example code and try to get that to work. Something to double check: your pin numbers. They look like actual 1-40 numbers. Are you sure that's what pad4pi wants? Try GPIO numbers and see if that makes a difference. Commented Feb 5, 2023 at 21:16
  • Thanks for comment, i check the pins connections on raspberry, and i connect on wrong pins, that's why my code does not work kk Commented Feb 6, 2023 at 13:32

0

Your Answer

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.