Serial communication problem !

Hello,
I am trying to control servo motor via serial port. When sending angle, the servo does not go to true angle. What is the problem ?

#include <Servo.h> 
 
Servo myservo1;
void setup() 
{ 
  myservo1.attach(9);  // attaches the servo on pin 9 to the servo object 
  Serial.begin(9600);
  Serial.println("Arduino Serial Servo Control");
  } 
  
  void loop() 
{ 
  int angle;
  while(1){
  Serial.println("Enter servo angle: ");
  if (Serial.available() > 0) {  // check for serial input
        
    int angle = Serial.read();	 // read the incoming byte:
                    myservo1.write(angle);              // tell servo to go to position in variable 'pos' 
                  Serial.print("I received: ");
                  Serial.println(angle);                       
                } 
  }
}

What indeed. What do your serial prints tell you? What are you sending from the terminal program?

while(1) Completely unnecessary. You're already in an infinite loop, you don't need to do another one.

Serial.println("Enter servo angle: ");
  if (Serial.available() > 0) {  // check for serial input
        
    int angle = Serial.read();     // read the incoming byte:
                    myservo1.write(angle);              // tell servo to go to position in variable 'pos' 
                  Serial.print("I received: ");
                  Serial.println(angle);                       
                } 
  }

You're receiving ASCII characters from the serial monitor. '9' is not the same as 9.

When sending angle, the servo does not go to true angle.

The "angle" is simply an abstraction; the Arduino has no idea of the position of the servo. Neither, come to think of it, does the servo. It merely moves to a position that minimises the error between the measured position and the commanded position. What is your actual problem?

I sent angle (like 120) via Arduino Serial Monitor, but I did not read 120

Then Arrch nailed your issue. If you are typing three characters 1 2 and 0 into the serial monitor, you will need to collect them in a character array, null terminate it and use atoi to provide your angle variable as a byte. Before you change your code though, try sending 0 followed once the move is done by z - do you get consistent positions if you alternate?

AWOL:

When sending angle, the servo does not go to true angle.

The "angle" is simply an abstraction; the Arduino has no idea of the position of the servo. Neither, come to think of it, does the servo. It merely moves to a position that minimises the error between the measured position and the commanded position. What is your actual problem?

I want to turn servo to angle I want like 120. What should I change my codes ? When I send 120 angle, the servo send me ASCII characters; 49,50 and then 48 :roll_eyes:

, the servo send me ASCII characters; 49,50 and then 48

The servo sends you [u]nothing[/u]

This problem comes up every other week here, there are plenty of solutions on the forum

Posted this for somebody else, but it seems applicable here too. Make sure to and read and understand what is happening, rather than just copying the code and hoping it works:

/*

  • Example for Serial2Int
  • When reading from the serial monitor, there are two important things to note:
  • (1) Bytes are read one at a time. So sending “246” will be read by your
  • code as ‘2’, then ‘4’, then ‘6’. If you want to identify them as related in some
  • way, you need a way to determine that. This example uses start and stop bytes.
  • (2) Sending a number through the monitor sends it’s ASCII representation, not
  • the value itself. So typing 3 and hitting enter would send ‘3’ or 51 as per the
  • ascii table. To account for this, we will be using atoi(), which takes a null
  • terminated array of chars, also known as a string, and produces the int equivalent.
    */

// To send a number through the serial monitor, put it between brackets
const char startByte = ‘<’;
const char stopByte = ‘>’;

// Maximum characters in an int + null terminated character
const short maxBuffer = 6;

void setup() {
Serial.begin(57600);
Serial.println("[Serial2Int]");
}

void loop() {
// Stores the characters between the start and stop bytes
static char buffer[maxBuffer];
// Keeps track of spot in buffer
static short index=0;

if (Serial.available() > 0 ) {
char inChar = Serial.read();

if (inChar==startByte) { // If start byte is received
index=0; // then reset buffer and start fresh
} else if (inChar==stopByte) { // If stop byte is received
buffer[index] = ‘\0’; // then null terminate
processData(buffer); // and process the data
index=0; // this isn’t necessary, but helps limit overflow
} else { // otherwise
buffer[index] = inChar; // put the character into our array
index++; // and move to the next key in the array
}

/* Overflow occurs when there are more than 5 characters in between

  • the start and stop bytes. This has to do with having limited space
  • in our array. We chose to limit our array to 5 (+1 for null terminator)
  • because an int will never be above 5 characters */
    if (index>=maxBuffer) {
    index=0;
    Serial.println(“Overflow occured, next value is unreliable”);
    }
    }
    }

void processData(char buffer) {
unsigned int value = atoi(buffer); // convert string to int
Serial.print("Value: ");
Serial.println(value);
}