Servo resolution

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Servo resolution

Post by fma » Fri Sep 18, 2015 5:41 pm

Hi!

What is the resolution (in µs) of the Servo class, when driving from an angle to another?

I'm having some issues with a servo, and I wonder if it is a lack of resolution of my controllers; using pyboard gives the same results, but I don't know if pyboard is better!

Thanks,
Frédéric

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Servo resolution

Post by dhylands » Fri Sep 18, 2015 6:46 pm

The Servo class uses Timer 5, which is initialized here:
https://github.com/micropython/micropyt ... #L208-L224

This runs the underlying clock tick at 100 kHZ, which means that you've basically got 10usec resolution.

I have some code here: https://github.com/dhylands/upy-example ... ic_test.py which initializes X1 using the timers directly. This gives 1 usec resolution. Since timer 2 & 5 are both 32-bit timers, and both run off the 84 MHz clock, you could run the timer with a prescaler of 0 (divide by 1) and get a 1/84,000,000 clock tick (or 12nsec resolution).

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Servo resolution

Post by fma » Fri Sep 18, 2015 8:33 pm

Thanks for your answer. I'll give a try to your code, to see if 1µs resolution improves the servo behaviour.
Frédéric

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Servo resolution

Post by fma » Sun Sep 20, 2015 6:44 am

Is there a way to overwrite timer5 configuration when using the Servo class, so I can still use this class, but with 1µs resolution?
Frédéric

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Servo resolution

Post by dhylands » Sun Sep 20, 2015 6:52 am

I don't think that will work. The servo class was coded to use bytes (I think to save a few bytes of memory) and thus the largest value it can store is 255 which it multiplies by 10 usec to get 2.55 msec pulse width.

You could probably use a configuration option to make it use usec values (or convince Damien to allow it to change). Or just implement a new servo class in python.

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Servo resolution

Post by fma » Sun Sep 20, 2015 7:43 am

dhylands wrote:(or convince Damien to allow it to change)
I vote for this solution ;)

Damien, could it be possible to:
- have 1µs resolution (timer5 config)
- add a 'time' parameter to the pulse_width() method, so it works like the angle() method, allowing precise control over position/speed

Thanks!
Frédéric

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Servo resolution

Post by pythoncoder » Sun Sep 20, 2015 11:19 am

Unless I'm missing something, coding a high resolution servo interface is easy. You need to generate pulses with a repetion rate of 25Hz, with width varying from 1mS to 2mS covering the angle range 0 to 180 degrees (for a normal servo). The following gives the two extremes:

Code: Select all

timer = pyb.Timer(2, freq=25)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=84033) # 1mS (zero degrees)
ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=168067) # 2mS (180 degrees)
Peter Hinch
Index to my micropython libraries.

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Servo resolution

Post by fma » Sun Sep 20, 2015 2:08 pm

Yes, no problem for a fix pulse width, but what the Servo class does, and your examples don't, is managing the pulse width variation speed...
Frédéric

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Servo resolution

Post by pythoncoder » Tue Sep 22, 2015 5:17 am

I wasn't presenting it as a complete solution, rather showing that precision of about 0.002 degrees is achievable by the hardware. My first question before anyone takes the trouble to pursue it is this. What is the precision of a typical hobby servo? The electronics and the mechanics of these devices may impose a limit; as someone needing this feature you (@fma) may be well placed to answer this question.

Regarding a Python high resolution servo class I can't see any great difficulty in achieving thus. The speed and angle methods are different conversions from integer values to pulse widths. The time arguments could be implemented in a callback on the timer being used to generate the pulses. This would update the channel pulse width by interpolating between the initial and target pulse widths.

If the servos are capable of responding to significantly higher resolution than that offered by the standard library perhaps you, me or someone else might feel motivated to actually write and publish it ;)
Peter Hinch
Index to my micropython libraries.

fma
Posts: 164
Joined: Wed Jan 01, 2014 5:38 pm
Location: France

Re: Servo resolution

Post by fma » Tue Sep 22, 2015 5:38 am

Thanks for you answer!

Good hobby servos have resolutions of 2-3µs, I guess. Even the chineese one I'm testing, which is pretty bad regarding resolution, takes avdantage of a 1µs resolution, over 10µs...

It is really simple to change the timer5 init in micropython code, so the Servo class has 1µs resolution. If it does not lead to other modifications, why not changing it?

I can see in the Servo code that the angle() method can use float, if MICROPY_PY_BUILTINS_FLOAT is defined. Is it the case on the pyboard?

I don't know if a pure python solution, using callback, could work; is it fast enough to change the pusle width fast enough? If not, this will lead to jerky move...
Frédéric

Post Reply