16 channel i2c servo driver and python
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/

16 channel i2c servo driver and python

by halley on Mon Oct 01, 2012 1:53 pm

I got the i2c 16x servo board this weekend.

Can I get confirmation that the i2c solder pads are the low 6 bits, and that a 7th bit is hardwired as 0x40 hex? I am just digging into the git code and trying to see how these addresses can be customized and chained.
[ e d @ h a l l e y . c c ]
User avatar
halley
 
Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

by adafruit_support_rick on Mon Oct 01, 2012 4:05 pm

halley wrote:Can I get confirmation that the i2c solder pads are the low 6 bits, and that a 7th bit is hardwired as 0x40 hex?

That is correct.

adafruit_support_rick
 
Posts: 12774
Joined: Tue Mar 15, 2011 11:42 am
Location: Buffalo, NY

Re: 16 channel i2c servo driver and python

by halley on Thu Oct 04, 2012 11:56 pm

Great.

I noticed that at the time of this writing, the example Servo_Example.py code on git was only exercising the PWM with raw 0~4095 positions.

There was the beginnings of an implementation of a method called setServoPulse() in the example, but it doesn't seem to work well. The intention of this function is to compute the 0~4095 scale pulse width required to get the servo to the desired position. Essentially, it is missing a bias value for the minimum pulse width of 1ms.

I moved my version of this function into the PWM class itself, and added a self.freq member variable to recall the master frequency given in setPWMFreq(). It's vital that the two functions calculate timing information using the same base frequency.

Here's my version of PWM.setServoPosition():

Code: Select all | TOGGLE FULL SIZE
  def setServoPosition(self, channel, position):
    "Commands a servo position from 0.0 to 1.0."
    if self.freq is None:
      raise RuntimeError, "must set base PWM frequency first"
    position = max(0.0, min(position, 1.0))
    pulseLength = 1000000             # 1 us is 1 millionth of a second
    pulseLength /= self.freq
    if self.debug:
      print "%d us per period" % pulseLength
    pulseLength /= 4096
    if self.debug:
      print "%d us per bit" % pulseLength
    pulse = position * 1000           # 1 millisecond range overall
    pulse += 1000                     # plus 1 millisecond for "minimum" position
    pulse /= pulseLength
    if self.debug:
      print "final pulse-off is %d" % pulse
    self.setPWM(channel, 0, pulse)
[ e d @ h a l l e y . c c ]
User avatar
halley
 
Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

by halley on Fri Oct 05, 2012 12:04 am

Oh, and for hobby servos like the Tower Pro SG92R sold by Adafruit, this is a nice introduction to how they work.

http://www.princeton.edu/~mae412/TEXT/N ... 92-302.pdf

The basic standard for classic non-continuous servos is 25Hz to 50Hz frequency set with setPWMFreq(), but it's not that critical. The Servo_Example.py suggests 60Hz, which caused some excess buzzing and current drain as if under load, in my experience.
[ e d @ h a l l e y . c c ]
User avatar
halley
 
Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

by halley on Fri Nov 02, 2012 5:04 pm

I used the 16 channel i2c servo driver on this simple Halloween display.

http://www.youtube.com/watch?v=7T7kwsECvPY

The huge hobby lipos lasted 3 hours with moderate voltage drop.

This year, the main program was only a couple lines long (sleep(2), command random servo to random position, repeat).

Next year, they will be a lot more coordinated and sensitive to visitors.
[ e d @ h a l l e y . c c ]
User avatar
halley
 
Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm