Trouble with Servo Breakout & Wave Shield.
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Re: Trouble with Servo Breakout & Wave Shield.

by unorthodoxarts on Wed Jan 16, 2013 9:54 pm

Oh. Hahah. I see. The 'pulselen' in the pwm.setPWM() thing is a placeholder. Ahhah!

The only thing now, is that the 'delay' after the pwm.setPWM() doesn't control the speed at which the servo moves, but the gap in between them moving. Is there any way to slow down the rate it moves?

Thank you again.
unorthodoxarts
 
Posts: 11
Joined: Fri Dec 28, 2012 2:13 pm

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Thu Jan 17, 2013 6:45 am

The servo will always move at 'full speed' to the position you set. If you want it to move slowly, you need to give it incremental moves as in the example code:

Code: Select all | TOGGLE FULL SIZE
  for (uint16_t pulselen = map (120,0,180,SERVOMIN,SERVOMAX); pulselen < map (180,0,180,SERVOMIN,SERVOMAX); pulselen++)
  {
    pwm.setPWM(servonum, 0, pulselen);
  }


If you want to change the speed of the move, you can add a delay inside the loop:

Code: Select all | TOGGLE FULL SIZE
  for (uint16_t pulselen = map (120,0,180,SERVOMIN,SERVOMAX); pulselen < map (180,0,180,SERVOMIN,SERVOMAX); pulselen++)
  {
    pwm.setPWM(servonum, 0, pulselen);
    delay(2);
  }


To move in the other direction:

Code: Select all | TOGGLE FULL SIZE
  for (uint16_t pulselen =  map (180,0,180,SERVOMIN,SERVOMAX); pulselen >  map (120,0,180,SERVOMIN,SERVOMAX); --pulselen)
  {
    pwm.setPWM(servonum, 0, pulselen);
    delay(2);
  }


There are ways to clean that up and make it easier to use. But it's best if you understand this part first.

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

by SolangeB on Wed Mar 25, 2015 3:05 am

Is it possible to get servos rotating in opposite directions. I used the code above and was able to get 2 servos to rotate simultaneously in the same direction (code below). How do I get them to rotate simultaneously in opposite directions now? I'm new to this as well.

for (uint16_t pulselen = map (0,0,180,SERVOMIN,SERVOMAX); pulselen < map (120,0,180,SERVOMIN,SERVOMAX); pulselen++)
{
pwm.setPWM(2, 0, pulselen);
delay(10);
pwm.setPWM(4, 0, pulselen);
delay(10);
}

SolangeB
 
Posts: 5
Joined: Wed Mar 25, 2015 3:00 am

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Wed Mar 25, 2015 5:57 am

Something like this should work:
Code: Select all | TOGGLE FULL SIZE
for (int i = 0; i < 180; i++)
{
    uint16_t pulselen1 = map (i,0,180,SERVOMIN,SERVOMAX);
    uint16_t pulselen2 = map (i,0,180,SERVOMAX,SERVOMIN);

    pwm.setPWM(2, 0, pulselen1);
    pwm.setPWM(4, 0, pulselen2);
    delay(20);
}

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

by SolangeB on Wed Mar 25, 2015 4:42 pm

Thanks you so much. It worked. Only thing is now one servo stops about half a second before the other when they both rotate. Do you have any idea what could be the issue?

SolangeB
 
Posts: 5
Joined: Wed Mar 25, 2015 3:00 am

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Wed Mar 25, 2015 4:46 pm

One servo may have a slightly different response than the other. Some variability between servos is typical and for critical applications you may need to tune the pulse widths a bit.

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

by SolangeB on Sat Mar 28, 2015 2:45 pm

Ok. One last thing. Is there a way to initialise the servo shield to have the servos start at a particular angle instead of going to the zero position in startup? The manipulator arm I'm programming jerks on startup because the servos go to the zero position before going from, say, 10 degrees to 50 degrees.

SolangeB
 
Posts: 5
Joined: Wed Mar 25, 2015 3:00 am

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Sat Mar 28, 2015 2:49 pm

There is usually some twitch on power-up. But the servo should not seek to a position until you command it. Please post the code you are using.

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

