POTM - December - BSmithyMan - Simple Servo Control

All the latest news and announcements from XCore and XMOS.
Post Reply
User avatar
jason
XCore Expert
Posts: 577
Joined: Tue Sep 08, 2009 5:15 pm
Contact:

POTM - December - BSmithyMan - Simple Servo Control

Post by jason »

Image

Congratulations to BSmithyMan who is this months winner for his Simple Servo Control project.

iqdLpQFa2MQ

A quote from BSmithyMan's project is as follows:
"Basically this is just a really simple single-thread code for driving RC servos. I'm sure there's a smarter way to do some of these steps (the for-loop over signal pins is a bit of a busy wait). This should be relatively high-performing though, and it's easy to fit to any port size. I'm sure it wouldn't be hard to go from here to using a multiplexed output, but I only need a few channels. This should work on just about anything you can hook it up to, but the demo code is set up to use ports on the XC-1."
Once again well done to BSmithyMan, please do check out his project here!

Looking towards the new year - January, please submit your nominations to the main POTM thread here (please ensure criteria are met detailed in this post if you wish to be considered).


User avatar
bsmithyman
Experienced Member
Posts: 126
Joined: Fri Feb 12, 2010 10:31 pm
Contact:

Post by bsmithyman »

Wow, thanks everybody! Hopefully the servo driver code is useful to people

Since I'm here: I've got pretty modest requirements in terms of the number of servos I'm using, but if anyone is interested in helping me figure out how to make it work with more than 8 servos, feel free to have a look. At the moment it's fine for 8 servos, but could theoretically lose some resolution on servos that are all at about the same position if compiled with the Debug profile. The loop over servo channels has to complete within the desired timing resolution. I think the problem would be worse with a 16-bit or 32-bit port, although everything should still work well enough for many purposes, and the maximum error should be maybe 1 degree in the higher port sizes.
User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm
Contact:

Post by Berni »

Well servos don't really use that tight timings (1 to 2 ms of pulse with if i remember correctly) so for 1 degree precision you need about 80us of resolution while the xcore takes 10ns for a instruction cycle. So you have plenty of crunching time and you can always use a timer event to get 10ns resolution. This means doing 16 servos very accurately should be no problem.
User avatar
bsmithyman
Experienced Member
Posts: 126
Joined: Fri Feb 12, 2010 10:31 pm
Contact:

Post by bsmithyman »

Berni wrote:Well servos don't really use that tight timings (1 to 2 ms of pulse with if i remember correctly) so for 1 degree precision you need about 80us of resolution while the xcore takes 10ns for a instruction cycle. So you have plenty of crunching time and you can always use a timer event to get 10ns resolution. This means doing 16 servos very accurately should be no problem.
Thanks Berni,

I think it's a little tighter than that, since the full-scale range is something like 1000 us on the low end to 2000 us on the high end (1-2 ms as you said). So assuming 1000 us range and 90 degrees of sweep (some are more), one degree of resolution is 11.1 us. On the other hand, if you had a 180 degree servo (5.6 us / degree) and say 32 channels, with ~20 instructions per iteration in the for loop (6.4 us for the loop, plus command overhead), then it's possible to lose a degree or so of accuracy on servo 31. Not really a concern that's keeping me up at night, but it might cause extra battery drain / servo wear in some situations. There might be a Nyquist sampling argument in there too, which probably doesn't bear considering for hobby servos.

The big issue is that there aren't enough timers to dedicate one to each servo (and it would be a huge waste of resources in any case), so I'm having to do a polling system. There may be some ways to clean that up a bit too, but ideally I would get back into the event-driven regime with it.

Edit: Restrictive clause.
User avatar
Berni
Respected Member
Posts: 363
Joined: Thu Dec 10, 2009 10:17 pm
Contact:

Post by Berni »

You can use a single timer and constantly decide what servo needs the next pulse. Also you don't have to make all the pulses at the same time. You have lots of time to generate the pulses one by one after each other since there is a lot of low time in the signal.
User avatar
bsmithyman
Experienced Member
Posts: 126
Joined: Fri Feb 12, 2010 10:31 pm
Contact:

Post by bsmithyman »

Berni wrote:You can use a single timer and constantly decide what servo needs the next pulse. Also you don't have to make all the pulses at the same time. You have lots of time to generate the pulses one by one after each other since there is a lot of low time in the signal.
That's more or less what I'm doing, although I see your point about them not needing to be in sync, particularly. I might give that a try, as you're right; it would nicely deal with the issue.
Post Reply