Trouble with Servo Breakout & Wave Shield.

Breakout boards, sensors, other Adafruit kits, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
unorthodoxarts
 
Posts: 11
Joined: Fri Dec 28, 2012 2:13 pm

Re: Trouble with Servo Breakout & Wave Shield.

Post by unorthodoxarts »

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.

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

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

  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

  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

  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.

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

Re: Trouble with Servo Breakout & Wave Shield.

Post by SolangeB »

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);
}

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

Something like this should work:

Code: Select all

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);
}

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

Re: Trouble with Servo Breakout & Wave Shield.

Post by SolangeB »

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?

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

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.

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

Re: Trouble with Servo Breakout & Wave Shield.

Post by SolangeB »

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.

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

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.

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

Re: Trouble with Servo Breakout & Wave Shield.

Post by SolangeB »

The swivel plate rotates, then the 2 servos at the shoulder joint rotate to have the links move up and down

Code: Select all

#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);
     
    }

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

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

Code: Select all

pwm.setPWM(n, 0, 0);

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

Re: Trouble with Servo Breakout & Wave Shield.

Post by SolangeB »

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?

User avatar
adafruit_support_bill
 
Posts: 88086
Joined: Sat Feb 07, 2009 10:11 am

Re: Trouble with Servo Breakout & Wave Shield.

Post by adafruit_support_bill »

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

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

Return to “Other Products from Adafruit”