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.
Trouble with Servo Breakout & Wave Shield.
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
-
- Posts: 11
- Joined: Fri Dec 28, 2012 2:13 pm
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
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:
If you want to change the speed of the move, you can add a delay inside the loop:
To move in the other direction:
There are ways to clean that up and make it easier to use. But it's best if you understand this part first.
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);
}
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);
}
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);
}
- SolangeB
- Posts: 5
- Joined: Wed Mar 25, 2015 3:00 am
Re: Trouble with Servo Breakout & Wave Shield.
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);
}
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);
}
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
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);
}
- SolangeB
- Posts: 5
- Joined: Wed Mar 25, 2015 3:00 am
Re: Trouble with Servo Breakout & Wave Shield.
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?
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
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.
- SolangeB
- Posts: 5
- Joined: Wed Mar 25, 2015 3:00 am
Re: Trouble with Servo Breakout & Wave Shield.
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.
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
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.
- SolangeB
- Posts: 5
- Joined: Wed Mar 25, 2015 3:00 am
Re: Trouble with Servo Breakout & Wave Shield.
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);
}
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
If you disable PWM pulses in your setup as below, the servos should remain idle.
Code: Select all
pwm.setPWM(n, 0, 0);
- SolangeB
- Posts: 5
- Joined: Wed Mar 25, 2015 3:00 am
Re: Trouble with Servo Breakout & Wave Shield.
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?
- adafruit_support_bill
- Posts: 88093
- Joined: Sat Feb 07, 2009 10:11 am
Re: Trouble with Servo Breakout & Wave Shield.
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.What's happening is that the swivel plate whips back to the starting angle in the code from the position it was at last.
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
Please be positive and constructive with your questions and comments.