Go Down

Topic: Serial communication and control. HELP! (Read 683 times) previous topic - next topic

Hello, I am new to Arduino and coding in general, so I delayed posting this in the hopes that I can just learn to do it myself. But I am running out of ideas and really need some help. What I want to do is pretty simple: I would like to input an angle into the serial monitor and have my servo motor turn to that angle.

The problem is that I can't seem to get the Arduino to read the numbers I input together, which makes sense because it IS "serial" communication, but there must be a way to do this right? I am able to get the Arduino to print many different characters at once, but that doesn't help because I need to be able to use the entire value to control my servo. Please help me!

Below is the code I found and was trying to use
------------------------------------------------------------------------------------------------------------------------------------------------------------------



int  serIn; //var that will hold the bytes in read from the serialBuffer

void setup() {
  Serial.begin(9600);

}

int thing;

void loop () {
if(Serial.available() > 0 && Serial.available() < 4){
    //inform that Arduino heard you saying something
    Serial.print("Angle value recieved:");
   
    //keep reading and printing from serial untill there are bytes in the serial buffer
     while (Serial.available()>0){
        serIn = Serial.read();   //read Serial       
        Serial.print(serIn, BYTE);    //prints the character just read
     }
     
    //the serial buffer is over just go to the line (or pass your favorite stop char)               
    Serial.println(BYTE);
  }

  //slows down the visualization in the terminal
  delay(1000);
}

Msquare

First fix:
Code: [Select]
if(Serial.available() > 0 && Serial.available() < 4){
If you somehow get behind in reading from serial, then this if will stop it from reading once you are more than 4 bytes behind.

I suspect you wanted to have a 4 character number, but you must do your own buffering, not use the serial buffer.

Woah wait, buffering? how do I do that? And I do only want 3 bytes to get read; the angle will go from 1 degree to 359 degrees. Are you saying that having that condition in there impedes my ability to read and use more than one byte at a time?

Msquare

#3
Apr 08, 2011, 10:48 pm Last Edit: Apr 08, 2011, 11:06 pm by Msquare Reason: 1
Well, I do not know what you thought, but I have seen a number of interesting attempts on this Forum, and your first try was leaning in that direction.

Anyhow, a bit of solution. I often have small sketches where I want to tweak something while testing, and rather than recompile and upload a sketch with a new value I use the Serial. I'll just cut-n-paste bits from my last one.

Code: [Select]
boolean SerGet( ) {
 while ( Serial.available()>0 ) {
   SerC = Serial.read() ;
   if ('a'<=SerC&&SerC<='z') SerC &= B01011111 ; // forces uppercase (for 7bit ASCII)
   switch (SerC) {
     case '0' : case '1' : case '2' : case '3' : case '4' :
     case '5' : case '6' : case '7' : case '8' : case '9' :
       SerV = SerV*10 + byte(SerC)-byte('0') ; //Serial.print(SerV) ;
       break ;
     case 'Z' : ValZ = constrain(SerV,0,12) ; return (true) ;
     case 'A' : ValA = constrain(SerV,0,180) ; return (true) ;
 }
 return ( false ) ;
}

This will accumulate a number of digits in SerV as an integer. The function returns false until it sees the terminating char. So when it returns true you have a valid command char in SerC and a value in SerV. (This code also keeps the value in a dedicated variable... for some other reasons)

So on my terminal I enter 5Z or 234A  or 66a4z and the code can ten use that for a servo (A for angle ...)

(Edited a cut-n-paste error in the code)

This looks great, thank you so much. For some reason it isn't able to compile when I put it into my sketch. That should go behind the setup and loop parts correct?

AWOL

#5
Apr 08, 2011, 11:02 pm Last Edit: Apr 08, 2011, 11:07 pm by AWOL Reason: 1
You have void function returning a bool value "false".

"return" isn't a function - the parentheses are unnecessary.
"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.

Msquare

#6
Apr 08, 2011, 11:05 pm Last Edit: Apr 08, 2011, 11:08 pm by Msquare Reason: 1
Actually, occasionally it returns true, too  :)

Cut-n-paste error  :smiley-roll-blue: - thats the header of a differnt function. I have edited the post above.

(Edit to correct the tense of above sentence)

Sorry, but I am not sure I understand your code. Could you comment on it a little more or tell me what I should input and what I should expect as an output?

zoomkat

Quote
What I want to do is pretty simple: I would like to input an angle into the serial monitor and have my servo motor turn to that angle.


The below should do what you ask.

Code: [Select]

// zoomkat 10-4-10 serial servo test
// type servo position 0 to 180 in serial monitor
// for writeMicroseconds, use a value like 1500
// for IDE 0019 and later
// Powering a servo from the arduino usually DOES NOT WORK.

String readString;
#include <Servo.h>
Servo myservo;  // create servo object to control a servo

void setup() {
  Serial.begin(9600);
  myservo.attach(7);  //the pin for the servo control
  Serial.println("servo-test-21"); // so I can keep track of what is loaded
}

void loop() {

  while (Serial.available()) {
    delay(1); 
    if (Serial.available() >0) {
      char c = Serial.read();  //gets one byte from serial buffer
      readString += c; //makes the string readString
    }
  }

  if (readString.length() >0) {
    Serial.println(readString);  //so you can see the captured string
    int n;
    char carray[6]; //converting string to number
    readString.toCharArray(carray, sizeof(carray));
    n = atoi(carray);
    myservo.writeMicroseconds(n); // for microseconds
    //myservo.write(n); //for degees 0-180
    readString="";
  }
}

Google forum search: Use Google Advanced Search and use Http://forum.arduino.cc/index in the "site or domain:" box.

Wow thank you so much zoomkat. Now all I have to do is understand it, but I think I can handle that part. The sketch works great! :^)

Go Up