Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #91983 > unrolled thread

Keypress Input

Started byJohn McKenzie <davros@bellaliant.net>
First post2015-06-03 18:22 +0000
Last post2015-08-16 19:45 +0000
Articles 15 on this page of 35 — 11 participants

Back to article view | Back to comp.lang.python


Contents

  Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-03 18:22 +0000
    Re: Keypress Input Laura Creighton <lac@openend.se> - 2015-06-03 20:59 +0200
    Re: Keypress Input Gary Herron <gherron@digipen.edu> - 2015-06-03 12:15 -0700
    Re: Keypress Input Gary Herron <gherron@digipen.edu> - 2015-06-03 11:47 -0700
    Re: Keypress Input Laura Creighton <lac@openend.se> - 2015-06-04 12:50 +0200
    Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-06 18:28 +0000
      Re: Keypress Input Laura Creighton <lac@openend.se> - 2015-06-06 22:52 +0200
      Re: Keypress Input Chris Angelico <rosuav@gmail.com> - 2015-06-07 07:20 +1000
      Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-06-06 22:31 -0600
    Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-15 05:15 +0000
      Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-16 15:09 +0000
      Re: Keypress Input Christian Gollwitzer <auriocus@gmx.de> - 2015-06-19 07:20 +0200
        Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-20 14:59 +0000
        Re: Keypress Input Rick Johnson <rantingrickjohnson@gmail.com> - 2015-07-15 18:03 -0700
          Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-07-15 22:30 -0600
            Re: Keypress Input Rick Johnson <rantingrickjohnson@gmail.com> - 2015-07-16 10:22 -0700
              Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-07-16 15:27 -0600
          Re: Keypress Input Terry Reedy <tjreedy@udel.edu> - 2015-07-16 02:08 -0400
            Re: Keypress Input Rick Johnson <rantingrickjohnson@gmail.com> - 2015-07-16 11:30 -0700
          Re: Keypress Input Terry Reedy <tjreedy@udel.edu> - 2015-07-16 03:10 -0400
          Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-07-16 15:29 -0600
    Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-15 05:23 +0000
      Re: Keypress Input Oscar Benjamin <oscar.j.benjamin@gmail.com> - 2015-06-15 12:22 +0100
        Re: Keypress Input Grant Edwards <invalid@invalid.invalid> - 2015-06-15 15:22 +0000
      Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-06-16 11:15 -0600
        Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-16 20:06 +0000
          Re: Keypress Input Grant Edwards <invalid@invalid.invalid> - 2015-06-16 20:49 +0000
            Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-06-16 19:22 -0600
            Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-06-18 16:42 -0600
        Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-06-20 15:02 +0000
          Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-06-20 10:30 -0600
    Re: Keypress Input Paul Rubin <no.email@nospam.invalid> - 2015-06-16 14:22 -0700
    Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-07-15 19:05 +0000
      Re: Keypress Input Michael Torrie <torriem@gmail.com> - 2015-07-15 13:17 -0600
        Re: Keypress Input John McKenzie <davros@bellaliant.net> - 2015-08-16 19:45 +0000

Page 2 of 2 — ← Prev page 1 [2]


#93967

FromMichael Torrie <torriem@gmail.com>
Date2015-07-16 15:29 -0600
Message-ID<mailman.614.1437082193.3674.python-list@python.org>
In reply to#93888
On 07/16/2015 01:10 AM, Terry Reedy wrote:
> On 7/16/2015 12:30 AM, Michael Torrie wrote:
>> On 07/15/2015 07:03 PM, Rick Johnson wrote:
>>> <too much to quote>
>>
>> I think you've missed the whole point of the OP's project.  He doesn't
>> want to make a GUI.  He simply wants to have his program do something
>> like blink an LED when someone presses a big red button.  He just wanted
>> a quick way to test things out since his big red button can emulate a
>> USB keyboard.  So all he needed was a simple console app that can fetch
>> keystrokes.  In the end, though GPIO is very simple both electrically
>> and in terms of Python, so that is the ultimate route he will go.  If
>> you read his last post you'll find he says this.
> 
> Rick pretty much acknowledged what you said in this paragraph.
> 
> "You may have solved your input capturing problem, and i
> don't think a GUI is the preferred solution for a
> graphically deficient device anyhow, but you may well need a
> GUI in the future, and this would be a fine example from which
> to learn."
> 
> It is a fine example.

