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
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
print "%d us per period" % pulseLength
pulseLength /= 4096
print "%d us per bit" % pulseLength
pulse = position * 1000 # 1 millisecond range overall
pulse += 1000 # plus 1 millisecond for "minimum" position
pulse /= pulseLength
print "final pulse-off is %d" % pulse
self.setPWM(channel, 0, pulse)
[ e d @ h a l l e y . c c ]