2

I have a python program that loops through some GPIO commands. How can I break the loop at any time during the loop by pressing the Enter key. So far I have this...

import sys
import select
import os
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.OUT)

i = 0
while True:
     os.system('cls' if os.name == 'nt' else 'clear')
     print "I'm doing stuff. Press Enter to stop me!"
     print i
     GPIO.output(3, GPIO.HIGH)
     time.sleep(1)
     GPIO.output(3, GPIO.LOW)
     time.sleep(1)
     GPIO.output(3, GPIO.HIGH)
     time.sleep(1)
     GPIO.output(3, GPIO.LOW)
     time.sleep(1)
     if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
         line = raw_input()
         break
     i += 1

This works but once pressing Enter to break the loop I have to wait until the GPIO.output commands have finished before the loop will break. I want it to break immediately.

  • 1
    This is not really a Pi question. Check more often, or interrupt by pressing control C. – joan Aug 28 '14 at 7:26
  • Try using subprocess or a multi-tasking module to run the GPIO data for you. The main problem is the time.sleep() which will stop until its over. – James Clarke Aug 28 '14 at 13:10
2

You need to change the length of the time.sleep() to the length of time you are willing to wait between pressing Enter and breaking out of the loop. time.sleep() will take a floating point input, so you can specify times like 0.1s if necessary.

If you need the loop to break absolutely immediately, you will probably need a separate dedicated process to watch the keyboard. If breaking before the next change in GPIO level is sufficient, try reducing the length of the loop, so there is only one time.sleep() per check of the keyboard, and using logic to decide what to do with the GPIO each time, like so:

import sys
import select
import os
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)
GPIO.setup(3, GPIO.OUT)

i = 0
toggle = False

os.system('cls' if os.name == 'nt' else 'clear')
print "I'm doing stuff. Press Enter to stop me!"
while True:
    print i
    if toggle:
        GPIO.output(3, GPIO.HIGH)
    else:
        GPIO.output(3, GPIO.LOW)
    time.sleep(1)
    if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
        line = raw_input()
        break
    i += 1
    toggle = not toggle

If you need to be able to break out of the loop faster than you are toggling the GPIO, then use a shorter sleep and add some more logic to count the number of loops between changes of the GPIO.

1

Maybe this helps a little: https://stackoverflow.com/questions/5114292/break-interrupt-a-time-sleep-in-python

Also you might want to consider the hints given in the comments section.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.