Servo angle not stable after pushbutton

Hello ! I have started Arduino a year ago and currently working on a basic robot project : When a pushbutton is pressed it triggers flashing LEDs and the robot arm waves up and down for a set period of time - The idea is for the arm to start and finish at the same position until the pushbutton is pressed again. At the moment I am ensuring this by matching the total duration of the action (led flashing and arm waving) with : degrees x Time to move 1 degree.

My code is working although I encounter 2 problem,

1.sometimes the arm does not start and finish at the same positon (it generally rush to one angle and then stabilize to regular speed)
Is this due to the surge of current incoming after the button is pressed ? Should I put a capacitor if so where and which capacitance ? (I will have 12 servos in parallel at some point shariong 1 data signal)

2/ aftter an extended period of incativity, the servo does not react (the LEDs do)

Thanks!!!
Gif here : Imgur: The magic of the Internet

Code here ;

#include<Servo.h>

Servo myservo;
const int buttonPin = 8;
const int ledPin = LED_BUILTIN;

int pos = 0; // variable to store the servo position
int direction = 0; // variable to stor servo direction

unsigned long previousMillis = 0;

int ledState = LOW;
bool isPressed = false;
const long actionDuration = 6080; // duration of led and servo function
const long onDuration = 1000; // led ON Duration
const long offDuration = 1000; // led OFF Duration

#definerunEvery(t) for (static typeof(t) _lasttime; (typeof(t))((typeof(t))millis() - _lasttime) > (t); _lasttime += (t))

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
myservo.write(pos);
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}

void loop()
{
if (digitalRead(buttonPin) == HIGH && isPressed == false)
{ //button is pressed AND this is the first digitalRead() that the button is pressed
Serial.println("button is pressed");
isPressed == true;
unsigned long startTime = millis();
Serial.println("Action starts");
while ((millis() - startTime) < actionDuration)
{ // trigger action
servo();
led();
}
isPressed == false;
Serial.println("Action over");
}
}

void servo()
{
runEvery(10) //run every 10 milliseconds
{
if (pos < 60 && direction == 0)
{
pos = pos + 1;
}
if (pos > 0 && direction == 1)
{
pos = pos - 1;
}
}

if (pos == 60)
{
direction = 1;
}
if (pos == 0)
{
direction = 0;
}
myservo.write(pos);
Serial.print("servo position is :");
Serial.println(pos);
}

void led()
{

if (ledState == HIGH)
{
if ((millis() - previousMillis) >= onDuration)
{
ledState = LOW; // change the state of LED
digitalWrite(ledPin, ledState); // set initial state
previousMillis = millis(); // remember Current millis() time
}
}
else
{
if ((millis() - previousMillis) >= offDuration)
{
ledState = HIGH; // change the state of LED
digitalWrite(ledPin, ledState); // set initial state
previousMillis = millis(); // remember Current millis() time
}
}
}

Firstly, in your code, change isPressed* == true;* to isPressed* = true;* . Don't confuse the assignment operator = (single equal sign) with the "equal to" comparison operator == (double equal signs)

Secondly, please make sure that you provide enough power to servo motors via external power source. See Servo motor does not work check list

I fixed the code and tried with external power supplying 5v to the Arduino and the servo.
I still have the same problems with the angle and the inactivity after extended period of non pressed button

I am actualy wondering if the code is not conflicting between the duration in Ms and the State machine logic (duration and POS). When the action stops the direction is not conistent nor the angle.

Does the servo uses the value delcared before any loops ? So everytime is starts servo(); it used 0 as POS instead of the last stored value in the void.

Would your servos have plastic gears that quickly wear out and have a terrible hysteresis issues or are you using a good quality metal geared servo?

Have you tried to put your well formatted code in code tags?

Have you considered using write uSeconds instead of using degrees?

There are, when the servo library is set for 180 degree rotation, 11.11uS per degree, I find that many good quality hobby servos can respond to a small torque change.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.