SG90 Servo jumps to 90 degrees at startup

I have a sg90 servo, powered from an external lab supply with a common ground connection to my Arduino Uno, and I control it with the following code:

#include <Servo.h>

Servo myServo;
int servoState;

void setup() {
  // put your setup code here, to run once:
  myServo.attach(11);

  Serial.begin(9600);
  Serial.println("Initialization done, wait for 2 seconds...");
  Serial.print("Initial servo state: ");
  Serial.println(servoState);
  delay(2000);
  Serial.println("Now at your service");

}

void loop() {
  // put your main code here, to run repeatedly:
  String servoCommand = Serial.readString();
  

  if (servoCommand == "up\n") {
    while (servoState > 0) {
      myServo.attach(11);
      myServo.write(servoState - 1);
      servoState -= 1;
      delay(25);
    }

    Serial.println("UP");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState);
  }

  if (servoCommand == "down\n") {
    while (servoState < 90) {
      myServo.write(servoState + 1);
      servoState += 1;
      delay(25);
    }

    Serial.println("DOWN");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState); 
  }

  if (servoCommand == "middle\n") {
    if (servoState < 45) {
      while (servoState < 45) {
        myServo.write(servoState + 1);
        servoState += 1;
        delay(25);

      }
    }
    else {
      while (servoState > 45) {
        myServo.write(servoState - 1);
        servoState -= 1;
        delay(25);
      }
    }

    Serial.println("MIDDLE");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState);
  }


}

It is okay and controls my servo perfectly, but has a huge problem. When I power up my circuit, servo first jumps to the maximum of 90 degrees then starts getting my desired commands.

I have something in my mind, how can I keep the last state of the servo in my code, then write it to the servo when I power up the circuit? or how can I just prevent servo from jumping at startup?

If you do a .write() before the .attach() the servo will move to the specified angle rather than the default which is 90 degrees

1 Like

I tried this and it worked fine. My problem is now keeping the last state of the servo. any ideas for that?

Save it EEPROM but be careful how often you do it because the EEPROM has a limited number of safe writes to each address, albeit about 10,000 from memory

1 Like

You need a controlled shutdown function to save the current servo position to EEPROM before power off, then recall it on next startup.
Compiles but untested, type "sd[ENTER]" to shutdown and hopefully save servo position for next startup.

#include <Servo.h>
#include <EEPROM.h>

Servo myServo;

int servoState;
const uint16_t eeAdd = 0x3FE; // last int address in EEPROM

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  EEPROM.get(eeAdd,servoState);
  if(servoState > 180)
    servoState = 0;
  myServo.write(servoState);
  myServo.attach(11);
  Serial.println("Initialization done, wait for 2 seconds...");
  Serial.print("Initial servo state: ");
  Serial.println(servoState);
  delay(2000);
  Serial.println("Now at your service");
}

void loop() {
  // put your main code here, to run repeatedly:
  String servoCommand = Serial.readString();
  
  if (servoCommand == "sd\n") { // type "sd[ENTER]" for shutdown
    EEPROM.put(eeAdd,servoState);
    delay(50);
    while(true);  // loop here forever, power off.
  }  
  if (servoCommand == "up\n") {
    while (servoState > 0) {
      //myServo.attach(11);
      myServo.write(servoState - 1);
      servoState -= 1;
      delay(25);
    }
    Serial.println("UP");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState);
  }
    if (servoCommand == "down\n") {
    while (servoState < 90) {
      myServo.write(servoState + 1);
      servoState += 1;
      delay(25);
    }
    Serial.println("DOWN");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState); 
  }
    if (servoCommand == "middle\n") {
    if (servoState < 45) {
      while (servoState < 45) {
        myServo.write(servoState + 1);
        servoState += 1;
        delay(25);
       }
    }
    else {
      while (servoState > 45) {
        myServo.write(servoState - 1);
        servoState -= 1;
        delay(25);
      }
    }

    Serial.println("MIDDLE");
    Serial.print("Current Servo Angle: ");
    Serial.println(servoState);
  }
}