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);
}
}
}
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?
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?
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
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 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);
}