blaablaaguy
Posts: 623
Joined: Sun Sep 27, 2015 3:26 pm

Detect keypress using Python

Mon Jan 04, 2016 6:31 pm

Hi,

I want to be able to set a GPIO pin to high or low using a keyboard. Is this possible? If so how do I do it?
This signature intentionally left blank.

enedil
Posts: 80
Joined: Sat Feb 21, 2015 4:22 pm
Location: Toruń, Poland
Contact: Website

Re: Detect keypress using Python

Mon Jan 04, 2016 6:45 pm

- What Can a Thoughtful Man Hope for Mankind on Earth, Given the Experience of the Past Million Years?
- Nothing.

Kurt Vonnegut, Cat's Cradle

blaablaaguy
Posts: 623
Joined: Sun Sep 27, 2015 3:26 pm

Re: Detect keypress using Python

Wed Jan 06, 2016 6:19 pm

Wouldnt do anything... :(
Anyone else got any ideas? Tried fifty million examples allready and none work.
This signature intentionally left blank.

User avatar
paddyg
Posts: 2612
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: Detect keypress using Python

Wed Jan 06, 2016 6:31 pm

In pi3d we used curses. This question crops up a lot, try searching this forum with "curses getch"
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

hippy
Posts: 9167
Joined: Fri Sep 09, 2011 10:34 pm
Location: UK

Re: Detect keypress using Python

Wed Jan 06, 2016 8:04 pm

Not sure who gets credit for the original code here, but this is what I have used in the past. Works at a Windows prompt and on Pi command line, not tested on Mac. Ctrl-C throws an exception under Windows but doesn't on the Pi.On Windows Inkey() returns a negative if no character, 0 to +N for a character, on Pi I recall it blocks until character available.

Code: Select all

class _GetCh:
  def __init__(self):
    try:
      self.impl = _GetChWindows()
    except ImportError:
      try:
        self.impl = _GetChMacCarbon()
      except ImportError:
        self.impl = _GetChUnix()
  def __call__(self):
    return self.impl()

class _GetChWindows:
  def __init__(self):
    import msvcrt
  def __call__(self):
    import msvcrt
    if msvcrt.kbhit():
      while msvcrt.kbhit():
        ch = msvcrt.getch()
      while ch in b'\x00\xe0':
        msvcrt.getch()
        ch = msvcrt.getch()
      return ord( ch.decode() )
    else:
      return -1

class _GetChMacCarbon:
  def __init__(self):
    import Carbon
    Carbon.Evt
  def __call__(self):
    import Carbon
    if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask
      return ""
    else:
      (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
      return msg & 0x000000FF

class _GetChUnix:
  def __init__(self):
    import tty, sys, termios # import termios now or else you'll get the Unix
                             # version on the Mac
  def __call__(self):
    import sys, tty, termios
    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 ord(ch)

InKey = _GetCh()

print "Press Ctrl-C to exit"

c = InKey()
while c != 3:
  if c >= 0:
    print c
  c = InKey()

gordon77
Posts: 5452
Joined: Sun Aug 05, 2012 3:12 pm

Re: Detect keypress using Python

Wed Jan 06, 2016 8:23 pm

This is the code linked to with a bit added, pressing p will toggle gpio pin 26 high and low.

Code: Select all

import pygame, sys
from pygame.locals import *
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode (GPIO.BOARD)
GPIO.setup(26, GPIO.OUT)
GPIO.output(26,GPIO.LOW)

pygame.init()
BLACK = (0,0,0)
WIDTH = 100
HEIGHT = 100
windowSurface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)

windowSurface.fill(BLACK)
x = 0
while True:
   for event in pygame.event.get():
      if event.type == QUIT:
            pygame.quit()
            sys.exit()
      if event.type == KEYDOWN:
         key = event.key
         if key == pygame.K_p:
            if x == 0:
               GPIO.output(26,GPIO.HIGH)
               x = 1
            else:
               GPIO.output(26,GPIO.LOW)
               x = 0

blaablaaguy
Posts: 623
Joined: Sun Sep 27, 2015 3:26 pm

Re: Detect keypress using Python

Thu Jan 07, 2016 1:29 pm

Thanks guys, will try when I get a chance.
This signature intentionally left blank.

blaablaaguy
Posts: 623
Joined: Sun Sep 27, 2015 3:26 pm

Re: Detect keypress using Python

Fri Jan 08, 2016 7:39 pm

[quote="gordon77"]This is the code linked to with a bit added, pressing p will toggle gpio pin 26 high and low.

Code: Select all

import pygame, sys
from pygame.locals import *
import RPi.GPIO as GPIO
GPIO.setwarnings(False)
GPIO.setmode (GPIO.BOARD)
GPIO.setup(26, GPIO.OUT)
GPIO.output(26,GPIO.LOW)

pygame.init()
BLACK = (0,0,0)
WIDTH = 100
HEIGHT = 100
windowSurface = pygame.display.set_mode((WIDTH, HEIGHT), 0, 32)

windowSurface.fill(BLACK)
x = 0
while True:
   for event in pygame.event.get():
      if event.type == QUIT:
            pygame.quit()
            sys.exit()
      if event.type == KEYDOWN:
         key = event.key
         if key == pygame.K_p:
            if x == 0:
               GPIO.output(26,GPIO.HIGH)
               x = 1
            else:
               GPIO.output(26,GPIO.LOW)
               x = 0
[/quote}

It worked, but not without a display connected. Maybe I should have mentioned that first. Can I trick the pi into thinking that it is connected to a screen?
This signature intentionally left blank.

blaablaaguy
Posts: 623
Joined: Sun Sep 27, 2015 3:26 pm

Re: Detect keypress using Python

Fri Jan 08, 2016 7:44 pm

Oh wait it does work without a display. Must have stopped running the code and tries without realising... Or maybe it was just fairy magic. Thanks for the help!
This signature intentionally left blank.

Return to “Python”