I'm working on a project where I have to make 2 servos rotate in the opposite direction, stop for a few seconds and go in reverse for both servos. All of this without the delay function. I've attempted to solve this puzzle, but the code ends up not working and gets very messy. My current code is below:
#include <Servo.h>
//MOTOR
const int servoPin = 9; // the pin number for the servo signal
const int servoMinDegrees = 20; // the limits to servo movement
const int servoMaxDegrees = 190; //Increase to increase servo time on
Servo Motor; // create servo object to control a servo
int servoPosition = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval = 80; // millisecs between servo moves
int servoFastInterval = 10;
int servoInterval = servoSlowInterval; // initial millisecs between servo moves
int servoDegrees = 4; // amount servo moves at each step
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis = 0; // the time when the servo was last moved
//MOTOR2
const int servoPin2 = 10; // the pin number for the servo signal
const int servoMinDegrees2 = -10; // the limits to servo movement
const int servoMaxDegrees2 = 190; //Increase to increase servo time on
Servo Motor2; // create servo object to control a servo
int servoPosition2 = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval2 = 80; // millisecs between servo moves
int servoFastInterval2 = 10;
int servoInterval2 = servoSlowInterval2; // initial millisecs between servo moves
int servoDegrees2 = -4; // amount servo moves at each step
unsigned long currentMillis2 = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis2 = 0; // the time when the servo was last moved
void setup() {
Serial.begin(9600);
Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
Motor.write(servoPosition); // sets the initial position
Motor.attach(servoPin);
Motor2.write(servoPosition); // sets the initial position
Motor2.attach(servoPin2);
}
//=======
void loop() {
currentMillis = millis(); // capture the latest value of millis()
servoSweep();
currentMillis2 = millis();
servoSweep2();
}
void servoSweep() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis - previousServoMillis >= servoInterval) {
// its time for another move
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition <= servoMinDegrees) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval == servoSlowInterval) {
servoInterval = servoFastInterval;
}
else {
servoInterval = servoSlowInterval;
}
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
Motor.detach();
}
// make the servo move to the next position
Motor.write(servoPosition);
// and record the time when the move happened
}
}
void servoSweep2() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis2 - previousServoMillis2 >= servoInterval2) {
// its time for another move
previousServoMillis2 += servoInterval2;
servoPosition2 = servoPosition2 + servoDegrees2; // servoDegrees might be negative
if (servoPosition2 <= servoMinDegrees2) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval2 == servoSlowInterval2) {
servoInterval2 = servoFastInterval2;
}
else {
servoInterval2 = servoSlowInterval2;
}
}
if ((servoPosition2 >= servoMaxDegrees2) || (servoPosition2 <= servoMinDegrees2)) {
Motor2.detach();
}
// make the servo move to the next position
Motor2.write(servoPosition2);
// and record the time when the move happened
}
}
I've also tried using the boolean function, but I feel as if I'm lacking some vital understanding on it and yes I have already researched.
#include <Servo.h>
boolean reverse = false;
//MOTOR
const int servoPin = 9; // the pin number for the servo signal
const int servoMinDegrees = -10; // the limits to servo movement
const int servoMaxDegrees = 190; //Increase to increase servo time on
Servo Motor; // create servo object to control a servo
int servoPosition = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval = 80; // millisecs between servo moves
int servoFastInterval = 10;
int servoInterval = servoSlowInterval; // initial millisecs between servo moves
int servoDegrees = 4; // amount servo moves at each step
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis = 0; // the time when the servo was last moved
//MOTOR2
const int servoPin2 = 10; // the pin number for the servo signal
const int servoMinDegrees2 = -10; // the limits to servo movement
const int servoMaxDegrees2 = 190; //Increase to increase servo time on
Servo Motor2; // create servo object to control a servo
int servoPosition2 = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval2 = 80; // millisecs between servo moves
int servoFastInterval2 = 10;
int servoInterval2 = servoSlowInterval2; // initial millisecs between servo moves
int servoDegrees2 = -4; // amount servo moves at each step
unsigned long currentMillis2 = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis2 = 0; // the time when the servo was last moved
void setup() {
Serial.begin(9600);
Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
Motor.write(servoPosition); // sets the initial position
Motor.attach(servoPin);
Motor2.write(servoPosition); // sets the initial position
Motor2.attach(servoPin2);
}
//=======
void loop() {
currentMillis = millis(); // capture the latest value of millis()
servoSweep();
currentMillis2 = millis();
servoSweep2();
}
void servoSweep() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis - previousServoMillis >= servoInterval) {
// its time for another move
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition <= servoMinDegrees) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval == servoSlowInterval) {
servoInterval = servoFastInterval;
}
else {
servoInterval = servoSlowInterval;
}
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
Motor.detach();
}
// make the servo move to the next position
Motor.write(servoPosition);
// and record the time when the move happened
}
}
void servoSweep2() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis2 - previousServoMillis2 >= servoInterval2) {
// its time for another move
previousServoMillis2 += servoInterval2;
servoPosition2 = servoPosition2 + servoDegrees2; // servoDegrees might be negative
if (reverse == false) {
if (servoPosition2 <= servoMinDegrees2) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval2 == servoSlowInterval2) {
servoInterval2 = servoFastInterval2;
}
else {
servoInterval2 = servoSlowInterval2;
}
}
}
if ((servoPosition2 >= servoMaxDegrees2) || (servoPosition2 <= servoMinDegrees2)) {
Motor2.detach();
reverse = true;
}
// make the servo move to the next position
Motor2.write(servoPosition2);
// and record the time when the move happened
}
if (reverse == true){
if (currentMillis - previousServoMillis >= servoInterval) {
// its time for another move
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition <= servoMinDegrees) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval == servoSlowInterval) {
servoInterval = servoFastInterval;
}
else {
servoInterval = servoSlowInterval;
}
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
Motor2.detach();
reverse = false;
}
// make the servo move to the next position
Motor2.write(servoPosition);
// and record the time when the move happened
}
}
}
This is one of my attempts at making Motor2 reverse (it doesn't work).
I have looked at it, but after I detach the servo, how do I make it pause for a few seconds (without using delay) and then turn on again, but going in reverse?
The 2 servo control a panel. When the servo's rotate the panel covers what's underneath (solar panel), protecting it from any "dangers", such as dust to a solar panel. That detach is there to stop the panel and protect the solar panels from the dust (this is only the beginning of the project). When the flow of dust stops, the panel goes back, uncovering the solar panel and allowing more energy to be collected.
That is exactly what it won't do. Detaching the servo allows it to turn if the output shaft is turned by an external force. To stop the servo turning all that needs to happen is to write a constant value to it.
What value would I give holdPosition and would I replace it with the position Motor.detach(); took? And by the way I edited that post for clarity before I knew you already posted (5V and GND)
The value you use for what I named holdPosition is up to you. What angle do you want to stop the servo at ?
In your PM to me you said
I've tries making hold position = servoMinDegrees and servoMaxDegrees, but it doesn't work.
but you didn't say what you meant by that.
Please post the code that you tried.
So, the servos are powered directly from the Arduino 5V and GND pins. This is generally regarded as bad practice due to the current that can be taken by servos. Can you please provide a link to the servos being used.
#include <Servo.h>
//MOTOR
const int servoPin = 9; // the pin number for the servo signal
const int servoMinDegrees = -10; // the limits to servo movement
const int servoMaxDegrees = 190; //Increase to increase servo time on
Servo Motor; // create servo object to control a servo
int servoPosition = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval = 80; // millisecs between servo moves
int servoFastInterval = 10;
int servoInterval = servoSlowInterval; // initial millisecs between servo moves
int servoDegrees = 4; // amount servo moves at each step
unsigned long currentMillis = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis = 0; // the time when the servo was last moved
//MOTOR2
const int servoPin2 = 10; // the pin number for the servo signal
const int servoMinDegrees2 = -10; // the limits to servo movement
const int servoMaxDegrees2 = 190; //Increase to increase servo time on
Servo Motor2; // create servo object to control a servo
int servoPosition2 = 90; // the current angle of the servo - starting at 90.
int servoSlowInterval2 = 80; // millisecs between servo moves
int servoFastInterval2 = 10;
int servoInterval2 = servoSlowInterval2; // initial millisecs between servo moves
int servoDegrees2 = -4; // amount servo moves at each step
unsigned long currentMillis2 = 0; // stores the value of millis() in each iteration of loop()
unsigned long previousServoMillis2 = 0; // the time when the servo was last moved
void setup() {
Serial.begin(9600);
Serial.println("Starting SeveralThingsAtTheSameTimeRev1.ino"); // so we know what sketch is running
Motor.write(servoPosition); // sets the initial position
Motor.attach(servoPin);
Motor2.write(servoPosition); // sets the initial position
Motor2.attach(servoPin2);
}
//=======
void loop() {
currentMillis = millis(); // capture the latest value of millis()
servoSweep();
currentMillis2 = millis();
servoSweep2();
}
void servoSweep() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis - previousServoMillis >= servoInterval) {
// its time for another move
previousServoMillis += servoInterval;
servoPosition = servoPosition + servoDegrees; // servoDegrees might be negative
if (servoPosition <= servoMinDegrees) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval == servoSlowInterval) {
servoInterval = servoFastInterval;
}
else {
servoInterval = servoSlowInterval;
}
}
if ((servoPosition >= servoMaxDegrees) || (servoPosition <= servoMinDegrees)) {
Motor.write(servoMaxDegrees);
}
// make the servo move to the next position
Motor.write(holdPosition);
// and record the time when the move happened
}
}
void servoSweep2() {
// this is similar to the servo sweep example except that it uses millis() rather than delay()
// nothing happens unless the interval has expired
// the value of currentMillis was set in loop()
if (currentMillis2 - previousServoMillis2 >= servoInterval2) {
// its time for another move
previousServoMillis2 += servoInterval2;
servoPosition2 = servoPosition2 + servoDegrees2; // servoDegrees might be negative
if (servoPosition2 <= servoMinDegrees2) {
// when the servo gets to its minimum position change the interval to change the speed
if (servoInterval2 == servoSlowInterval2) {
servoInterval2 = servoFastInterval2;
}
else {
servoInterval2 = servoSlowInterval2;
}
}
if ((servoPosition2 >= servoMaxDegrees2) || (servoPosition2 <= servoMinDegrees2)) {
Motor2.write(servoMinDegrees2);
}
// make the servo move to the next position
Motor2.write(servoPosition2);
// and record the time when the move happened
}
}
The servo should stop at that position, the minimum or maximum. The degrees are even specified, but the servos continue to rotate. I replaced Motor.detach(); with the corresponding servoMin/MaxDegrees.
What you have are not servos, despite their name. They are electronically controlled motors. The value written to them controls their speed and direction and not their position as would be the case for real servos.
You cannot, therefore, stop them at a particular position. My advice would be to buy some real servos.