Set GPIO in a precisely time using usleep()

222 views
Skip to first unread message

andrea...@hs-owl.de

unread,
Dec 3, 2015, 8:25:45 AM12/3/15
to BeagleBoard
Hi,

I am trying to control a servo with my BeagleBoneBlack using Angstrom. I must have a high-level on a GPIO for 1 millisecond. I use the following simple code:

while(1){
servo.setValue(BlackLib::low);
usleep(19000);
servo.setValue(BlackLib::high);
usleep(1000);
}

The GPIO is high for about 1.5 Milliseconds. The usleep()-function is not linear, so it did not work with any other value e.g. usleep(500). Sometimes I decrease the value by one (1 microsecond) but the time decrease by 100 microseconds.
Has anybody an idea what could be wrong? 

William Hermans

unread,
Dec 3, 2015, 9:10:31 AM12/3/15
to beagl...@googlegroups.com
The GPIO is high for about 1.5 Milliseconds. The usleep()-function is not linear, so it did not work with any other value e.g. usleep(500). Sometimes I decrease the value by one (1 microsecond) but the time decrease by 100 microseconds.
Has anybody an idea what could be wrong? 

First of all, usleep() is not your problem. The problem most likely is related to kernel latency. You could improve this by using a PREEMPT RT kernel, but that will only at best give you 95% determinism.

Second, since you have not made your code public, we can not tell if servo.setValue() is well written or not. In the context of determinism. I will say however if you're not using mmap() with /dev/mem/ on the GPIO registers directly. Your code will be "slow", and not very deterministic.

Lastly, if you need absolute determinism, you had better start using the PRUs . . .
 

--
For more options, visit http://beagleboard.org/discuss
---
You received this message because you are subscribed to the Google Groups "BeagleBoard" group.
To unsubscribe from this group and stop receiving emails from it, send an email to beagleboard...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

William Hermans

unread,
Dec 3, 2015, 9:13:45 AM12/3/15
to beagl...@googlegroups.com
I will say that it is very likely that if you switch to a PREEMPT RT kernel, that determinism down to 1ms should be easily achievable. So long as you do not have too much in the way of background processes running at the same time.

Przemek Klosowski

unread,
Dec 3, 2015, 7:12:42 PM12/3/15
to beagl...@googlegroups.com
On Thu, Dec 3, 2015 at 6:30 AM, <andrea...@hs-owl.de> wrote:
> Hi,
>
> I am trying to control a servo with my BeagleBoneBlack using Angstrom. I
> must have a high-level on a GPIO for 1 millisecond. I use the following
> simple code

It looks like you're trying to generate the servo PWM output in
software. This seems like a wrong way; you should use PWM hardware
units instead. There will always be some jitter from software context
switches, other OS activity and/or memory/cache/TLB latencies, and the
servo will be jerky.

Set up the PWM or PRU to generate your output. This way, software will
only be activated when you need to change the output values.

andrea...@hs-owl.de

unread,
Dec 4, 2015, 8:45:32 AM12/4/15
to BeagleBoard
Thanks all for the response.
It is right, I try to generate a PWM, because all hardware PWMs are occupied.

I will check the PREEMPT RT kernel.
Reply all
Reply to author
Forward
0 new messages