Cannot calibrate servo

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
adouglas
Posts: 16
Joined: Fri Apr 30, 2021 4:46 pm

Cannot calibrate servo

Post by adouglas » Tue May 11, 2021 3:28 am

I can't get the servo calibration working, it always gives an error message no matter what I do.
Partly it is my inexperience, but still. There should be an example code, also I think there is a type which doesn't make things eaiser.

a)it doesn't say if the pulse widths are in microseconds or milliseconds.

b)it is not clear what the implications of setting the pulse_angle_90 are. It should be the same as pulse_max

c) arduino assumes the servo goes from 0 to 180 degrees. The servo library here assumes the servo goes from -79 to 85 degrees, and will not command positions beyond that (determined by experiment). A mistake? Or just using the less common standard for servos?

anyone have any example code to use the servo calibration thing?

adouglas
Posts: 16
Joined: Fri Apr 30, 2021 4:46 pm

Re: Cannot calibrate servo

Post by adouglas » Tue May 11, 2021 3:29 am

p.s yeah I came back to the pyboard after leaving, but this is my second exercise, and this is what happens.

Also, in the first exercise there was no way to set the external reference for the adc... again loses points to arduino.

adouglas
Posts: 16
Joined: Fri Apr 30, 2021 4:46 pm

Re: Cannot calibrate servo

Post by adouglas » Tue May 11, 2021 3:49 am

looks like it is the servo which is part of the problem. It came with a kit for a wifi enabled chip from way back, however apparently it is standard kit in the arduino kits. Coincidence, then that it worked perfectly with arduino.

turns out it does not obey the standard for pulse width timing, apparently, although I can't check without an oscilloscope, assuming the pyboard is working correctly, the following code should give 180 degrees motion according to https://www.princeton.edu/~mae412/TEXT/ ... 92-302.pdf
:

Code: Select all

from pyb import Pin, Timer
import pyb # no need to do this twice I know but that's what I threw in so I could use the delay method
p = Pin('X1') # X1 has TIM2, CH1
tim = Timer(2, freq=50)
ch = tim.channel(1, Timer.PWM, pin=p)
while True:
    ch.pulse_width_percent(5)# 5 percent at 20 msec per period is 1 msec
    pyb.delay(500)
    ch.pulse_width_percent(10) # so 2 msec.
    pyb.delay(500)
but actually, it gives less than 90 degrees apparently, or very close to 90 degrees. Not standard. Shame, shame.

User avatar
russ_h
Posts: 88
Joined: Thu Oct 03, 2019 2:26 am
Contact:

Re: Cannot calibrate servo

Post by russ_h » Tue May 11, 2021 5:22 am

I used this library to control the pen lift servo on my drawbots. It worked well on an ESP32 since it was easy to tweak the min/max frequencies. I used trial and error until I got the response I needed. Take a look at Here at lines 108-116 to see the values that worked for cheap MG-90 servos. Something similar should work on the Pyboard.

adouglas
Posts: 16
Joined: Fri Apr 30, 2021 4:46 pm

Re: Cannot calibrate servo

Post by adouglas » Tue May 11, 2021 4:39 pm

There is no source code for the pyboard available anywhere that I can find?? WTF? It should be right there. I want to look at the source code of the servo object...

thanks russ, that library does not work right off the bat on the pyboard as the machine library functions seem to work differently, i don't know why... I will keep investigating.

User avatar
russ_h
Posts: 88
Joined: Thu Oct 03, 2019 2:26 am
Contact:

Re: Cannot calibrate servo

Post by russ_h » Tue May 11, 2021 6:09 pm

The servo object is written in C and is here servo.c and here servo.h the documentation is here

This is roughly the same as my example using the native servo driver setting the min, max and center freq's using the calibration method. The default calibration is pulse_min = 64; pulse_max = 242; pulse_centre = 150;

Code: Select all

import pyb
s1 = pyb.Servo(1)   			# create a servo object on position X1
s1.calibration([60,  240,  150])  	# units are in 10us for my example those are 600us min, 2400us max, 1500us for center
s1.angle(-90)  				# move all the one direction 
... some time later ...
s1.angle(90)	 			# move all the way the other direction

Post Reply