Good to know.  With some posters it's hard to glean the good bits from
the ramblings.

[toc] | [prev] | [next] | [standalone]


#92622

FromJohn McKenzie <davros@bellaliant.net>
Date2015-06-15 05:23 +0000
Message-ID<Ojtfx.178941$Jv.137884@fx26.iad>
In reply to#91983
 Thank to the others who joined in and posted replies.

 Michael, your assumption is correct. To quote my original post, "and I 
want this working on a Raspberry Pi." Doing a superficial look at curses 
and getch it looks excessively complicated. I was under the impression it 
was not multi-platform and Linux was excluded. Searching for getch and 
raspberry pi on the web I see it is not and is available for Raspian.

 Worried about implementing it but I will consider it again. May spend 
time reading about during my treatment tomorrow as the hospital has wifi 
and Internet access and I am allowed to have my laptop there.

[toc] | [prev] | [next] | [standalone]


#92626

FromOscar Benjamin <oscar.j.benjamin@gmail.com>
Date2015-06-15 12:22 +0100
Message-ID<mailman.481.1434367364.13271.python-list@python.org>
In reply to#92622
On 15 June 2015 at 06:23, John McKenzie <davros@bellaliant.net> wrote:
>
>  Thank to the others who joined in and posted replies.
>
>  Michael, your assumption is correct. To quote my original post, "and I
> want this working on a Raspberry Pi." Doing a superficial look at curses
> and getch it looks excessively complicated. I was under the impression it
> was not multi-platform and Linux was excluded. Searching for getch and
> raspberry pi on the web I see it is not and is available for Raspian.

I'm not sure what you mean but you can write a getch function for
Unixy systems using the tty module (I can't remember where I
originally borrowed this code from):

import sys, tty, termios

def getch():
    fd = sys.stdin.fileno()
    oldsettings = termios.tcgetattr(fd)
    try:
        tty.setraw(sys.stdin.fileno())
        c = sys.stdin.read(1)
    finally:
        termios.tcsetattr(fd, termios.TCSADRAIN, oldsettings)
    return c

while True:
    key = getch()
    print("key: '%c'  code: '%d'" % (key, ord(key)))
    if key == 'q':
        break

This puts the terminal in "raw mode" and waits for a key-press. Once a
key is pressed the terminal is restored to it's previous mode (most
likely not raw mode) and the character is returned. This is important
because once your program finishes you don't want the terminal to be
in raw mode. If the terminal goes weird you can usually fix it by
typing "reset" and pressing enter.

Note that going into raw mode has other implications such as not being
able to exit your program with ctrl-c or suspend with ctrl-z etc. You
can explicitly process those kinds of contrl keys with something like:

while True:
    key = getch()
    if 1 <= ord(key) <= 26:
        ctrl_key = chr(ord(key) + 64)
        print("ctrl-%c" % ctrl_key)
        if ctrl_key == 'C':
            break
    else:
        print("key: '%c'" % key)


--
Oscar

[toc] | [prev] | [next] | [standalone]


#92639

FromGrant Edwards <invalid@invalid.invalid>
Date2015-06-15 15:22 +0000
Message-ID<mlmqkc$dnq$1@reader1.panix.com>
In reply to#92626
On 2015-06-15, Oscar Benjamin <oscar.j.benjamin@gmail.com> wrote:

