Python Key press and Key Release Listener

26,901

Solution 1

I've seen Pygame game development library being successfully used in similar scenarios before, handling realtime systems and machinery in production, not just toy examples. I think it's a suitable candidate here too. Check out pygame.key module for what is possible to do with the keyboard input.

In short, if you are not familiar with game development, you basically continuously poll for events such as input state changes inside an 'infinite' game loop and react accordingly. Usually update the parameters of the system using deltas per time elapsed. There's plenty of tutorials on that and Pygame available around and Pygame docs are pretty solid.

A simple example of how to go about it:

import pygame

pygame.init()

# to spam the pygame.KEYDOWN event every 100ms while key being pressed
pygame.key.set_repeat(100, 100)

while 1:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_w:
                print 'go forward'
            if event.key == pygame.K_s:
                print 'go backward'
        if event.type == pygame.KEYUP:
            print 'stop'

You'll need to play with pygame.KEYDOWN, pygame.KEYUP and pygame.key.set_repeat depending on how your car movement is implemented.

Solution 2

Faced a similar problem (I am no Python expert) but this worked for me

import pynput
from pynput import keyboard 

def on_press(key):
    try:
        print('Key {0} pressed'.format(key.char))
        #Add your code to drive motor
    except AttributeError:
        print('Key {0} pressed'.format(key))
        #Add Code
def on_release(key):
    print('{0} released'.format(key))
    #Add your code to stop motor
    if key == keyboard.Key.esc:
        # Stop listener
        # Stop the Robot Code
        return False

# Collect events until released
with keyboard.Listener(
        on_press=on_press,
        on_release=on_release) as listener:
    listener.join()
Share:
26,901
Admin
Author by

Admin

Updated on March 21, 2020

Comments

  • Admin
    Admin about 4 years

    I am controlling a remote toy car using python code .As of now the code is as below

    def getkey():
            fd = sys.stdin.fileno()
            old = termios.tcgetattr(fd)
            new = termios.tcgetattr(fd)
            new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
            new[6][TERMIOS.VMIN] = 1
            new[6][TERMIOS.VTIME] = 0
            termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
            c = None
            try:
                    c = os.read(fd, 1)
            finally:
                    termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
            return c
    
    def car():
        while True:
            key = getkey()
            if key == 's': #Down arrow
                print "Down"
                Backward()
            elif key == 'w': #Up arrow
                print "Up"
                forward()
            elif key == 'a': 
                print "left"
                Left()
            elif key == 'd': 
                print "Right"
                Right()
            elif key == 'q': #Quit
                print "That's It"
                break
    def forward():
        GPIO.output(11,True)  #Move forward
    

    When i press 'w' forward() method is called and the car moves forward but wont stop until i quit the program or call GPIO.output(11,Flase) from some other method.

    Is there any key Listener which detects key release of any particular key .

    For example , if 'w' pressed called this method and if released call some other method

    Sudo code

    if w_isPressed()
       forward()
    else if w_isReleased()
        stop()
    
  • malte
    malte almost 7 years
    One limitation to pygame is that it requires a display to be connectecd. That is, this approach does not work if you are connecting to a headless raspberry pi with SSH.