YodaDaCoda
Posts: 4
Joined: Fri Jun 21, 2013 4:45 am

Millisecond-level timing on RPi

Tue Jun 25, 2013 2:33 am

Firstly, I apologise if this has already been answered elsewhere. It is not my intention to duplicate existing questions. I simply can't find a direct answer to my questions.

Given that the RPi runs a Linux system and that I'll be programming in Python, both of which introduce potential delays to time-sensitive code, how accurately can I expect to get timing on the RPi? I'm replacing an existing system which is capable of millisecond-level timing, but for the purposes of the application anything within about 5ms should be acceptable.

The GPIO pin will be connected to a relay, which will actuate a pneumatic device. I need to actuate the device for a precise number of milliseconds (within a few ms tolerance).

Example code below, for actuating my device for ~1000ms.

Code: Select all

import time

#returns ms since the epoch
def millis():
        return time.time() * 1000

def switchTheThing(howlong):
    #set GPIO pin high
    start = millis()
    while ( (start + howlong) > millis() ):
        pass
    #set GPIO pin low

def main():
    #bunch of code
    switchTheThing(1000)    #actuate the pneumatics for 1000ms
    #bunch more code
Can I expect reliable sub-5ms timing with this code?
If not, what might I be able to expect as maximum delay (I should be able to work around larger delays, up to a point)?
If not, what's the cheapest way of achieving such precise timings (add-on board or such)?
If this is an OK way to go, are there any improvements to the way I'm performing the timing calculations? It feels a little clumsy.

elatllat
Posts: 1337
Joined: Sat Dec 17, 2011 5:05 pm

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 4:16 am

no; you need to look in to real time operating systems if you want reliable timing.
http://wiki.linuxcnc.org/cgi-bin/wiki.p ... nd_patches
SBC with 32GB RAM: https://hardkernel.com

FAQ : https://raspberrypi.stackexchange.com

Unanswered: https://www.raspberrypi.org/forums/search.php?search_id=unanswered

drgeoff
Posts: 10831
Joined: Wed Jan 25, 2012 6:39 pm

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 11:52 am

Quite apart from the OS, if you are using a mechanical relay, millisecond-level timing is very questionable.
Quis custodiet ipsos custodes?

User avatar
pluggy
Posts: 3635
Joined: Thu May 31, 2012 3:52 pm
Location: Barnoldswick, Lancashire,UK
Contact: Website

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 1:19 pm

I have reasonable millisecond level timing on Raspdian. Using WiringPi, C and interrupts. Not quite up to real-time standards but more than acceptable considering the flexibility of multi-tasking.

https://projects.drogon.net/raspberry-pi/

Image

This is a live plot of my energy usage. The Red and Blue lines are useage and PV panel out put. Each has a bright thin line superimposed over a paler, broader line. The bright thin line get the data from an Arduino which is real time, the broader pale line underneath is generated by the Pi. Both measure the time between pulses from the same electric meters. The differences are as much up to the differing algorythms used as much as the timing. The raw outputs from the Arduino and the Pi are pretty close. At high power usage, the pulses are several times a second.
Don't judge Linux by the Pi.......
I must not tread on too many sacred cows......

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 1:54 pm

Relatively straightforward. Your problem will be no one has bothered to write the code so far, being more interested in microsecond delays rather than millisecond ones. You can use DMA.

Sub-millisecond pulses being generated and captured: http://www.raspberrypi.org/phpBB3/viewt ... 03#p374403

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 26716
Joined: Sat Jul 30, 2011 7:41 pm

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 2:08 pm

YodaDaCoda wrote:Firstly, I apologise if this has already been answered elsewhere. It is not my intention to duplicate existing questions. I simply can't find a direct answer to my questions.

Given that the RPi runs a Linux system and that I'll be programming in Python, both of which introduce potential delays to time-sensitive code, how accurately can I expect to get timing on the RPi? I'm replacing an existing system which is capable of millisecond-level timing, but for the purposes of the application anything within about 5ms should be acceptable.

The GPIO pin will be connected to a relay, which will actuate a pneumatic device. I need to actuate the device for a precise number of milliseconds (within a few ms tolerance).

Example code below, for actuating my device for ~1000ms.

Code: Select all

import time

#returns ms since the epoch
def millis():
        return time.time() * 1000

def switchTheThing(howlong):
    #set GPIO pin high
    start = millis()
    while ( (start + howlong) > millis() ):
        pass
    #set GPIO pin low

