Hello everyone,
I am currently writing a code witch controls several motors via an r/c remote. I have everything working as I want except for the fact that I can't adjust the speed the servos will move at. I don't need the speed to increase or decrease during its move I am just looking for a way to set the constant speed it will be moving at. Anyone know how I might do that?
#include <Servo.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"
int ch1;
int ch2;
int ch3;
int ch4;
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_DCMotor *driveWheel1 = AFMS.getMotor(1);
Adafruit_DCMotor *driveWheel2 = AFMS.getMotor(2);
Adafruit_DCMotor *armMotor1 = AFMS.getMotor(3);
Adafruit_DCMotor *armMotor2 = AFMS.getMotor(4);
Servo claw;
int servoPin = 9;
int pos = 0;
Servo arm;
int servoPin2 = 10;
int pos2 = 0;
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
long onTime1 = 100;
long onTime2 = 100;
void setup()
{
AFMS.begin();
pinMode(A0, INPUT);
pinMode(A1, INPUT);
pinMode(A2, INPUT);
pinMode(A3, INPUT);
pinMode(A4, OUTPUT);
Serial.begin(9600);
driveWheel1->setSpeed(180);
driveWheel2->setSpeed(180);
armMotor1->setSpeed(255);
armMotor2->setSpeed(255);
claw.attach(servoPin);
arm.attach(servoPin2);
}
void loop()
{
unsigned long currentMillis = millis();
ch1 = pulseIn(A0, HIGH, 25000);
ch2 = pulseIn(A1, HIGH, 25000);
ch3 = pulseIn(A2, HIGH, 25000);
ch4 = pulseIn(A3, HIGH, 25000);
if(ch4>1500)
{
Serial.println("Right Switch: Engaged");
driveWheel1->run(FORWARD);
driveWheel2->run(BACKWARD);
}
if(ch4<1400)
{
Serial.println("Right Switch: Disengaged");
driveWheel1->run(BACKWARD);
driveWheel2->run(FORWARD);
}
if((ch4 > 1400) && (ch4 < 1500))
{
Serial.println("Right Switch: Neutral");
driveWheel1->run(RELEASE);
driveWheel2->run(RELEASE);
}
if(ch3 > 1500)
{
Serial.println("Left Switch: Forward");
armMotor1->run(FORWARD);
armMotor2->run(FORWARD);
}
if(ch3 < 1400)
{
Serial.println("Left Switch: BACKWARD");
armMotor1->run(BACKWARD);
armMotor2->run(BACKWARD);
}
if((ch3 > 1400) && (ch3 < 1500))
{
Serial.println("Left Switch: Neutral");
armMotor1->run(RELEASE);
armMotor2->run(RELEASE);
}
if(ch2 > 1500)
{
Serial.println("grab");
if(currentMillis - previousMillis1 >= onTime1)
{
for(pos = 0; pos < 170; pos++)
{
claw.write(pos);
}
previousMillis1 = currentMillis;
}
}
if(ch2 < 1350)
{
Serial.println("Release");
if(currentMillis - previousMillis1 >= onTime1)
{
for(pos = 170; pos > 0; pos--)
{
claw.write(pos);
}
previousMillis1 = currentMillis;
}
}
if((ch2 > 1350) && (ch2 < 1500))
{
Serial.println("nothing");
}
if(ch1 > 1500)
{
Serial.println("bend forward");
if(currentMillis - previousMillis2 >= onTime2)
{
for(pos2 = 0; pos2 < 170; pos2++)
{
arm.write(pos2);
}
previousMillis2 = currentMillis;
}
}
if(ch1 < 1400)
{
Serial.println("bend backward");
if(currentMillis - previousMillis2 >= onTime2)
{
for(pos2 = 170; pos2 > 0; pos2--)
{
arm.write(pos2);
}
}
}
if((ch1 > 1400) && (ch1 < 1500))
{
Serial.println("normal");
}
}
You cannot increase the speed of the servo, but you can make the servo appear to be going slower by moving the servo to several intermediate locations and pausing briefly at each location. The servo operates at its own speed and there is no command to set its speed.
Would I have to use delay for that?
The "VarSpeedServo" library allows you to set the speed of servos.
Ok, I'll look into that library
vaj4088:
you can make the servo appear to be going slower by moving the servo to several intermediate locations and pausing briefly at each location.
Huntechr1:
Would I have to use delay for that?
I think by now you know the answer to that one is "no", and you should use the BlinkWithOutDelay approach as discussed in another of your threads. You need to pause the servo but not delay() the program: while the program is stopped with a delay(), you might miss a sensor read that would have prevented your robot from crashing into the wall.
The IDE's servo sweep example in fact does what you want but with delay(): it moves the servo a degree at a time with a delay() after each degree's movement and you could slow the servo right down by making that delay() very long. A BlinkWithOutDelay approach would pause the servo (in the sense that it hasn't been given the next move yet) while still servicing the rest of the program (checking crash sensors....) through loop() and so not delay()ing the program. Then the servo will only get the go-ahead for its next move when the pause has elapsed.
I suspect, but haven't looked, that the library OldSteve mentioned uses a sort of "SweepWithOutDelay" approach.
JimboZA this is actually a different code for a different purpose than the object avoidance code I was writing in my other thread. In this one I actually have used millis() to effectively allow my code to multi-task. The reason I asked if the mentioned fix used delay was because I knew that it would pause my program not allowing for it to find the changes in signal from my R/C remote. I was just looking for a method to slow down a servo which will be part of a claw.
Huntechr1:
The reason I asked if the mentioned fix used delay was because I knew that it would pause my program
But you didn't ask that, you asked if you would have to use delay which is what made me think you hadn't yet embraced the WithOutDelay approach. I'm glad that you have though.
It would be a good exercise to write a sketch to slow the servo without using delay(). I will do that once I'm out of bed (0700 on yet another public holiday....).
I can see how you could interpret what I said that way and I think I'll try to make a separate program that slows the servo then try to implement it into my other code like you said
I just saw your latest post. I guess I've wasted my time. You're probably not interested in this if you're writing your own code, but since I've already typed it:-
Although I have "VarSpeedServo" installed, I've never got around to actually testing it, so have no idea how well it works. It uses interrupts, not 'delay()' or 'millis()'.
The Github download page below has a modified version that also optionally waits for the servo move to complete. (The wait is 'blocking' though - the function returns when the move is complete.)
VarSpeedServo, the download page for the modified version:-
VarSpeedServo download
VarSpeedServo, the original thread:-
VarSpeedServo - a modified Servo library with speed control
Examples of using 'VarSpeedServo':-
myservo.write(180, 30, true); // Move to 180 degrees, use a speed of 30, Wait until move is complete.
myservo.write(180, 20, false); // Move to 180 degrees, use a speed of 20, Don't wait for the move to complete.
OldSteve:
I have "VarSpeedServo" installed.... It uses interrupts, not 'delay()' or 'millis()'.
I have just read this thread, and had just gathered that Korman hadn't used millis(), since MSquare said that his (MSquare's) approach had used millis() implying Korman's hadn't.
OldSteve:
modified version that also optionally waits for the servo move to complete.
I wonder how it knows?
JimboZA:
I wonder how it knows?
Yeah, so do I. Without position feedback that's not actually possible.
My guess is that it allows a nominal time depending on the speed that's been set. I haven't had a chance to look closely at the library to see how it's done.
Edit: Since it's blocking, I personally wouldn't bother using the optional 'wait' feature. Might as well just use 'delay()', tailored to the time the move actually takes. Better to use 'millis()'-based timing for that if it's needed anyway.
OldSteve:
Without position feedback that's not actually possible.
I've read about these from adafruit but never seen one.
JimboZA:
I've read about these from adafruit but never seen one.
That's a good idea, and should be easy enough to implement on any servo. Wish I'd thought of it.
I love the idea of recording movements based on the value of the internal pot as shown in the video, too.
Thanks for pointing that out Jim.
Edit: I'm gonna have to pull apart and modify one of my servos now. 
OldSteve:
Edit: I'm gonna have to pull apart and modify one of my servos now. 
Start with a cheap(er) one.....
JimboZA:
Start with a cheap(er) one.....
That's easy - mine are all cheapies. 