Servo resolution
Servo resolution
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,
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
Re: Servo resolution
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).
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).
Re: Servo resolution
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
Re: Servo resolution
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
Re: Servo resolution
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.
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.
Re: Servo resolution
I vote for this solutiondhylands wrote:(or convince Damien to allow it to change)
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
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Servo resolution
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.
Index to my micropython libraries.
Re: Servo resolution
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
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Servo resolution
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
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.
Index to my micropython libraries.
Re: Servo resolution
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...
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