> Note that going into raw mode has other implications such as not
> being able to exit your program with ctrl-c or suspend with ctrl-z
> etc. You can explicitly process those kinds of contrl keys with
> something like:
>
> while True:
>     key = getch()
>     if 1 <= ord(key) <= 26:
>         ctrl_key = chr(ord(key) + 64)
>         print("ctrl-%c" % ctrl_key)
>         if ctrl_key == 'C':
>             break
>     else:
>         print("key: '%c'" % key)

It's probably better (at least on Linux) to just enable handling of
those characters in by setting the ISIG lflag:

    def getch():
        fd = sys.stdin.fileno()
        oldsettings = termios.tcgetattr(fd)
        try:
            tty.setraw(sys.stdin.fileno())
    
            # enable handling of ctrl-C, ctrl-Z, etc.            
            attr = termios.tcgetattr(fd)
            attr[3] |= termios.ISIG
            termios.tcsetattr(fd,termios.TCSANOW,attr)
    
            c = sys.stdin.read(1)
    
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, oldsettings)
        return c

It would be a bit cleaner if the termios module supported the the
cfmakeraw(3) function, then you could do it this way and save a couple
of system calls:

    def getch():
        fd = sys.stdin.fileno()
        oldsettings = termios.tcgetattr(fd)
        try:
            newsettings = termios.makeraw(oldsettings)
            newsettings[3] |= termios.ISIG
            termios.tcsetattr(fd,termios.TCSANOW,newsettings)
            c = sys.stdin.read(1)
        finally:
            termios.tcsetattr(fd, termios.TCSADRAIN, oldsettings)
        return c

[I'm a bit surprised that after all these years using literal integers
to index into the attribute list is the "right" way.]
        
-- 
Grant Edwards               grant.b.edwards        Yow! Well, O.K.
                                  at               I'll compromise with my
                              gmail.com            principles because of
                                                   EXISTENTIAL DESPAIR!

[toc] | [prev] | [next] | [standalone]


#92689

FromMichael Torrie <torriem@gmail.com>
Date2015-06-16 11:15 -0600
Message-ID<mailman.519.1434474965.13271.python-list@python.org>
In reply to#92622
On 06/14/2015 11:23 PM, John McKenzie wrote:
>  Thank to the others who joined in and posted replies.
> 
>  Michael, your assumption is correct. To quote my original post, "and I 
> want this working on a Raspberry Pi." Doing a superficial look at curses 
> and getch it looks excessively complicated. I was under the impression it 
> was not multi-platform and Linux was excluded. Searching for getch and 
> raspberry pi on the web I see it is not and is available for Raspian.
> 
>  Worried about implementing it but I will consider it again. May spend 
> time reading about during my treatment tomorrow as the hospital has wifi 
> and Internet access and I am allowed to have my laptop there.

I'm not sure exactly what you mean by not available on Linux.  Curses
provides the same API on all platforms it runs on and I know it can read
keystrokes.  Curses getch is certainly available on Linux.  In fact,
here's an example:

http://stackoverflow.com/questions/10693256/how-to-accept-keypress-in-command-line-python

Again, however, you probably can't just fire up your program from a
startup script and have it run automatically, since stdin for a script
is not going to be the tty.  One idea would be to run your program from
init as a getty on tty1 (the default tty).  That would run as soon as it
boots up.

Though question for you. Why are you hooking the arcade buttons up to a
kade USB device?  Would not it be far simpler to hook the buttons
directly to a GPIO pin and read them from python?  You're already using
GPIO pins to run the LEDs.  Seems like the usb keyboard hack is
unnecessary and it's making your task more difficult.

[toc] | [prev] | [next] | [standalone]


#92697

FromJohn McKenzie <davros@bellaliant.net>
Date2015-06-16 20:06 +0000
Message-ID<Cl%fx.2$WK.0@fx07.iad>
In reply to#92689
 That was the impression I got reading some comments people made online 
and doing research, so I focused on tkinter. As I mentioned in the 4th 
sentence of the post you quoted I discovered that was not the case, but 
by then I had already done some work on the tkinter script so I kept with 
it.

 Before I actually tried any of this and was just thinking of it 
conceptually I bought the Kade device. It was my hope that it would save 
on soldering, something I hate so very, very much, and I had not started 
learning Python at that point. It never occurred to me something so 
simple as keystrokes would not be present in Python, a language rated as 
being terrific by everyone I know who knows it.

 Out of great ignorance I thought I could hook up the Kade device and do 
something like if keypress == r then do this. Also out of ignorance I 
thought that using the GPIO would require days of soldering and 
incredibly complicated coding to talk to the pins.

 Only since I got much more deep into actually doing this did I start to 
find out otherwise. Spent the last few days looking at breakout boards to 
see if they would make the wiring easier to test out. When I saw one that 
had built in electrical protection (RaspIO Pro) I thought about getting 
it and going the route you suggest. However, I cannot find any option 
that does not require a breadboard. The lack of compactness and all the 
exposed wires does bother me a bit. More than it should, but I need a 
compact setup I can place outdoors. Breadboards and loose wires worry me 
in this case.

 Still, I must admit I spent the last 3 or 4 days thinking about exactly 
what you said and I may do it that way after all just to get it to work 
software wise.

 And BTW, I am not using any GPIO for the lights, the LED light strip is 
hooked up to a Blinkstick Pro through a USB port.

[toc] | [prev] | [next] | [standalone]


#92700

FromGrant Edwards <invalid@invalid.invalid>
Date2015-06-16 20:49 +0000
Message-ID<mlq25a$188$1@reader1.panix.com>
In reply to#92697
On 2015-06-16, John McKenzie <davros@bellaliant.net> wrote:

> It never occurred to me something so simple as keystrokes would not
> be present in Python, a language rated as being terrific by everyone
> I know who knows it.

Ah, but in reality "keystrokes" is not simple at all.  Keyboards and
input handling is a very messy, complicated area.

-- 
Grant Edwards               grant.b.edwards        Yow! FOOLED you!  Absorb
                                  at               EGO SHATTERING impulse
                              gmail.com            rays, polyester poltroon!!

[toc] | [prev] | [next] | [standalone]


#92716

FromMichael Torrie <torriem@gmail.com>
Date2015-06-16 19:22 -0600
Message-ID<mailman.534.1434504141.13271.python-list@python.org>
In reply to#92700
On 06/16/2015 02:49 PM, Grant Edwards wrote:
> On 2015-06-16, John McKenzie <davros@bellaliant.net> wrote:
> 
>> It never occurred to me something so simple as keystrokes would not
>> be present in Python, a language rated as being terrific by everyone
>> I know who knows it.
> 
> Ah, but in reality "keystrokes" is not simple at all.  Keyboards and
> input handling is a very messy, complicated area.

If you do choose to go with the GPIO route, unless your code for
accessing the GPIO lines does debouncing, you will have to debounce the
key.  There are lots of examples out there (most in C on the arduino,
but still applicable). Most of them check for a button press, then do a
timer count-down to let things settle out before recording a button
press.  So it's still complicated even if you talk directly to the
buttons!  No way around some complexity though.

[toc] | [prev] | [next] | [standalone]


#92858

