Forum rules

16 channel i2c servo driver and python

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 ]

halley

Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

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.

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

Re: 16 channel i2c servo driver and python

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 ]

halley

Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

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 ]

halley

Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm

Re: 16 channel i2c servo driver and python

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

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 ]

halley

Posts: 72
Joined: Fri Nov 21, 2008 11:07 pm