Go Down

Topic: Serial communication problem ! (Read 656 times) previous topic - next topic

shadowcand

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 ?
Code: [Select]
#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);                       
                }
  }
}

wildbill

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

Arrch

 
Code: [Select]
while(1)
Completely unnecessary. You're already in an infinite loop, you don't need to do another one.
 
Code: [Select]
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.

AWOL

#3
May 13, 2012, 07:13 pm Last Edit: May 13, 2012, 08:06 pm by AWOL Reason: 1
Quote
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?
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

shadowcand

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

wildbill

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?

shadowcand

#6
May 13, 2012, 08:52 pm Last Edit: May 13, 2012, 08:54 pm by shadowcand Reason: 1

Quote
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   :smiley-roll:

AWOL

#7
May 13, 2012, 09:03 pm Last Edit: May 13, 2012, 09:05 pm by AWOL Reason: 1
Quote
, the servo send me ASCII characters; 49,50 and then 48

The servo sends you nothing

This problem comes up every other week here, there are plenty of solutions on the forum
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Arrch

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:

Quote

/*
* 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);
}


Go Up