FromMichael Torrie <torriem@gmail.com>
Date2015-06-18 16:42 -0600
Message-ID<mailman.617.1434667341.13271.python-list@python.org>
In reply to#92700
On 06/18/2015 01:35 PM, Oscar Benjamin wrote:
> I use the following. I found in testing that when you push the button it
> prints 'Button pressed' 10 times a second (in actual use it calls poweroff
> so I guess bounce isn't an issue there). Is there some reason it needs to
> be cleverer in this case?

Yes, that would be expected, given your code has a while loop that never
exits.  Just curious what you expect the code to do that it's not doing.

You are probably right that debouncing isn't important in your
application.  So just add your poweroff command after the print()
statement, and break out of the loop:

...
while True:
    time.sleep(0.1)
    if not GPIO.input(PIN_NUM):
        print('Button pressed')
        # run shutdown command here
        os.system('/usr/sbin/shutdown')
        break


[toc] | [prev] | [next] | [standalone]


#92915

FromJohn McKenzie <davros@bellaliant.net>
Date2015-06-20 15:02 +0000
Message-ID<Cgfhx.15512$C_.11002@fx15.iad>
In reply to#92689
 Guys, thanks for the various code examples for GPIO and the warning 
about debouncing issues. I am still considering going the route of more 
complex wiring and doing it a more traditional GPIO way.

[toc] | [prev] | [next] | [standalone]


#92917

FromMichael Torrie <torriem@gmail.com>
Date2015-06-20 10:30 -0600
Message-ID<mailman.660.1434817849.13271.python-list@python.org>
In reply to#92915
On 06/20/2015 09:02 AM, John McKenzie wrote:
> 
>  Guys, thanks for the various code examples for GPIO and the warning 
> about debouncing issues. I am still considering going the route of more 
> complex wiring and doing it a more traditional GPIO way.

You can wire up the button without a little breadboard or circuit board
using this general diagram:

https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/robot/buttons_and_switches/

Just solder the resistors to the wires themselves, and keep them close
to the pi to keep them clean.  Then you you just have to route one wire
per switch, with one common wire hitting the other side of each switch.
 Probably you will want to use the pull-up version where the switch
pulls the signal down to ground.  You may want to use a header to plug
into the rpi.  But besides that should just be a matter of routing wires.

But on the original track, you might want to ask on the kade forums if
there's any way to interact with kade and get events besides HID
emulation.  For example, maybe you could communicate with it over a
virtual serial port.  Or some other protocol so you don't have to worry
about ttys and Linux kernel HID handling for your program, especially in
a headless environment.  Using HID emulation makes sense in a MAME
arcade environment but not for a headless raspberry pi application.

[toc] | [prev] | [next] | [standalone]


#92702

FromPaul Rubin <no.email@nospam.invalid>
Date2015-06-16 14:22 -0700
Message-ID<87r3pbs601.fsf@jester.gateway.sonic.net>
In reply to#91983
John McKenzie <davros@bellaliant.net> writes:
>  Would like a set-up where something happens when a key is pressed. Not 
> propose a question, have the user type something, then hit return, then 
> something happens, but just the R key is pressed, something happens, 

The quick answer is that you want raw mode tty input.  Type "stty raw"
to the shell, and sys.stdin.read(1) will give you the bytes of the typed
characters immediately.  Use "stty -raw" to put it back in cooked mode,
or maybe better, "stty sane" to restore normal settings in general.

Yes there are messy details like function keys actually sending several
characters.  In practice you'll also want to control the tty modes from
your program instead of the shell, but that should get you started.  You
may also want to turn off echo, i.e. "stty raw -echo".

[toc] | [prev] | [next] | [standalone]


#93879

FromJohn McKenzie <davros@bellaliant.net>
Date2015-07-15 19:05 +0000
Message-ID<9aypx.126956$r46.110087@fx28.iad>
In reply to#91983
 Hello, all.

 Thanks to everyone who responded to my post.

 I decided to make sure I had something that worked with what I have now 
and used Curses to finish it. However, it turns out that the extra work 
and problems with using GPIO pins and wiring up controllers that way is a 
small amount of headaches and work compared to what I thought it would be 
and the software part is actually easier than doing it this way. So in 
the end I will hooking the Raspberry Pi up directly to the buttons and 
use the Raspberry Pi's GPIO library to do it all.

 For posterity and in case other beginners want to look at it, here is 
what I have with curses that works now. Tried to add a function to cause 
it to only work for a certain amount of time and that did not work. Will 
worry about that when I do the new programme based off of directly 
connected buttons and have those working.

 Thanks everyone.

 Here is the keyboard controls the colours script. (Raspberry Pi B+, 
Blinkstick Pro and LED Adapter, analouge RGB LED light strip.)

import curses
import atexit
import time
from datetime import datetime
from blinkstick import blinkstick

starttime = time.time()

screen = curses.initscr()
curses.noecho()
curses.curs_set(0)
screen.keypad(1)
screen.nodelay(1)

led = blinkstick.find_first()

timered = 0
timeyellow = 0
timeblue = 0

timestamp = str(datetime.now())

colour = 0

screen.addstr("Eflag 1")

while True:
    event = screen.getch()
    if event == ord("q"):
        flog = open('flag1log.text', 'a')
        flog.write(timestamp + '\n' + 'Red Team: ' + str(timered) + '\n' 
+ 'Yellow Team: ' + str(timeyellow) + '\n' + 'Blue Team: ' + str(timeblue) 
+ '\n')
        flog.close()
        curses.endwin()
        break
    elif event == ord("r"):
        colour = 1
        screen.addstr("Red Activated")

    elif event == ord("y"):
        colour = 2
        screen.addstr("Yellow Activated")

    elif event == ord("b"):
        colour = 3
        screen.addstr("Blue Activated")


    if colour == 1:
        led.pulse(red=255, green=0, blue=0, repeats=1, duration=3000, 
steps=50)
        timered += 1
        print timered

    if colour == 2:
        led.pulse(red=255, green=255, blue=0, repeats=1, duration=3000, 
steps=50)
        timeyellow += 1

    if colour == 3:
        led.pulse(red=0, green=0, blue=255, repeats=1, duration=2000, 
steps=50)
        timeblue += 1


    if time.time() == (time.time() + 30):
        flog = open('flag1log.text', 'a')
        flog.write(timestamp + '\n' + 'Red Team: ' + str(timered) + '\n' 
+ 'Yellow Team: ' + str(timeyellow) + '\n' + 'Blue Team: ' + str(timeblue) 
+ '\n')
        flog.close()
        curses.endwin()
        break

[toc] | [prev] | [next] | [standalone]


#93880

FromMichael Torrie <torriem@gmail.com>
Date2015-07-15 13:17 -0600
Message-ID<mailman.548.1436987838.3674.python-list@python.org>
In reply to#93879
On 07/15/2015 01:05 PM, John McKenzie wrote:
>  Hello, all.
> 
>  Thanks to everyone who responded to my post.
> 
>  I decided to make sure I had something that worked with what I have now 
> and used Curses to finish it. However, it turns out that the extra work 
> and problems with using GPIO pins and wiring up controllers that way is a 
> small amount of headaches and work compared to what I thought it would be 
> and the software part is actually easier than doing it this way. So in 
> the end I will hooking the Raspberry Pi up directly to the buttons and 
> use the Raspberry Pi's GPIO library to do it all.
> 
>  For posterity and in case other beginners want to look at it, here is 
> what I have with curses that works now. Tried to add a function to cause 
> it to only work for a certain amount of time and that did not work. Will 
> worry about that when I do the new programme based off of directly 
> connected buttons and have those working.
> 
>  Thanks everyone.

Thanks for the update! Also I am very glad to hear that using GPIO
doesn't look very difficult.  Good luck on things!

[toc] | [prev] | [next] | [standalone]


#95412

FromJohn McKenzie <davros@bellaliant.net>
Date2015-08-16 19:45 +0000
Message-ID<3L5Ax.73239$E26.11652@fx20.iad>
In reply to#93880
 Thanks again to everyone who tried to help.

 Michael, I especially appreciate your encouragement and chiming in to 
point out that telling newbies to learn everything there is before 
posting question was not helpful in getting more people using Python.

 Have the Pi wired up directly to the buttons, read up on the GPIO 
library and I just posted for help regarding the error messages I am 
getting from my Python buttons script.

 Thanks.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | comp.lang.python


csiph-web