Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Key press and Key Release Listener

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, False) from some other method.

Is there any key Listener which detects the 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()
like image 852
Giridhar Avatar asked Jun 22 '14 15:06

Giridhar


1 Answers

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.

like image 93
famousgarkin Avatar answered Oct 13 '22 19:10

famousgarkin