Hi! I have this problem that when I turn the switch off the servos dont turn slowly to the position the potentiometer is on. When I turn the switch on the servos turn correctly to their position and slowly as planned. What could be my problem? I'm pretty new to arduino.
#include <Servo.h>
Servo myservo1; // create servo 1 object to control a servo
Servo myservo2; // create servo 2 object to control a servo
int potpin = A0; // analog pin used to connect the potentiometer
unsigned int servoPin[] = {5, 6}; // watch video for details https://youtu.be/QB49Rmc96Ho
int switchPin = 7; // digital pin used for the switch
int val; // variable to read the value from the analog pin
int previousPos1 = 0; // variable to store previous position of servo 1
int previousPos2 = 0; // variable to store previous position of servo 2
boolean switchState = false; // current state of the switch
boolean servosMoved = false; // flag to track if the servos have been moved
void setup() {
Serial.begin(9600);
Serial.println("Multiple Servo");
Serial.println("Robojax.com");
myservo1.attach(servoPin[0]); // attaches the servo 1 to the servo object
myservo2.attach(servoPin[1]); // attaches the servo 2 to the servo object
pinMode(switchPin, INPUT_PULLUP); // sets the switch pin as input
digitalWrite(switchPin, HIGH);
myservo1.write(0);
myservo2.write(0);
}
void loop() {
// Read the state of the switch
switchState = digitalRead(switchPin);
previousPos1 = myservo1.read();
previousPos2 = myservo2.read();
if (switchState && !servosMoved) {
// If the switch is on and servos haven't been moved yet
previousPos1 = 90;
previousPos2 = 0;
gradualServoMovement(previousPos1, previousPos2, 2500); // Gradually move servos to new positions over 2 seconds
servosMoved = true; // Set the flag to indicate that the servos have been moved
}
else if (!switchState && servosMoved) {
// If the switch is off and servos have been moved
myservo1.write(previousPos1); // Set servo 1 position to previous position
myservo2.write(previousPos2); // Set servo 2 position to previous position
gradualServoMovement(previousPos1, previousPos2, 500);
servosMoved = false; // Reset the flag since the servos are back to their original positions
}
if (!switchState) {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 45); // Scale it to use it with the servo (value between 0 and 45)
myservo1.write(val);
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 90, 45); // Scale it to use it with the servo (value between 45 and 0)
myservo2.write(val);
}
Serial.print(val);
Serial.println();
//delay(10); // waits for the servo to get there
}
// Function for gradually moving servos from current position to target position over a specified duration
void gradualServoMovement(int targetPos1, int targetPos2, unsigned int duration) {
int startPos1 = myservo1.read(); // Get current position of servo 1
int startPos2 = myservo2.read(); // Get current position of servo 2
unsigned long startTime = millis(); // Get the start time
unsigned long remainingDuration = duration; // Initialize remaining duration
while (true) {
unsigned long elapsedTime = millis() - startTime;
if (elapsedTime >= duration) {
// Time duration has elapsed, set final position and exit the function
myservo1.write(targetPos1);
myservo2.write(targetPos2);
return;
}
// Calculate the current position based on time elapsed
float progress = elapsedTime / (float)duration;
int currentPos1 = startPos1 + (targetPos1 - startPos1) * progress;
int currentPos2 = startPos2 + (targetPos2 - startPos2) * progress;
// Set the servo positions based on the current position
myservo1.write(currentPos1);
myservo2.write(currentPos2);
// Check if the remaining duration is half of the original duration
if (elapsedTime >= duration / 2 && remainingDuration == duration) {
// Double the remaining duration
remainingDuration = duration * 2;
}
// Calculate the delay incrementally for smoother movement
unsigned long delayIncrement = remainingDuration / 100;
delay(delayIncrement);
}
}
I built it in tinkercad. Everything works otherwise, but when I turn the switch off the servos wait 0,5 seconds and then move quickly to a new position... They should turn slowly like they do when I turn the switch on.
moving to the pot postion does not use your gradualServoMovement() function. It just writes the value directly to the servo so it will move as fast as possible.
having done this before i know your code is unnecessarily long which makes it more difficult to read, understand and debug for novices as well as experienced coders
please look this over
#include <Servo.h>
const byte PinSwitch = 7;
const byte PinPot = A0;
const byte PinServo [] = { 5, 6};
const int Nservo = sizeof (PinServo);
Servo myServo [Nservo];
int pos [Nservo];
int targ [Nservo];
void
loop (void)
{
byte sw = digitalRead (PinSwitch);
if (sw) {
int ang = map (analogRead(PinPot), 0, 1023, 0, 45);
targ [0] = ang;
targ [1] = 90 - ang;
}
else {
targ [0] = 0;
targ [1] = 90;
}
for (int n = 0; n < Nservo; n++) {
if (targ [n] == pos [n])
continue; // avoid simulation prints of writes
if (targ [n] < pos [n])
pos [n]--;
else if (targ [n] > pos [n])
pos [n]++;
myServo [n].write (pos [n]);
}
delay (20);
}
void
setup (void)
{
Serial.begin (9600);
pinMode (PinSwitch, INPUT_PULLUP);
for (int n = 0; n < Nservo; n++) {
myServo [n].attach (PinServo [n]);
}
}
Make sure when you actually wire this up that you don't power the servos from the Arduino. The servos need to be directly connected to a power supply that can supply the proper voltage and current.
So when I power this up the first movement of servos is really fast and I want it to go as slow as the other movements when switch is turned on or off.
at startup there's no easy way to know the position of the servos. one awkward way would be to store the last position in EEPROM and on startup in setup, initialize the servos to that position. of course there's nothing to prevent the servos from being moved while the system is off
considering the use of the switch, it doesn't even make sense to move the servos to some default position in setup() because as soon as loop() is called, they will be moved to the position dictated by the sw and pot.
presumably if you turn the system off and back on, the servos should may jitter a bit but at least return to the position they were already at when the system was turned on
Hi! I got help before on a different problem in this code so I thought I'd ask again if someone would know a solution because I've been struggling. This is my first actual project with arduino. So still learning be kind.
So my problem now is that when I power up the system both of the servos "bounce" to a 90 degree angle from the picture below. After that bounce they start moving nice and slow to either a set position if the switch is on or to a position the potentiometer sets them. I want to eliminate the bounce at the start, but I dont know what is causing it... Thank you so much in advance <3
#include <Servo.h>
Servo myservo1; // create servo 1 object to control a servo
Servo myservo2; // create servo 2 object to control a servo
int potpin = A0; // analog pin used to connect the potentiometer
unsigned int servoPin[] = {5, 6}; // watch video for details https://youtu.be/QB49Rmc96Ho
int switchPin = 7; // digital pin used for the switch
int val; // variable to read the value from the analog pin
int previousPos1 = 0; // variable to store previous position of servo 1
int previousPos2 = 0; // variable to store previous position of servo 2
int previousPos3 = 0; // variable to store previous position of servo 1
int previousPos4 = 0;
boolean switchState = false; // current state of the switch
boolean servosMoved = false; // flag to track if the servos have been moved
void setup() {
Serial.begin(9600);
Serial.println("Multiple Servo");
Serial.println("Robojax.com");
myservo1.attach(servoPin[0]); // attaches the servo 1 to the servo object
myservo2.attach(servoPin[1]); // attaches the servo 2 to the servo object
pinMode(switchPin, INPUT_PULLUP); // sets the switch pin as input
digitalWrite(switchPin, HIGH);
previousPos1 = myservo1.read();
previousPos2 = myservo2.read();
// Read the initial state of the switch
switchState = digitalRead(switchPin);
if (!switchState) {
// If the switch is off during power-up, gradually move the servos to their original positions over 2.5 seconds
gradualServoMovement(previousPos1, previousPos2, 2500);
servosMoved = false; // Reset the flag since the servos are back to their original positions
}
}
void loop() {
// Read the state of the switch
switchState = digitalRead(switchPin);
if (switchState && !servosMoved) {
// If the switch is on and servos haven't been moved yet
previousPos1 = 90;
previousPos2 = 0;
gradualServoMovement(previousPos1, previousPos2, 3000); // Gradually move servos to new positions over 2.5 seconds
servosMoved = true; // Set the flag to indicate that the servos have been moved
Serial.println("switchState && !servosMoved");
}
else if (!switchState && servosMoved) {
// If the switch is off and servos have been moved
gradualServoMovement(previousPos3, previousPos4, 3000); // Gradually move servos to original positions over 2.5 seconds
servosMoved = false; // Reset the flag since the servos are back to their original positions
Serial.println("!switchState && servosMoved");
}
else if (!switchState) {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 45); // Scale it to use it with the servo (value between 0 and 45)
myservo1.write(val);
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 90, 45); // Scale it to use it with the servo (value between 45 and 90)
myservo2.write(val);
previousPos3 = myservo1.read();
previousPos4 = myservo2.read();
Serial.println("!switchState");
}
Serial.print(val);
Serial.println();
delay(100); // waits for the servo to get there
}
// Function for gradually moving servos from current position to target position over a specified duration
void gradualServoMovement(int& targetPos1, int& targetPos2, unsigned int duration) {
float startPos1 = myservo1.read(); // Get current position of servo 1
float startPos2 = myservo2.read(); // Get current position of servo 2
unsigned long startTime = millis(); // Get the start time
while (true) {
unsigned long elapsedTime = millis() - startTime;
if (elapsedTime >= duration) {
// Time duration has elapsed, set final position and exit the function
myservo1.write(targetPos1);
myservo2.write(targetPos2);
return;
}
// Calculate the current position based on time elapsed
float progress = elapsedTime / (float)duration;
float currentPos1 = startPos1 + (targetPos1 - startPos1) * progress;
float currentPos2 = startPos2 + (targetPos2 - startPos2) * progress;
// Set the servo positions based on the current position
myservo1.write(currentPos1);
myservo2.write(currentPos2);
// Check if the switch is turned off and update the target positions
if (!switchState) {
targetPos1 = analogRead(potpin);
targetPos1 = map(targetPos1, 0, 1023, 0, 45);
targetPos2 = analogRead(potpin);
targetPos2 = map(targetPos2, 0, 1023, 90, 45);
}
delay(10); // Delay for smooth movement
}
}
write() the initial servo position that you would like to the servo before using attach() and the servo will start in that position instead of its default of 90 degrees
By the way, powering the servos from the Arduino 5V pin is a bad idea because it cannot provide the required current and may damage the Arduino and/or cause other problems
Hello! I've asked couple questions about this code before and it works almost perfectly now but 1 thing is still bothering me... I know this code is pretty "bad" but this is my first own project and I'm still learning :))
So when I power this up the first movement of servos is really fast and I want it to go as slow as the other movements when switch is turned on or off.
I've tried different solutions but none have worked and have broken something else...
#include <Servo.h>
Servo myservo1; // create servo 1 object to control a servo
Servo myservo2; // create servo 2 object to control a servo
int potpin = A0; // analog pin used to connect the potentiometer
unsigned int servoPin[] = {5, 6}; // watch video for details https://youtu.be/QB49Rmc96Ho
int switchPin = 7; // digital pin used for the switch
int val; // variable to read the value from the analog pin
int previousPos1 = 0; // variable to store previous position of servo 1
int previousPos2 = 0; // variable to store previous position of servo 2
int previousPos3 = 0; // variable to store previous position of servo 1
int previousPos4 = 0;
boolean switchState = false; // current state of the switch
boolean servosMoved = false; // flag to track if the servos have been moved
void setup() {
Serial.begin(9600);
Serial.println("Multiple Servo");
Serial.println("Robojax.com");
myservo1.write(45);
myservo2.write(45);
myservo1.attach(servoPin[0]); // attaches the servo 1 to the servo object
myservo2.attach(servoPin[1]); // attaches the servo 2 to the servo object
pinMode(switchPin, INPUT_PULLUP); // sets the switch pin as input
digitalWrite(switchPin, HIGH);
previousPos1 = myservo1.read();
previousPos2 = myservo2.read();
// Read the initial state of the switch
switchState = digitalRead(switchPin);
if (!switchState) {
// If the switch is off during power-up, gradually move the servos to their original positions over 2.5 seconds
gradualServoMovement(previousPos1, previousPos2, 2500);
servosMoved = false; // Reset the flag since the servos are back to their original positions
}
}
void loop() {
// Read the state of the switch
switchState = digitalRead(switchPin);
if (switchState && !servosMoved) {
// If the switch is on and servos haven't been moved yet
previousPos1 = 90;
previousPos2 = 0;
gradualServoMovement(previousPos1, previousPos2, 3000); // Gradually move servos to new positions over 2.5 seconds
servosMoved = true; // Set the flag to indicate that the servos have been moved
Serial.println("switchState && !servosMoved");
}
else if (!switchState && servosMoved) {
// If the switch is off and servos have been moved
gradualServoMovement(previousPos3, previousPos4, 3000); // Gradually move servos to original positions over 2.5 seconds
servosMoved = false; // Reset the flag since the servos are back to their original positions
Serial.println("!switchState && servosMoved");
}
else if (!switchState) {
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 0, 45); // Scale it to use it with the servo (value between 0 and 45)
myservo1.write(val);
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 0, 1023, 90, 45); // Scale it to use it with the servo (value between 45 and 90)
myservo2.write(val);
previousPos3 = myservo1.read();
previousPos4 = myservo2.read();
Serial.println("!switchState");
}
Serial.print(val);
Serial.println();
delay(100); // waits for the servo to get there
}
// Function for gradually moving servos from current position to target position over a specified duration
void gradualServoMovement(int& targetPos1, int& targetPos2, unsigned int duration) {
float startPos1 = myservo1.read(); // Get current position of servo 1
float startPos2 = myservo2.read(); // Get current position of servo 2
unsigned long startTime = millis(); // Get the start time
while (true) {
unsigned long elapsedTime = millis() - startTime;
if (elapsedTime >= duration) {
// Time duration has elapsed, set final position and exit the function
myservo1.write(targetPos1);
myservo2.write(targetPos2);
return;
}
// Calculate the current position based on time elapsed
float progress = elapsedTime / (float)duration;
float currentPos1 = startPos1 + (targetPos1 - startPos1) * progress;
float currentPos2 = startPos2 + (targetPos2 - startPos2) * progress;
// Set the servo positions based on the current position
myservo1.write(currentPos1);
myservo2.write(currentPos2);
// Check if the switch is turned off and update the target positions
if (!switchState) {
targetPos1 = analogRead(potpin);
targetPos1 = map(targetPos1, 0, 1023, 0, 45);
targetPos2 = analogRead(potpin);
targetPos2 = map(targetPos2, 0, 1023, 90, 45);
}
delay(10); // Delay for smooth movement
}
}
I don't catch the usage of "servosMoved". If it is needed just for the system start, why you put it in the loop() function? Or, if it is not, why you don't set it on the last "else if (!switchState)"?
Please give more details on what in your mind the program should do (and not only what it does now):
"servosMoved" dont actually do anything usefull atm... Used it before but not anymore.
When powered on and the switch is OFF
Servos are being controlled by the potentiometer other one moving between 0 and 45 degrees and the other between 90 and 45 degrees. On start the servos should move nice and slow to a position where the potentiometer is set to.
When powered on and the switch is ON
Potentiometer doesn't move the servos. Servos should move to set position of 90 and 0 degrees nice and slow.
During the loop, while it is OFF
Potentiometer moves the servos and the position is recorded by previousPos3 and 4.
During the loop, when you set it from OFF to ON
Servos move to the set positions of 90 and 0 degrees. Potentiometer stops moving the servos.
During the loop, while it is ON
Nothing happens. Servos stay in place.
During the loop, when you set it from ON to OFF
Servos move to a position where potentiometer is set to. Potentiometer takes control of the servos again.
Ugh, you're absolutely right!
And I see HERE the problem has been solved, so for me there's no point on going on, as this thread is next to be closed/deleted...
Have a nice coding, mate.