I have tried a dozen ways to try and control the initial servo speed when it makes it first movement to a new starting degree, but nothing seems to work. I can control the speed and range once the servo reached a new PWM starting point range " if (pwmValue < 1150) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1175) { delayValue = 4; startPos = 70; endPos = 110; }"
And I can control the speed of the servo when I stop sending a signal, and it will move back to a neutral point at a speed I select "int neutralDelayValue = 4; // Set the delay value for neutral position, adjust as needed"
Can someone please help me add to this code what is required for me to slow down the servo when it moves to a new degree range. Right now it just moves as fast as it can to a new speed, I would like to slow this down to speed 4.
I would very grateful for your help.
#include <Servo.h>
Servo myservo;
const int pwmPin = 2; // the pin where the throttle PWM signal will be read
const int servoPin = 9; // the pin where the servo is connected
int pwmValue = 0; // variable to store the read PWM value
void setup() {
myservo.attach(servoPin); // attaches the servo on pin 9 to the servo object
pinMode(pwmPin, INPUT);
Serial.begin(9600); // for debugging purposes
}
void loop() {
pwmValue = pulseIn(pwmPin, HIGH); // read the PWM value
// You can print the PWM value to the Serial Monitor for debugging
Serial.println(pwmValue);
// Determine delay value and corresponding start and end positions for twenty distinct servo speeds and ranges
int delayValue;
int startPos;
int endPos;
if (pwmValue < 1150) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1175) { delayValue = 4; startPos = 70; endPos = 110; }
else if (pwmValue < 1200) { delayValue = 4; startPos = 70; endPos = 110; }
else if (pwmValue < 1250) { delayValue = 4; startPos = 70; endPos = 110; }
else if (pwmValue < 1300) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1350) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1400) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1450) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1500) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1550) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1600) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1650) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1700) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1750) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1800) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1850) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1900) { delayValue = 1; startPos = 55; endPos = 125; }
else if (pwmValue < 1950) { delayValue = 1; startPos = 55; endPos = 125; }
else if (pwmValue < 2000) { delayValue = 1; startPos = 55; endPos = 125; }
else { delayValue = 1; startPos = 55; endPos = 125; }
// If the PWM signal is above a certain threshold (e.g. 1200 = 20% on throttle screen), the servo will start to move,
// the higher this number the long it takes % wise on the throttle screen value to start moving
// giving the trigger some play before starting motor which is nice.
int neutralDelayValue = 4; // Set the delay value for neutral position, adjust as needed
if (pwmValue > 1100) {
// Move servo within the calculated range
for (int pos = startPos; pos <= endPos; pos++) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
// Move servo back to the start position
for (int pos = endPos; pos >= startPos; pos--) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
} else if (pwmValue < 1100) {
// Get the current position of the servo
int currentPos = myservo.read();
// Determine the direction of motion
int direction = (currentPos < 90) ? 1 : -1;
// Move servo to the neutral position of 45 with a controlled speed
for (int pos = currentPos; pos != 90; pos += direction) {
myservo.write(pos);
delay(neutralDelayValue); // Delay controls the speed of the motion
}
}
}
Thank you, I have just tried this code, and when I upload it, I have no control of the servo, it does not move. Unfortunately, I do not know coding beyond just changing some values of a working code. What I have generated is from ChatGPT and it works perfect except the servo speed as it moves to a new start value/degree.
ok, I litterally just pasted this exact question into chatgpt and it gave me a solution and it works perfectly... Not sure what it was not giving me a working solution before but here is the solution..
The primary problem you're facing is that, when a new PWM range is selected, the servo moves directly to the startPos and begins its routine from there. To slow down this initial movement to startPos, you'll want to create a function that eases the servo into the new starting position.
Here's the new function and modifications to your code:
Add a new function moveToPosition:
cppCopy code
void moveToPosition(int targetPos, int speed) {
int currentPos = myservo.read();
int direction = (currentPos < targetPos) ? 1 : -1;
while (currentPos != targetPos) {
currentPos += direction;
myservo.write(currentPos);
delay(speed);
}
}
Now, call this function just before your servo starts its main movement routine:
cppCopy code
// ... [The rest of your code]
// If the PWM signal is above a certain threshold (e.g. 1200 = 20% on throttle screen),
if (pwmValue > 1100) {
moveToPosition(startPos, 4); // Add this line
// Move servo within the calculated range
for (int pos = startPos; pos <= endPos; pos++) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
// Move servo back to the start position
for (int pos = endPos; pos >= startPos; pos--) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
} else if (pwmValue < 1100) {
// ... [The rest of your code]
}
With this modification, when the code detects a change in the PWM signal that triggers a new range, the moveToPosition function will first ease the servo into the new starting position at a speed of 4 before it starts the main movement routine.
If your servo is in an unknown position or
if there is no power on the servo because everything is switched off
and the servohorn got moved servo pure mechanically to a different position
the servo will move at full speed to the given position.
If you would like to avoid this case you would have to use servos that have positionfeedback on a extra wire.
Interesting, I don't have that option on the servo im using, but I see every time I turn on the power to the system, the servo now moves back and forth very quickly a few times then stops at neutral position, not sure, why or how to stop this violent start??
Well the reason is: chatGPT is a KI. Not a real person.
The name chatGPT is well chosen. It is chatting based on probabilities.
If chatGPT does not find a 100,00% matching answer in is knowledge-base it goes on with that answer that has the highest percentage in matching.
Though as it is below 100,00% it does not fit 100,00%.
You could give chatGPT a challenge:
Post your actual code that shows this weird behaviour to chatGPT with a new prompt that describes the behaviour that you have seen.
Let's see if chatGPT is able to solve this problem by presenting a modified code-version.
My expectation is rather that chatGPT will give you more generalised hints on how to solve this problem your self.
Needed Setup:
bool firstRun = true; // Add this line here
Then:
void loop() {
if (firstRun) {
delay(1000); // Delay for a second on first power-up to stabilize the system
firstRun = false;
}
pwmValue = pulseIn(pwmPin, HIGH); // read the PWM value
here is working code FYI:
#include <Servo.h>
Servo myservo;
const int pwmPin = 2; // the pin where the throttle PWM signal will be read
const int servoPin = 9; // the pin where the servo is connected
int pwmValue = 0; // variable to store the read PWM value
bool firstRun = true; // Add this line here
void setup() {
myservo.attach(servoPin); // attaches the servo on pin 9 to the servo object
pinMode(pwmPin, INPUT);
Serial.begin(9600); // for debugging purposes
}
void moveToPosition(int targetPos, int speed) {
int currentPos = myservo.read();
int direction = (currentPos < targetPos) ? 1 : -1;
while (currentPos != targetPos) {
currentPos += direction;
myservo.write(currentPos);
delay(speed);
}
}
void loop() {
if (firstRun) {
delay(1000); // Delay for a second on first power-up to stabilize the system
firstRun = false;
}
pwmValue = pulseIn(pwmPin, HIGH); // read the PWM value
// You can print the PWM value to the Serial Monitor for debugging
Serial.println(pwmValue);
// Determine delay value and corresponding start and end positions for twenty distinct servo speeds and ranges
int delayValue;
int startPos;
int endPos;
if (pwmValue < 1150) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1175) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1200) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1250) { delayValue = 4; startPos = 45; endPos = 135; }
else if (pwmValue < 1300) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1350) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1400) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1450) { delayValue = 3; startPos = 45; endPos = 135; }
else if (pwmValue < 1500) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1550) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1600) { delayValue = 2; startPos = 45; endPos = 135; }
else if (pwmValue < 1650) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1700) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1750) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1800) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1850) { delayValue = 1; startPos = 45; endPos = 135; }
else if (pwmValue < 1900) { delayValue = 1; startPos = 55; endPos = 125; }
else if (pwmValue < 1950) { delayValue = 1; startPos = 55; endPos = 125; }
else if (pwmValue < 2000) { delayValue = 1; startPos = 55; endPos = 125; }
else { delayValue = 1; startPos = 55; endPos = 125; }
// If the PWM signal is above a certain threshold (e.g. 1200 = 20% on throttle screen), the servo will start to move,
// the higher this number the long it takes % wise on the throttle screen value to start moving
// giving the trigger some play before starting motor which is nice.
int neutralDelayValue = 4; // Set the delay value for neutral position, adjust as needed
if (pwmValue > 1100) {
moveToPosition(startPos, 4); // Add this line
// Move servo within the calculated range
for (int pos = startPos; pos <= endPos; pos++) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
// Move servo back to the start position
for (int pos = endPos; pos >= startPos; pos--) {
myservo.write(pos);
delay(delayValue); // Delay controls the speed of the motion
}
} else if (pwmValue < 1100) {
// Get the current position of the servo
int currentPos = myservo.read();
// Determine the direction of motion
int direction = (currentPos < 90) ? 1 : -1;
// Move servo to the neutral position of 45 with a controlled speed
for (int pos = currentPos; pos != 90; pos += direction) {
myservo.write(pos);
delay(neutralDelayValue); // Delay controls the speed of the motion
}
}
}
Please, in your own words, explain how the issue described in #6 has been addressed.
You cannot, successfully, because it has not. The problem of an unknown power-up starting position cannot be reliably resolved without a feedback mechanism. The best you can do is manually ensure that your servo is, for example, 'centered', then arrange the first motion to be 'to center'. That will minimize the 'twitch'. But, if you then start up with the servo at one extreme end, there will inevitably be a starting 'jump' to the first commanded position.
Sorry for the confusion, I did not resolve the jump to position during boot up. But I was able to program out the initial servo swings back and forth upon boot up.