curses is terminal-based, so it cannot detect key release events.Sleep Mode zZ wrote:Python's curses module should be able to do what you want.
Some posts indicate that the keyboard events won't work with the dummy driver:davef21370 wrote:http://www.pygame.org/wiki/HeadlessNoWi ... t=CookBook
Not in a position to test this but might be useful.
On further investigation that would seem to be the case, maybe this would fare better... https://github.com/sangmank/py-showkeySleep Mode zZ wrote:Some posts indicate that the keyboard events won't work with the dummy driver:
No, it doesn't have to be arrow keys, but I would at least like it to be on the keyboard... (that is where all the rest of the controlling is coming from.) I had thought of doing that but almost all the pins will be tied up with all the sensors and motors and stuff.Stephanie wrote:Just wondering if it has to be keyboard arrow keys that you are detecting?
Instead of jumping through hoops to monitor headless console keyboard input, have you thought of using some plain old pushbutton switches connected to GPIO pins?
Pygame seems to get along just fine with RPi.GPIO, and it's pretty straightforward in terms of wiring and detection. For that matter, if you're only using pygame for the keyboard events, maybe you can skip it altogether, by just monitoring some GPIO buttons rather than keyboard keys?
brjhaverkamp wrote:I was wondering if there is an update to this now. what is the best way to detect keypresses/releases?
My set up is a robot cart with a RPi3 on top. I can access it over Wifi with ssh.
On the RPi I have connected the motor controls via GPIO. As a start I want to remote control this via my laptop keyboard via the cursor keys. It has to be able to detect multiple keys, so press "up" to go forward, add "left" to make a turn to the left, release "left" key (leave "up2 pressed) to go forward again. etc.
The pygame library seemed very suited except for the screen requirement and the dummy screen doesn't seem to sufice.
What are the alternatives atm?
It's been such a long time since I was messing with that stuff, I don't remember much about it. I think I messed with the showkey but I think that didn't quite do what I wanted. Like it only gave me key-presses or something like that.brjhaverkamp wrote:Hi,
Thanks for your quick reply. Somewhere above here, someone mentioned py-showkey.
Did you try it? Or is it not worth bothering?
Code: Select all
import RPi.GPIO as GPIO # Import the GPIO Library import os import time # Import the Time library import curses # Set the GPIO modes GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # Set variables for the GPIO motor pins pinMotorAForwards = 9 pinMotorABackwards = 10 pinMotorBForwards = 8 pinMotorBBackwards = 7 # How many times to turn the pin on and off each second Frequency = 20 # How long the pin stays on each cycle, as a percent (here, it's 30%) DutyCycle = 30 # Setting the duty cycle to 0 means the motors will not turn Stop = 0 # Set the GPIO Pin mode GPIO.setup(pinMotorAForwards, GPIO.OUT) GPIO.setup(pinMotorABackwards, GPIO.OUT) GPIO.setup(pinMotorBForwards, GPIO.OUT) GPIO.setup(pinMotorBBackwards, GPIO.OUT) # Set the GPIO to software PWM at 'Frequency' Hertz pwmMotorAForwards = GPIO.PWM(pinMotorAForwards, Frequency) pwmMotorABackwards = GPIO.PWM(pinMotorABackwards, Frequency) pwmMotorBForwards = GPIO.PWM(pinMotorBForwards, Frequency) pwmMotorBBackwards = GPIO.PWM(pinMotorBBackwards, Frequency) # Start the software PWM with a duty cycle of 0 (i.e. not moving) pwmMotorAForwards.start(Stop) pwmMotorABackwards.start(Stop) pwmMotorBForwards.start(Stop) pwmMotorBBackwards.start(Stop) # Turn all motors off def StopMotors(): pwmMotorAForwards.ChangeDutyCycle(Stop) pwmMotorABackwards.ChangeDutyCycle(Stop) pwmMotorBForwards.ChangeDutyCycle(Stop) pwmMotorBBackwards.ChangeDutyCycle(Stop) # Turn both motors forwards def Forwards(): pwmMotorAForwards.ChangeDutyCycle(DutyCycle) pwmMotorABackwards.ChangeDutyCycle(Stop) pwmMotorBForwards.ChangeDutyCycle(DutyCycle) pwmMotorBBackwards.ChangeDutyCycle(Stop) # Turn both motors backwards def Backwards(): pwmMotorAForwards.ChangeDutyCycle(Stop) pwmMotorABackwards.ChangeDutyCycle(DutyCycle) pwmMotorBForwards.ChangeDutyCycle(Stop) pwmMotorBBackwards.ChangeDutyCycle(DutyCycle) # Turn Right def Right(): pwmMotorAForwards.ChangeDutyCycle(Stop) pwmMotorABackwards.ChangeDutyCycle(DutyCycle) pwmMotorBForwards.ChangeDutyCycle(DutyCycle) pwmMotorBBackwards.ChangeDutyCycle(Stop) # Turn Left def Left(): pwmMotorAForwards.ChangeDutyCycle(DutyCycle) pwmMotorABackwards.ChangeDutyCycle(Stop) pwmMotorBForwards.ChangeDutyCycle(Stop) pwmMotorBBackwards.ChangeDutyCycle(DutyCycle) # Here starts the code to make the robot move stdscr = curses.initscr() curses.cbreak() stdscr.keypad(1) stdscr.addstr(0,10,"Hit 'q' to quit") stdscr.nodelay(1) #nodelay(1) give us a -1 back when nothing is pressed Richtung = ' ' while Richtung != ord('q'): #Start of while loop stdscr.refresh() Richtung = stdscr.getch() #Gets the key which is pressed stdscr.addch(20,25,Richtung) if Richtung == ord('e'): StopMotors() if Richtung == ord('a'): Left() if Richtung == ord('s'): Backwards() if Richtung == ord('d'): Right() if Richtung == ord('w'): Forwards() if Richtung == int('-1'): StopMotors() time.sleep(0.04) #I need the timesleep because if not the robot will get a -1 all the time and not move to fast while loop I think, have to work on this. #End of while loop #Important to set everthing back by end of the script curses.nocbreak() stdscr.keypad(0) curses.endwin() StopMotors() GPIO.cleanup()