0
votes

My servo only starts to "change" (that is what the code tells me anyway) when it is set for 180 degrees.

I've tried searching the website as well as Google, but this seems to be something that has to do very specifically with writing to Servo in an advanced non-repeatable kind of way.

The code that changes the servo is:

#include <SoftwareSerial.h>
#include <Servo.h>

const int rxPin = 12;
const int txPin = 13;
SoftwareSerial bluetooth (rxPin, txPin);

Servo myServo;
boolean canMove = true;

int rotation = 0;
int currentRotation = 0;

void setup() {
  Serial.begin(9600); // Begins Serial communication
  bluetooth.begin(9600);
  myServo.attach(11); // Sets a servo on pin 11  
}

void loop() {
  // put your main code here, to run repeatedly:

  // Checks if Serial has something to read
  if (bluetooth.available() > 0) {
    rotation = bluetooth.read(); // Reads it and sets it to an integer
  }

  currentRotation = myServo.read();

  if (currentRotation != rotation) {
    Serial.println("Current Rotation:");
    Serial.println(currentRotation);
    Serial.println("Set to:");
    Serial.println(rotation);
    for (int i = currentRotation; i < rotation; i++) {
      Serial.println("Writing to servo");
      myServo.write(i);
    }  
  }

}

There is a Processing program that sends the data to the Arduino, but I can perfectly see that the numbers are coming in in the Arduino's Serial Monitor (they vary from 0 to 180)

After doing this the only thing that shows up in the Serial Monitor is:

Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0
Current Rotation:
93
Set to:
0

over and over. The servo just twitches back and forth. The only time it changes (the number to set to comes from the Processing program) is when the number it is set to be 180. Then it moves even more back and forth and says:

Current Rotation:
179
Set to:
180
Writing to servo
Current Rotation:
179
Set to:
180
Writing to servo

over and over. What is going on and how can I fix it? Cheers, and thanks for the help!

1
What are you exactly trying to do? Do you want to receive the value from Bluetooth and move you servo (as step by step) to that value? I also don't understand why you use a loop to move the servo, why not just write the value to the servo? - Masoud Rahimi
@M.R. The first part is right. I want to use the loop so that I don’t have to use a delay to make sure that it is finished before the code comes back around and executes again because the current rotation isn’t the rotation it is set to, that would cause errors. So, the for loop insures that nothing happens until the servo has been written to. - BeastCoder
Your for loop only handles the case when the currentRotation is smaller than rotation, as you have a smaller then check - Ferrybig
@Ferrybig Oh! You are right. Thanks! - BeastCoder

1 Answers

1
votes

There are some problems with your code:

  1. You don't need to read current servo value, just save the last gave value.

  2. Moving a servo step by step is not a good option as it may have some error for movement. You need to find a dynamic delay based on a threshold of movement. For example, suppose that your max delay time for the servo to fully move from 0 to 180 is 2 seconds, so if you need to move the servo for 90 degrees you need 1 second delay.

  3. You just need to move your servo when a new data came so set servo when new data comes.

Remember to set max_delay based on your servo.

#include <SoftwareSerial.h>
#include <Servo.h>

const int rxPin = 12;
const int txPin = 13;
SoftwareSerial bluetooth(rxPin, txPin);

Servo myServo;
boolean canMove = true;

int rotation = 0;
int currentRotation = 0;

// how much time takes servo to move
int move_delay = 0;
// maximum time for changing servo state from lowest to highest value
const int max_delay = 2;

void setup()
{
    Serial.begin(9600); // Begins Serial communication
    bluetooth.begin(9600);
    myServo.attach(11); // Sets a servo on pin 11
}

void loop()
{
    // put your main code here, to run repeatedly:

    // Checks if Serial has something to read
    if (bluetooth.available() > 0)
    {
        rotation = bluetooth.read(); // Reads it and sets it to an integer

        Serial.print("New value: ");
        Serial.println(rotation);
        Serial.print("Current Rotation: ");
        Serial.println(rotation);
        if (currentRotation != rotation)
        {
            Serial.println("Setting new value");
            // find a proper delay
            move_delay = (max_delay / 180) * (abs(rotation - currentRotation)) * 1000;
            myServo.write(rotation);
            delay(move_delay);
            currentRotation = rotation;
        }
    }
}