by SolangeB on Sat Mar 28, 2015 3:04 pm

The swivel plate rotates, then the 2 servos at the shoulder joint rotate to have the links move up and down
Code: Select all | TOGGLE FULL SIZE
#include <Wire.h> //Allows communication with the pwm servo shield
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#define SERVOMIN  150 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX  535 // this is the 'maximum' pulse length count (out of 4096)

// our servo # counter
uint8_t servonum = 6;

void setup() {
 Serial.begin(9600); // open the serial port at 9600 bps:
 Serial.println("16 channel Servo test!");
 
 pwm.begin();

 pwm.setPWMFreq(60);
}
// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
  double pulselength;
 
   pulselength = 1000000;   // 1,000,000 us per second
  pulselength /= 60;   // 60 Hz
  Serial.print(pulselength); Serial.println(" us per period");
  pulselength /= 4096;  // 12 bits of resolution
  Serial.print(pulselength); Serial.println(" us per bit");
  pulse *= 1000;
  pulse /= pulselength;
  Serial.println(pulse);
  pwm.setPWM(n, 0, pulse);
}
 
    void loop()
    {
     
    Serial.println(servonum);
    //************************POSE1******************************
    SWIVEL PLATE
     
     for (uint16_t pulselen =  map (40,0,180,SERVOMIN,SERVOMAX); pulselen <  map (140,0,180,SERVOMIN,SERVOMAX); pulselen++)
 {
    pwm.setPWM(6, 0, pulselen);
    delay(35);
  }
    // SHOULDER MOVING DOWM
   
    for (int i=100; i<160; i++)
    {
      uint16_t pulselen1 = map (i, 0, 160, SERVOMIN, SERVOMAX); // starts at zero or i and moves to 120
      uint16_t pulselen2 = map (i, 0, 160, SERVOMAX, SERVOMIN); //starts at 120 and moves to zero or i
     
     pwm.setPWM(2, 0, pulselen1);
     pwm.setPWM(4, 0, pulselen2);
      delay(25);
    }
   
    // SHOULDER AGAIN MOVING BACK UP
     for (int i=10; i<40; i++)
    {
      uint16_t pulselen1 = map (i, 0, 160, SERVOMAX, SERVOMIN); //
      uint16_t pulselen2 = map (i, 0, 160, SERVOMIN, SERVOMAX); //
     
      pwm.setPWM(2, 0, pulselen1);
      pwm.setPWM(4, 0, pulselen2);
     delay(35);
    }
    delay(1500);
      while(1);
     
    }

SolangeB
 
Posts: 5
Joined: Wed Mar 25, 2015 3:00 am

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Sat Mar 28, 2015 3:25 pm

If you disable PWM pulses in your setup as below, the servos should remain idle.

Code: Select all | TOGGLE FULL SIZE
pwm.setPWM(n, 0, 0);

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

by SolangeB on Sat Mar 28, 2015 6:24 pm

What's happening is that the swivel plate whips back to the starting angle in the code from the position it was at last. And the two servos at the shoulder cause the links to come up to a position quite quickly on startup and then carries out the commands. I tried your last suggestion but it only diaables the specified servo, meaning that the servo didnt move at all. Is there something in my code that makes it do that?

SolangeB
 
Posts: 5
Joined: Wed Mar 25, 2015 3:00 am

Re: Trouble with Servo Breakout & Wave Shield.

by adafruit_support_bill on Sun Mar 29, 2015 7:13 am

What's happening is that the swivel plate whips back to the starting angle in the code from the position it was at last.

The limitation of standard RC servos is that there is no feedback to the microcontroller, so you have no idea what position the servo is in when you start.
Image

AS soon as you issue the first command, the servo will move to the commanded position as fast as it can. One solution is to have a 'shutdown' sequence that always leaves the robot in a known position.

A much better solution is to use analog feedback servos. You can read the current servo position at startup and make a controlled move from there to the starting position.

https://learn.adafruit.com/analog-feedb ... d-feedback

Image

adafruit_support_bill
 
Posts: 38580
Joined: Sat Feb 07, 2009 10:11 am

Please be positive and constructive with your questions and comments.