Servo is not doing what I want

Hi there, so I am trying to make a steering mechanism for a RC car using a servo. Because of this, I want it to start at 90 degrees, which I tried to accomplish, using write(90); before the attach-function, but instead, it starts at 0. Anybody have an idea how that could happen? (Still very new to Arduino)

I also want the servo to sort of have 'borders', so it cannot go past 50 or 130 degrees, so it would always stay in between. As of now I don't really know how I can accomplish that, I tried to do it by defining Max- and MinServo, which clearly doesn't do anything, as I would probably need to use it in a function. If anybody could help with that as well, that would be awesome.

Code is linked below.

#include <Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width,  in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

#define MaxServo 130
#define MinServo 50

#define Knipper_Links 4
#define Knipper_Rechts 5

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

int pos = 0;    // variable to store the servo position
int stuur_hoek = 0;
char input;
void setup() {
  myservo.attach(8);
  myservo.write(90);  // attaches the servo on pin 9 to the servo object
  Serial.begin(9600);
      // SETUP OLED
  if (!oled.begin(SSD1306_SWITCHCAPVCC, 0x3D)) {
    Serial.println(F("SSD1306 allocation failed"));
    while (true);
  }
  delay(2000); // wait for initializing
  oled.setCursor(0, 0);
}

void loop() {
  if (Serial.available()) {
    input = Serial.read();
  }
  
if (input == 'a') {
  myservo.read();
  stuur_hoek = stuur_hoek + 5;
  Serial.println(90 - stuur_hoek);
  //knipper_links();
}
else if (input == 'd') {
  myservo.read();
  stuur_hoek = stuur_hoek - 5;
  Serial.println(90 + stuur_hoek);
  //knipper_rechts();
}
  
  
  sturen(stuur_hoek);
  delay(100);

  
}

void sturen(int hoek) {
  // rechts
 int huidige_hoek = myservo.read();
if(hoek > huidige_hoek) {
    for (pos = huidige_hoek; pos <= hoek; pos += 1) {  // goes from 0 degrees to 180 degrees
      // in steps of 1 degree
      myservo.write(pos);  // tell servo to go to position in variable 'pos'
      delay(30);           // waits 15 ms for the servo to reach the position
    }
}
// links
  if(hoek < huidige_hoek) {
for (pos = huidige_hoek; pos >= hoek; pos -= 1) {  // goes from 180 degrees to 0 degrees
    myservo.write(pos);                                     // tell servo to go to position in variable 'pos'
    delay(30);                                              // waits 15 ms for the servo to reach the position
  }
    
  
  }
}

void knipper_rechts() {

}

void knipper_links() {
 
}


I'm pretty sure that after attach the servo is at 90 degree.
Though you can try to execute the write before the attach
the code above does attach and after attach the write(90)

You should do a basic test with simply

myservo.attach(servoPin);

and have a look to what position your servo moves.

For adjusting the steering-mechanism:
Usually you can dismount the servo-horn change the angle and mount the servo-horn in a different angle.

Post a picture of your servo outside your rc-car

best regards Stefan

Look at the attach function from the Servo library.
servo.attach(pin, min, max);

I assume that you realise that you can change the angle of the servo output arm by removing it and turning it round

Hi Stefan, well, the weird thing is, it doesn't start at 90 degrees. Also, when I turn it by hand when it's disconnected, and I connect it again, the servo turns itself to 0 degrees, as if 90 = 0. The reason I'm sure it's at 0, and not 90, is because it won't let me move it by using my 'd'-button on my keyboard, and when I turn it by hand, I can turn it 180 degrees from it's starting position. (It is a servo with a max of 180 degrees)

Of course, but it just starts at 0, while it shouldn't, that's the whole issue.

void loop() {
  if (Serial.available()) {
    input = Serial.read();
  }

  if (input == 'a') {
    myservo.read();
    stuur_hoek = stuur_hoek + 5;
    Serial.println(90 - stuur_hoek);
    //knipper_links();
  }
  else if (input == 'd') {
    myservo.read();
    stuur_hoek = stuur_hoek - 5;
    Serial.println(90 + stuur_hoek);
    //knipper_rechts();
  }
  sturen(stuur_hoek);
  delay(100);
}

I see a few problems with this loop() code:

  1. Once input is equal to 'a' or 'd' then it will stay equal to 'a' or 'd' until another serial input. Therefore every 100ms or so it will either increment or decrement stuur_hoek by 5.
  2. There is nothing to limit the upper or lower value of stuur_hoek and therefore it could theoretically be anything between -32,768 to +32,767.
  3. This line of code does nothing:
    myservo.read();

That should work, thanks.

This works fine for me now, it does what it needs to do, it should stay at for example a 100 degrees, once I've communicated 'd' two times to serial monitor.

Why would this be a problem?

Is the servo positive lead plugged into the Vin pin :thinking:

Lol no, I've connected a 9V battery to breadboard, and connected a cable from breadbord plus to V-in.

Because the servo write() method expects 0 to 180.

Just so everyone is on the same page, show us a schematic.

9V battery cannot provide enough current without a significant voltage drop for servos. Are you powering servos from this? Most servos are a max of 6V.

Also, if the value you pass to the write() method is a negative value it will correct it to 0. If you pass a value >544 it will assume microseconds and transmit a corresponding pulse width.

Do not use the 5V Arduino output to power the servo. If you are, that is part or all of the problem.

A 4xAA battery pack should work well, but don't forget to connect the grounds.

But it needs to be a variable, so how could I fix that?

I will try that, maybe it'll help.

I assume when I type write(90);, the servo will take that as degrees, or should I communicate degrees specifically to it, in some way?

I am not using the 5V supply from Arduino. I'm using an extensive 9V battery for the power supply, exactly how you've shown it in the picture above. But thanks for the tip.

By the way, ToddL1962, personally, I'm thinking int pos = 0; is messing with the servo or something, as pos is also communicating a position for the servo. Also, whenever I communicate 'a' to the serial monitor, it will turn to 90 degrees immediately, and it will also return to 0 after that, which it both shouldn't do. So yeah, that's why I think my communication with the servo isn't entirely right, and that I think I'm telling it to move to 0, somewhere.

In that case, what voltage is the servo being powered with ?