Adafruit’s Servo Shield

Finally got the servo shield from Adafruit.

The shield comes with the typical non-stackable male headers to interface with the Arduino board, as well as four 3×4 male headers for connecting up to 16 servos, and a two pin terminal block to provide power for those servos.

1411kit_ORIG

Kit Components (Adafruit photo)

I wanted to be able to stack other shields on top of this one so I purchased, separately, 90° headers for the servo connections and stackable “pass-through” headers for the Arduino pins.

Assembled Shield Stacked on Arduino

My assembled shield stacked on the Arduino Uno

The angled headers are a lot harder to solder in. You need to make sure the horizontal pins are slightly angled up from the surface of the board, otherwise there might not be enough clearance for the servo connectors to fit due to the position of the surface mounted resistors.

The other drawback with using angled headers has to do with the position of C2. C2 (right behind the blue terminal block) is a slot where you can solder in a capacitor to help smooth out voltage fluctuations due to power source and servo configurations. However, with the angled headers it’s not possible to add a capacitor unless you insert it in from the other side of the board and make sure to trim the top side, where the leads will protrude, so they are as flush as possible.

All wired up

All Wired Up

The blue terminal block is for powering the servos. In the photo above I’m using a switching adaptor that provides 6 V rated at a max of 3 A. Servos can draw a lot of current so it’s not a good idea to power them directly from the Arduino. The servos can also generate a lot of electrical noise so it’s best they have their own power source.

The best feature of this shield is in how it controls the servos. Rather than using the Arduino’s PWM pins for control (and there aren’t enough of them anyway to service 16 servos) the shield has it’s own 16 channel PWM controller that the Arduino can communicate with via I2C (a serial bus). This means that none of the Arduino’s I/O pins – except the two I2C pins of course – are sacrificed when using this shield. Important to note that power for the shield’s PWM controller is taken from the Arduino board.

The other great feature is that each shield’s I2C address can be modified, meaning multiple servo shields can be stacked together on one Arduino board, giving you an ungodly number of servos you can control.

Adafruit provides a library that is meant to simplify accessing the shield but I have to say it’s very low level and basic.

I did manage to write a simple sketch to test everything out.

// include needed librarys
#include
#include <Adafruit_PWMServoDriver.h>

// create servo driver (defaults to addr 40)
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

// give meaningful names to each servo channel
int base = 4;
int shoulder = 5;
int elbow = 7;
int wrist = 6;
int hand = 9;
int grip = 8;

// simple [channel,angle] list, terminated with a -1
int frame1[] = {  base, 120,
                shoulder, 110,
                elbow, 150,
                wrist, 30,
                hand, 20,
                grip, 20,
                -1};

int frame2[] = {  base, 170,
                shoulder, 170,
                elbow, 120,
                wrist, 150,
                hand, 180,
                grip, 180,
                -1};

void setup()
{

  Serial.begin(9600);
  Serial.println("arm test!");

  pwm.begin();
  pwm.setPWMFreq(50);
}

// helper function that uses angles rather than pulse ticks
void setAngle( int channel, int angle )
{
  // 4096 ticks is 20,000 us
  // Angle 0 is 1,000 us
  // angle 180 is 2,000 us
  long ticks = ((1000L + (1000L*angle/180L))*4096L)/20000L;
  // update the servo channel with the new pusle
  pwm.setPWM(channel, 0, ticks);
}

// helper function to execute a frame list;
void execute( int *cmd )
{
  while( *cmd >= 0 )
  {
    setAngle( *cmd++, *cmd++);
  }
}

// main loop
void loop()
{
    // set servos to frame 1 positions
    execute( frame1 );
    delay(2000);
    // set servos to frame 2 positions
    execute( frame2 );
    delay(2000);
}

Here is a brief clip of the whole thing in action

Obviously creating smooth movements is going to take a lot more work. This robotics lark is not as easy as it seems.

At least, after all these years, I’ve got the arm doing something.

That’s a start.

Advertisements

Comments welcome

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s