Question 11.11: Intercepting Keypresses You want to intercept individual key......

Intercepting Keypresses

You want to intercept individual keypresses on a USB keyboard or numeric keypad.

Step-by-Step
The 'Blue Check Mark' means that this solution was answered by an expert.
Learn more on how do we answer questions.

There are at least two ways to solve this problem. The most straightforward is to use the sys.stdin.read function. This has the advantage over the other method of not requiring a graphical user interface to be running, so a program using it can be run from an ssh session.

Open an editor (nano or IDLE) and paste in the following code. As with all the program examples in this book, you can also download the program from the Code section of the Raspberry Pi Cookbook website, where it is called keys_sys.py.

import sys, tty, termios
def read_ch():
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)

finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
while True:
ch = read_ch()
if ch == ‘x’:
break
print(“key is: ” + ch)

The alternative to this is to use Pygame. Pygame is a Python library intended for writing games. It can also be used to detect keypresses. You could then use this to perform some action (or steer a robot, as it’s used in Recipe 10.8).

The following example program illustrates the use of Pygame to print out a message each time a key is pressed. However, it only works if the program has access to the windowing system, so you will need to run it using VNC (Recipe 2.8) or directly on the Raspberry Pi. The example code is in the file keys_pygame.

import pygame
import sys
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.mouse.set_visible(0)
while True:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if event.type == KEYDOWN:
print(“Code: ” + str(event.key) + ” Char: ” + chr(event.key))

This opens a blank Pygame window, and keys will only be intercepted if this has focus. The program produces output in the Terminal window from which the program is run.

If you press an arrow key or Shift key, the program will throw an error because those keys don’t have an ASCII value.

$python keys_pygame.py
Code: 97 Char: a
Code: 98 Char: b
Code: 99 Char: c
Code: 120 Char: x
Code: 13 Char:

In this case, Ctrl-C won’t stop this program from running. To stop the program, click the X on the PyGame window.

Discussion

When you are using the Pygame approach, other keys have constant values defined for them, which allows you to use the cursor and other non-ASCII keys (like the up arrow key and Home) on the keyboard. This isn’t possible with the other approach.

See Also

Intercepting keyboard events can also be an alternative to using a matrix keypad (Recipe 11.8).

Related Answered Questions

Question: 11.13

Verified Answer:

Use an RTC (real-time clock) module. A very common...
Question: 11.8

Verified Answer:

Keypads are arranged in rows and columns, with a p...
Question: 11.2

Verified Answer:

Record the last state of the button and invert tha...
Question: 11.1

Verified Answer:

Connect a switch to a GPIO pin and use the RPi.GPI...
Question: 11.7

Verified Answer:

Use a rotary (quadrature encoder) connected to two...
Question: 11.9

Verified Answer:

Use a PIR (passive infrared) motion detector modul...
Question: 11.12

Verified Answer:

The solution to this is very similar to that of us...
Question: 11.10

Verified Answer:

A 3.3V serial GPS module can be connected directly...