def main():
    #bunch of code
    switchTheThing(1000)    #actuate the pneumatics for 1000ms
    #bunch more code
Can I expect reliable sub-5ms timing with this code?
If not, what might I be able to expect as maximum delay (I should be able to work around larger delays, up to a point)?
If not, what's the cheapest way of achieving such precise timings (add-on board or such)?
If this is an OK way to go, are there any improvements to the way I'm performing the timing calculations? It feels a little clumsy.
Might be worth writing the time critical stuff in C and importing a library to Python. Would likely be slightly more accurate than Python.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

User avatar
pluggy
Posts: 3635
Joined: Thu May 31, 2012 3:52 pm
Location: Barnoldswick, Lancashire,UK
Contact: Website

Re: Millisecond-level timing on RPi

Tue Jun 25, 2013 2:23 pm

Back a couple of posts, James, I was making positive noises about the capabilities of the Pi..... ;)
Don't judge Linux by the Pi.......
I must not tread on too many sacred cows......

YodaDaCoda
Posts: 4
Joined: Fri Jun 21, 2013 4:45 am

Re: Millisecond-level timing on RPi

Wed Jun 26, 2013 1:48 am

Thankyou all for your comments. You've certainly given me some things to look into.

FWIW, I've conducted my own tests and seen generally sub-ms accuracy, with occasional spikes. Manually loading the system as it would be in production has negligible affect on the accuracy of the timing. Unfortunately, the spikes I'm seeing seem fairly regular and are as high as 9ms when it's sitting relatively idle. I can only assume this is Python's garbage collection interrupting my timings. (I also saw some other spikes ranging between 150-2000ms, but that was right as my network went funny, and I'm willing to chalk them up to circumstance for now)

Regarding PWM, from what I've read the RPi has one hardware PWM (on pin 12) which should provide the precise timings I'm looking for. Is this a feasible alternative to running a realtime kernel or additional realtime device?

If PWM will do what I'm after, it seems that I would need to do something like the below code. Can anyone tell me if I'm on the right track here?

Code: Select all

import time
import RPi.GPIO
t=12000 #actuation time in ms
pin=12 #GPIO pin to use
GPIO.setmode(GPIO.BOARD)
GPIO.setup(pin, GPIO.OUT)
p = GPIO.PWM(pin, 1/(t/1000))
p.start(1)
time.sleep(t/1000)
p.stop()
GPIO.cleanup()

Alfie
Posts: 3
Joined: Thu Apr 17, 2014 3:48 pm

Re: Millisecond-level timing on RPi

Fri Mar 13, 2015 8:22 pm

Use wiringpi.micros() -- available in python but apparently undocumented. I use it all the time in complex code. For wiringpi, see https://pypi.python.org/pypi/wiringpi2 -- and beginners install giude, see http://raspi.tv/how-to-install-wiringpi ... pi#install .. This is an example of it's general use..

Code: Select all

import wiringpi2
for n1 in range(1,10): print wiringpi2.micros()

User avatar
pluggy
Posts: 3635
Joined: Thu May 31, 2012 3:52 pm
Location: Barnoldswick, Lancashire,UK
Contact: Website

Re: Millisecond-level timing on RPi

Sat Mar 14, 2015 2:48 am

Lets do the timewarp again......
Don't judge Linux by the Pi.......
I must not tread on too many sacred cows......

User avatar
joan
Posts: 14960
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Millisecond-level timing on RPi

Sat Mar 14, 2015 8:14 am

Alfie wrote: ...

Code: Select all

import wiringpi2
for n1 in range(1,10): print wiringpi2.micros()
Standard Python will let you show nanoseconds.

Code: Select all

#!/usr/bin/env python

import time

epoch = time.time()

def nanos():
   return int((time.time()-epoch)*1e9)

time.sleep(1)

for i in range(10):
   print(nanos())

User avatar
rurwin
Forum Moderator
Forum Moderator
Posts: 4258
Joined: Mon Jan 09, 2012 3:16 pm
Contact: Website

Re: Millisecond-level timing on RPi

Sat Mar 14, 2015 8:46 am

It rather depends how important the timing is. With Python and Linux you will get, as you have found, occasional spikes and some of them can be very large. There is no way* to get rid of them entirely, but you may not need to. On the other hand if being 100ms off now and then makes your nuclear reactor meltdown or your toy robot crash into a wall at 70mph, you may want to look for another solution.

*OK, it may be possible using code at the device-driver level, but unless something is available that fits your needs already, it would be easier to use an Arduino.

Return to “Advanced users”