summaryrefslogtreecommitdiff
path: root/recourses/Keypad.py
diff options
context:
space:
mode:
authorAbdellah El Morabit <nsrddyn@gmail.com>2024-11-07 17:00:19 +0100
committerAbdellah El Morabit <nsrddyn@gmail.com>2024-11-07 17:00:19 +0100
commit32ec9336088799c42d8aa7ace6648802e1b267cf (patch)
treebc6d718631a2f2a210b4cde462a5f7f97bd6b613 /recourses/Keypad.py
parentfa7007d00c04fc73f668e2b7f339c3f60a64d055 (diff)
did alot of designing and testing out on a linux machine
Diffstat (limited to 'recourses/Keypad.py')
-rw-r--r--recourses/Keypad.py202
1 files changed, 0 insertions, 202 deletions
diff --git a/recourses/Keypad.py b/recourses/Keypad.py
deleted file mode 100644
index f762b4b..0000000
--- a/recourses/Keypad.py
+++ /dev/null
@@ -1,202 +0,0 @@
-#!/usr/bin/env python3
-
-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 default is 50ms
- def setDebounceTime(self,ms):
- self.debounceTime = ms
- #set HoldTime,The default is 500ms
- def setHoldTime(self,ms):
- self.holdTime = ms
- #
- def isPressed(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():
- kk = Key()
- waitKey = kk.NO_KEY
- while(waitKey == kk.NO_KEY):
- waitKey = getKey()
- return waitKey
-
- def getState():
- return self.key[0].kstate
- #
- def keyStateChanged():
- 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
-
-ROWS = 4
-COLS = 4
-keys = [ '1','2','3','A',
- '4','5','6','B',
- '7','8','9','C',
- '*','0','#','D' ]
-rowsPins = [12,16,18,22]
-colsPins = [19,15,13,11]
-
-def loop():
- keypad = Keypad(keys,rowsPins,colsPins,ROWS,COLS)
- keypad.setDebounceTime(50)
- while(True):
- key = keypad.getKey()
- if(key != keypad.NULL):
- print ("You Pressed Key : %c "%(key) )
-
-if __name__ == '__main__': # Program start from here
- print ("Program is starting ... ")
- try:
- loop()
- except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the child program destroy() will be executed.
- pass
- GPIO.cleanup()
-
-
-
-
-