I need help correlating (calibrating) angle to servo positi
Moderators: adafruit_support_bill, adafruit

Forum rules
Talk about Adafruit Raspberry Pi® accessories! Please do not ask for Linux support, this is for Adafruit products only! For Raspberry Pi help please visit: http://www.raspberrypi.org/phpBB3/

I need help correlating (calibrating) angle to servo positi

by prussia on Wed Oct 09, 2013 9:52 am

Hey Guys,
I finally got my i2c servo driver from Adafruit working beautifully and I can use to control both a micro servo and a larger one. But I have several questions about automating or writing a calibration script for the various types.

Goals:
1. I'd like to write a calibration script that I can run to convert degrees (0-180 for normal and I don't know what for Continuous rotation) I enter into a physical servo position for a pan/tilt system.
2. Figure out how to set-up the continuous rotation servos with this i2c chip.

Hardware:
1. Servo driver 16 Channel Ada controller.
2. micro servos I can't find the frequency on the docs btw
3. 3-d printed pan tilt
4. Pi Camera Module of course :) with the video4linux drivers up and running

So I wrote some initial code (below) to run the servos by providing an angle and "hoping" it goes there. Just some slight modifications of the Servo code provided by Ada (shown below). I would really love to get some feedback on how others are doing their calibration of the servos so that I can become more precise. I'm eventually going to use this system both for the pan/tilt gimbal of a quad copter and for a wheeled robot so I'd like to control by angle first and then just by clicking on an area in the field of view.

I'm having some difficulty correlating angle/with position though and that's where I would like some help if possible

min is:
Code: Select all | TOGGLE FULL SIZE
setPulseDegree(15, 60, 0)

max is :
Code: Select all | TOGGLE FULL SIZE
setPulseDegree(15, 60, 320)

Currently the angle input is -40 to about 300 which correlates to a physical 0 - 180. How would you calibrate this or adjust my values to work with this.:
Code: Select all | TOGGLE FULL SIZE
def angleToms(angle):
  pulseAngle = float(1.0/180.0)
  return ((pulseAngle * angle) + 1.0)
# 1ms / 180o .. you will have to add this to 1ms to get total.
# so say you want 90o you do (pulseAngle * 90) + 1

def setPulseDegree(channel, freq, angle):
  sec        = float(1000000)
  pulseLength = (sec / float(freq))             # period / pulse
  print "%.3f us per period" % pulseLength
  pulseLength /= totalTicks                     # us / tick
  print "%.2f us per bit" % pulseLength
  pulse = angleToms(angle)
  print "%.2f pulse for 90 angle" % pulse
  ticksOn = (pulse * 1000) / pulseLength
  print "%.2f ticksOn for 90 angle" % ticksOn
  pwm.setPWM(channel, 0, int(ticksOn))
prussia
 
Posts: 15
Joined: Mon Jan 21, 2013 7:07 pm

Re: I need help correlating (calibrating) angle to servo po

by adafruit_support_bill on Wed Oct 09, 2013 7:35 pm

What are you seeing in your output for 'ticksOn''? Looks like you might be getting some cumulative roundoff error in your calculations.
User avatar
adafruit_support_bill
 
Posts: 29028
Joined: Sat Feb 07, 2009 9:11 am

Re: I need help correlating (calibrating) angle to servo po

by prussia on Wed Oct 09, 2013 8:37 pm

Quite possible... Here are some of the readings

setPulseDegree(14, 60, 40)

Code: Select all | TOGGLE FULL SIZE
16666.667 us per period
4.07 us per bit
1.22 pulse for 90 angle
300.37 ticksOn for 90 angle



In [3]: setPulseDegree(14, 60, 100)
Code: Select all | TOGGLE FULL SIZE
16666.667 us per period
4.07 us per bit
1.56 pulse for 90 angle
382.29 ticksOn for 90 angle


In [4]: setPulseDegree(14, 60, 300)
Code: Select all | TOGGLE FULL SIZE
16666.667 us per period
4.07 us per bit
2.67 pulse for 90 angle
655.36 ticksOn for 90 angle
prussia
 
Posts: 15
Joined: Mon Jan 21, 2013 7:07 pm

Re: I need help correlating (calibrating) angle to servo po

by adafruit_support_bill on Thu Oct 10, 2013 4:31 am

For most servos at 60 Hz, your ticksOn should range from approximately 100 for 0 degrees and 600 for 180 degrees. The calculation should be roughly as follows. You can tweak tickMin and tickMax to tune to your servos.

angleMin = 0
angleMax = 180
angleRange = angleMax - angleMin

tickMin = 100
tickMax = 600
tickRange = tickMax - tickMin

ticksOut = ((angleIn * tickRange) / angleRange) + tickMin
User avatar
adafruit_support_bill
 
Posts: 29028
Joined: Sat Feb 07, 2009 9:11 am