Pages: [1]   Go Down
Author Topic: Serial communication problem !  (Read 544 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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);                       
                }
  }
}
Logged

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3402
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24320
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
« Last Edit: May 13, 2012, 01:06:52 pm by AWOL » Logged

"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.

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

New Jersey
Offline Offline
Faraday Member
**
Karma: 48
Posts: 3402
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 18
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: May 13, 2012, 01:54:06 pm by shadowcand » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 238
Posts: 24320
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: May 13, 2012, 02:05:21 pm by AWOL » Logged

"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.

California
Offline Offline
Faraday Member
**
Karma: 82
Posts: 3123
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Logged

Pages: [1]   Go Up
Jump to: