Adafruit 16-Channel Servo Driver Rasp Pi

For Adafruit customers who seek help with microcontrollers

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

So I went through this tutorial
https://learn.adafruit.com/adafruit-16- ... i/overview

It was working my continuous rotating servos are rotating only one way.

Also I'm using the Servo_Example.py code.

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

Post a photo of your hardware and connections and we'll take a look. 800x600 images usually work best.

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

adafruit_support_mike wrote:Post a photo of your hardware and connections and we'll take a look. 800x600 images usually work best.
http://imgur.com/j6U1ePH,X1YCe7b

The 3v3 and #22 are being used for a switch input
http://imgur.com/j6U1ePH,X1YCe7b#1

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

I'm also using a computer PSU

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

The connections look okay.

What kind of servo are you using? You may have one that wants different pulse widths than the ones in the example code.

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

adafruit_support_mike wrote:The connections look okay.

What kind of servo are you using? You may have one that wants different pulse widths than the ones in the example code.
Continuous rotating servos from the website.

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

The timing on those is slightly different from other servos.

Try dropping the PWM frequency to 50Hz:

Code: Select all

pwm.setPWMFreq( 50 )                        # Set frequency to 50 Hz

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

adafruit_support_mike wrote:The timing on those is slightly different from other servos.

Try dropping the PWM frequency to 50Hz:

Code: Select all

pwm.setPWMFreq( 50 )                        # Set frequency to 50 Hz

Code: Select all

from Adafruit_PWM_Servo_Driver import PWM
import time

# ===========================================================================
# Example Code
# ===========================================================================

# Initialise the PWM device using the default address
pwm = PWM(0x40)
# Note if you'd like more debug output you can instead run:
#pwm = PWM(0x40, debug=True)

servoMin = 150  # Min pulse length out of 4096
servoMax = 600  # Max pulse length out of 4096

def setServoPulse(channel, pulse):
  pulseLength = 1000000                   # 1,000,000 us per second
  pulseLength /= 60                       # 60 Hz
  print "%d us per period" % pulseLength
  pulseLength /= 4096                     # 12 bits of resolution
  print "%d us per bit" % pulseLength
  pulse *= 1000
  pulse /= pulseLength
  pwm.setPWM(channel, 0, pulse)

pwm.setPWMFreq(60)                        # Set frequency to 60 Hz
while (True):
  setServoPulse(0, 1000)
  time.sleep(1)
  setServoPulse(0, 2000)
  time.sleep(1)
Here's my code. I tried 50 Hz. The code is suppose to make the servo toggle, but it's just going counter-clockwise.

Also

setServoPulse(0, 1500)
time.sleep(1)

stops the servo.

Why isn't it toggling?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

You have to keep the pulses between 1ms and 2ms wide.

For a 50Hz PWM frequency, each cycle is 20ms wide. To make a pulse 1ms wide, you have it rise at 0 and fall at 205. To make the pulse 2ms wide, you have it rise at 0 and fall at 410. The neutral position would be halfway between the two, rising at 0 and falling at 307.

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

adafruit_support_mike wrote:You have to keep the pulses between 1ms and 2ms wide.

For a 50Hz PWM frequency, each cycle is 20ms wide. To make a pulse 1ms wide, you have it rise at 0 and fall at 205. To make the pulse 2ms wide, you have it rise at 0 and fall at 410. The neutral position would be halfway between the two, rising at 0 and falling at 307.
It's still just spinning one direction

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

Post a photo of your hardware and the code you're using and we'll see what we can find.

User avatar
rayzer
 
Posts: 49
Joined: Tue May 06, 2014 8:22 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by rayzer »

I have it by just trial and error. I'm thinking that the center points on the servos are off. I don't really know.

This is the code I came up with to make the servo move back and forth.

Code: Select all


from Adafruit_PWM_Servo_Driver import PWM
import time

# ===========================================================================
# Example Code
# ===========================================================================

# Initialise the PWM device using the default address
pwm = PWM(0x40)
# Note if you'd like more debug output you can instead run:
#pwm = PWM(0x40, debug=True)

servoMin = 150  # Min pulse length out of 4096
servoMax = 600  # Max pulse length out of 4096

def setServoPulse(channel, pulse):
  pulseLength = 1000000                   # 1,000,000 us per second
  pulseLength /= 60                       # 60 Hz
  print "%d us per period" % pulseLength
  pulseLength /= 4096                     # 12 bits of resolution
  print "%d us per bit" % pulseLength
  pulse *= 1000
  pulse /= pulseLength
  pwm.setPWM(channel, 0, pulse)

pwm.setPWMFreq(60)                        # Set frequency to 60 Hz
while (True): 
  setServoPulse(0, 1300)
  time.sleep(1)
  pwm.setPWM(0, 0, servoMax)
  time.sleep(1)

  setServoPulse(0, 1500)
  time.sleep(1)
  pwm.setPWM(0, 1500, servoMax)
  time.sleep(1)


stop to Clockwise to stop to counter clockwise.

However the counter clockwise seems a little bit slower than the clockwise rotation.

I'm just playing around and just followed the tutorial. I just experimented with the code until the hardware moved the way I wanted it to...

Thank you for being patient with me so far, but could I bother you to go into depth(dumb it down)? I'm new to datasheets, I looked at the one for continuous rotating servos linked from Adafruit product page. That's where I get 1500 and 1300. However 1700 acted like 1500 where it made the servo stop moving

Questions:
How does the Raspberry Pi 16 channel 12 bit servo driver?
What does Adafruit_PWM_Servo_Driver do?
Why doesn't the the Servo_Example code not work with my continuous rotating servos?
The guide stated that there was an option to add a capacitor on the board. In what situation does one want to add said capacitor?

User avatar
adafruit_support_mike
 
Posts: 67454
Joined: Thu Feb 11, 2010 2:51 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by adafruit_support_mike »

rayzer wrote:How does the Raspberry Pi 16 channel 12 bit servo driver?
I'm going to guess the next word should be 'work'.

The chip that does all the work is called the PCA9685. It has an internal 25MHz clock and a circuit called a 'prescaler' which groups those pulses into longer/slower ones (1 pulse every 10 ticks of the 25MHz clock, for instance). Those slower pulses go to 16 identical count-and-compare circuits.

Each count-and-compare unit has a 12-bit register that increments by 1 every time a pulse from the master clock arrives. Every time the count reaches 4095 (0x3ff == B11 1111 1111), the next pulse rolls the counter over to 0 again.

The unit also has two registers that hold 12-bit numbers which get compared to the counter. If the counter's value is between the two numbers, the unit's output value is 1. If the counter value is less than the first number or more than the second, the unit's output value is 0. That value goes to a circuit that controls the output pins for that unit.

The upshot is that each channel can generate pulses that go high and low at specific times, there are 4096 distinct ratios of high-to-low width, and the overall duration of a 4096-count cycle can be adjusted from 40Hz to 1000Hz.
rayzer wrote:What does Adafruit_PWM_Servo_Driver do?
It talks to the PCA9685.

The chip has a control unit that knows how to speak the I2C signal protocol, and that listens for commands from a 'master device' (an Arduino or RasPi for instance). The master device sends pulse codes that tell the PCA9685 how to adjust its prescaler, what values to store in each count-and-compare unit's registers, how to configure the output circuit, and when to do various housekeeping commands.

Having to generate all those pulse codes directly in your code would be a huge pain in the neck, so we wrapped it all up in a file that knows how to do all the gritty details, but doesn't have any opinions about when to do them. When you import the module into your own code, you can just say, 'pwm.setPWMFreq(60)' and the library will handle all the signal generation and transmission necessary to make the PCA9685 adjust its prescaler so the 4096-count rollover events happen 60 times per second.
rayzer wrote:Why doesn't the the Servo_Example code not work with my continuous rotating servos?
Damifino..

Something unusual seems to be going on, but I'm not sure what. It might have something to do with your hardware connections, which is why I asked for the photo.
rayzer wrote:The guide stated that there was an option to add a capacitor on the board. In what situation does one want to add said capacitor?
The cap is useful when you have lots of channels using a lot of current.

Current can only flow around a closed loop, and any closed loop with current flowing through it is surrounded by a magnetic field. The magnetic field holds a certain amount of energy (which is proportional to the amount of current flowing through the loop), and the 'field strength' is proportional to the amount of stored energy.

That sounds fine, but it means that the strength of the magnetic field has to change any time the amount of current flowing through the loop changes. For that to happen, the magnetic field has to absorb or release energy. That energy comes from the 'electromotive force' pushing current through the loop, and one of the basic properties of physics is that you can't move energy back and forth between the electromotive and magnetic fields in zero time. There's always some amount of delay.

During that delay, the transfer of energy to or from the magnetic field opposes the change in the current. If you push the electrons harder to move more current, the magnetic field will steal some of that energy as the current increases. If you cut off the current, the magnetic field will dump energy into the current to keep it flowing.

PWM motor or LED control works on the idea of turning current on and off instantly, but real current doesn't start or stop instantly. The transfer of energy back and forth to the magnetic field turns the theoretically simple square wave into a sloping, choppy mess.

That mess appears as voltage spikes on the VCC and GND rails. If the spikes get large enough (and they certainly can), it can make a circuit behave erratically.. lighting one strip of LEDs causes all the others to dim for a few moments, for instance.

A capacitor has similar "can't change instantly" properties, but those resist changes in voltage rather than changes in current. In theory, you can find a capacitor whose "can't change the voltage instantly" properties exactly balance the magnetic field's "can't change the current instantly" ones, and they'll cancel each other out. Instead of moving energy between the magnetic field and the current, you move energy from the magnetic field to the 'fixed electric field' inside the capacitor at a rate that doesn't change the current flowing through the loop or the voltage between any two points along the loop.

That process is called 'compensating' the loop.

In practice, trying to compensate a loop exactly is another huge pain in the neck, so the easier solution is to 'overcompensate' it.. to use a capacitor so big that its "can't change the voltage" effects outweigh anything the magnetic field's "can't change the current" effects can throw at it.

Electric motors are specifically designed to use lots of current and generate large magnetic fields, so trying to control them with PWM is kind of optimistic. Something controllable does happen, but the stuff happening in the wires looks nothing like that tidy, theoretical square wave. If you have several motors PWMing at the same time, the possibilities for combined effects and wierd interactions between parts of the circuit that should be independent of each other increase dramatically.

To keep that from happening, you overcompensate the supply rails by slapping in a BFC.

User avatar
brian49
 
Posts: 61
Joined: Tue Oct 14, 2014 6:08 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by brian49 »

"It's still just spinning one direction"

You first need to calibrate the motor (using the pot) so it stop rotating with 1.5ms. To do this you need to send out from the Pi 16-channel a pwm waveform with frequency = 50hz and pulse = 1.5ms. If the motor rotates then the pot on the motor needs to be adjusted until the motor stops.

After calibrated, pwm pulse 1.7ms will cause it to rote fast one direction, and 1.3ms causes it to rotates fast the other direction. Notice that the motor spec states pulse should be within 1.3ms to 1.7ms range, not 0ms to 2ms.

Brian

User avatar
brian49
 
Posts: 61
Joined: Tue Oct 14, 2014 6:08 pm

Re: Adafruit 16-Channel Servo Driver Rasp Pi

Post by brian49 »

P.S.

"he neutral position would be halfway between the two, rising at 0 and falling at 307."

Notice that value 307 pwm is to generate 1.5ms at 50hz signal, and I see your code defined it at 60hz, which would generate 1.2ms with 307 pwm making the motor to rotate instead of stop.

Locked
Please be positive and constructive with your questions and comments.

Return to “Microcontrollers”