Python Forum

Full Version: Best way to blink an output every 500 milliseconds?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all, interesting problem in Python... I'm working on a project that I will eventually run on a Raspberry Pi, so I'm utilizing Python to manipulate the GPIO. One of the outputs needs to turn on and off at 1 Hz, or every 500 milliseconds. As you may know, there's no native way to get milliseconds in Python, other than to use time.ctime or something along those lines and multiply by 1000, but I'm afraid that may give me a sort of lopsided output in practice. Ideally I'd just like to be able to run time.sleep for 500 milliseconds or something along those lines, but I don't think I can do that either.

Another problem I will need to solve is to find a way to blink this output independent of the rest of my code, as I have several other timed operations and I don't want them to get "paused" while I'm waiting to turn this output on or off. I'm not sure if I need to look into threading, or if again, there's some other more slick way to handle it.

I'd appreciate your thoughts and suggestions! Really hoping I don't have to go back to C++ for this project, because while it does seem to handle timed operations a bit better, it's certainly not as easy to work with. Sick
Exact timing is nearly impossible with Python, because it's running in a VM, which is running on an OS, where are many other processes are running.
A solution can be to control a PIN via PWM, if you need a accurate timing. But you'll get a drift after a duration. I think also the clock is not very accurate.

The RPi.GPIO Library can do also software PWM which works with (software?) interrupts. Look here: http://raspi.tv/2013/rpi-gpio-0-5-2a-now...-to-use-it

If you don't need exact timing, you can just start a background thread.

import threading
import RPi.GPIO as GPIO


def blink():
    while True:
        time.sleep(0.5)
        GPIO.output(22, True)
        time.sleep(0.5)
        GPIO.output(22, False)


GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.OUT)

thread = threading.Thread(target=blink)
thread.setDaemon(True)
thread.start()

# blink for 20 seconds
time.sleep(20)
# after this line the interpreter quits, because there are no more non-Daemon-Threads running.
I did not test the code. Just written out of my head.
(Jul-24-2017, 02:32 PM)DeaD_EyE Wrote: [ -> ]Exact timing is nearly impossible with Python, because it's running in a VM, which is running on an OS, where are many other processes are running.
A solution can be to control a PIN via PWM, if you need a accurate timing. But you'll get a drift after a duration. I think also the clock is not very accurate.

The RPi.GPIO Library can do also software PWM which works with (software?) interrupts. Look here: http://raspi.tv/2013/rpi-gpio-0-5-2a-now...-to-use-it

If you don't need exact timing, you can just start a background thread.

import threading
import RPi.GPIO as GPIO


def blink():
    while True:
        time.sleep(0.5)
        GPIO.output(22, True)
        time.sleep(0.5)
        GPIO.output(22, False)


GPIO.setmode(GPIO.BCM)
GPIO.setup(22, GPIO.OUT)

thread = threading.Thread(target=blink)
thread.setDaemon(True)
thread.start()

# blink for 20 seconds
time.sleep(20)
# after this line the interpreter quits, because there are no more non-Daemon-Threads running.
I did not test the code. Just written out of my head.

Wow, TIL that sleep accepts decimal values! I didn't see that referenced anywhere but maybe I was looking too hard.

Also - that example works perfectly, just gave it a shot. Thanks!