Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python whats the most efficient way to wait for input

I have a python program I want to run in the background (on a Raspberry Pi) that waits for GPIO input then performs an action and continues waiting for input until the process is killed.

What is the most efficient way to achieve this. My understanding is that using while true is not so efficient. Ideally it would use interrupts - and I could use GPIO.wait_for_edge - but that would need to be in some loop or way of continuing operation upon completion of the handler.

Thanks

like image 922
The Huff Avatar asked Jul 08 '15 21:07

The Huff


2 Answers

According to this: http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio GPIO.wait_for_edge(23, GPIO.FALLING) will wait for a transition on pin 23 using interrupts instead of polling. It'll only continue when triggered. You can enclose it in a try: / except KeyboardInterrupt to catch ctrl-c.

If you want to continue processing then you should register a call back function for your interrupt. See: http://sourceforge.net/p/raspberry-gpio-python/wiki/Inputs/

def callback(channel):
   do something here

GPIO.add_event_detect(channel, GPIO.RISING, callback=my_callback)
continue your program here, likely in some sort of state machine
like image 111
Mark Avatar answered Nov 14 '22 05:11

Mark


I understand that when you say "using while true" you mean polling, which is checking the gpio state at some time interval to detect changes, in the expense of some processing time.

One alternative to avoid polling (from the docs) is wait_for_edge():

The wait_for_edge() function is designed to block execution of your program until an edge is detected.

Which seems to be what you are looking for; the program would suspend execution using epool() IIUC.

Now assuming you meant that you don't want to use GPIO.wait_for_edge() because you don't want to loose GPIO state changes while handling events, you'll need to use threading. One possible solution is putting events in a Queue, and setup:

  • One thread to do the while True: queue.put(GPIO.wait_for_edge(...)).
  • Another thread to perform the Queue.get().
like image 1
jvdm Avatar answered Nov 14 '22 05:11

jvdm