Receiving strings and floats over the serial

Selecting from a menu of events and inputting to that event using processing and arduino How do I read multiple characters I am looking for: "rad" or "deg". How do I read the float?

The processing GUI is a textfield to type degrees or radians then send the information to the arduino.

For instance, I select degrees and type 180.0. Then I hit send. Processing sends deg180.0 over the serial. If I were to select radians and type 3.14, it would send rad3.14.

On the Arduino side, how do I read this information?

Processing code:

float angleInput;
angleInput = Float.parseFloat(txf_angleInput.getText());
println(angleInput);

Arduino code:

char ch = Serial.read();

This handles the first character. I get either 'r' or 'd'. How do I read multiple characters I am looking for: "rad" or "deg". How do I read the float?

When Processing sends "deg180.0", that is 8 bytes. The Arduino code snippet only reads 1 of them. You need to read [u]all[/u] of them, into a string (note the lower case s), and then convert that parse that string and convert the numeric portion to a float (atof(), perhaps).

How will you know when you have read all of them? Sending 180.0d or 1.57r would make more sense. The r or d would be the end of packet marker, defining the type of value (degrees or radians) AND marking the end of the value (replace it with a NULL).

PaulS: When Processing sends "deg180.0", that is 8 bytes. The Arduino code snippet only reads 1 of them. You need to read [u]all[/u] of them, into a string (note the lower case s), and then convert that parse that string and convert the numeric portion to a float (atof(), perhaps).

Yes, that is exactly what I am trying to do.

How will you know when you have read all of them? Sending 180.0d or 1.57r would make more sense. The r or d would be the end of packet marker, defining the type of value (degrees or radians) AND marking the end of the value (replace it with a NULL).

They are terminated by a carriage return "\n". Ok I'll work on getting a packet market code working and report back if I need help.

edit: Ok now I remember why I put the event handler first "r" or "d". Because if I send an "s" first, that is the kill switch to stop the motor. It doesn't matter though sending a float first doesn't take up that much time.

I remember why I put the event handler first "r" or "d".

A semantics issue, but "r" and "d" are not event handlers. They may be commands.

If the command comes first, the end of packet marker must be something. Carriage return ('\n') or line feed ('\r') are fine. You must read and store all data until the end of packet marker arrives. Then, replace the "command" ('r' or 'd') with a space, and then call atof().

I am having a problem reading in the data still. I am having problems with the characters being sent that I cannot see on the serial. It seems like there are two things being sent that don’t display and one of them is \r? Can you give me some links on learning how to deal with this? Or a keyword that I can google?

Here is what I have so far

/*
This code handles two inputs:
if Input == S
  Stop
if Input == D359.12 (input is 6 characters long)
  Rotate motor in degrees to 359.12
*/

char incomingByte;   // for incoming serial data
char incomingFloat[7]; // one extra for the '\0' thing. Why do I need this again?
int i=0;
void setup() {
  Serial.begin(9600);   // opens serial port, sets data rate to 9600 bps
}

void loop() {

  if (Serial.available() > 0) { //Wait until message is sent
    incomingByte = Serial.read();
  }
    if (incomingByte == 'S'){ //If the "kill switch" message is received
      Serial.println("Stopped"); //Later put in the Motor kill switch code here
    }
    if (incomingByte == 'D'){ // Callout that designates the next 6 characters (bytes?) to be interpreted as a degree.
      for(int j = 0; j<6; ){
        if (Serial.available()>0){
          incomingFloat[j]=Serial.read();
          j++;
        }
      }
      Serial.println(incomingFloat); //Check if it read in the float correctly
    }

Fixed

// zoomkat 10-29-10 simple delimited ',' string parce 
// from serial port input (via serial monitor)
// and print result out serial port
// CR/LF could also be a delimiter
// for IDE 0019 and later

// expect a 3 piece string like R,A,1.04235
// code for Radian, Absolute, 1.0435 radians

String readString[3];
char copy[7];
int i = 0;
char rotMode; // Rotate mode can be R or D: radians or degrees
char absOrRel; // Angle relative or absolute? A = Absolute, B = Relative
float angle; // Angle inputted

void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // so I can keep track of what is loaded

}

void loop() {


  while (Serial.available()) {
    delay(10);  //small delay to allow input buffer to fill
    char c = Serial.read();  //gets one byte from serial buffer
    
    // if S, stop it
    if (readString[0] == 'S'){
     Serial.println("Stop All"); 
    }
    
    // If Z, calibrate it
    if (readString[0] == 'Z'){
      Serial.println("Calibrate it");
    }
    
    if (c == ',') {
      i++;
      break;
    }  //breaks out of capture loop to print readstring
    readString[i]+=c; //builds the string readString char by char 
    if (c == '\r') {
      i = 0;
    }     
  }
  if (readString[1].length() >0) { //If there is a string built 
    
    // Set flags if R, D, if A, B
    if (readString[0] == 'R'){
      rotMode = 'R';
      Serial.println("rotMode = 'R'");
    }
    
    if (readString[0] == 'D'){
      rotMode = 'D';
      Serial.println("rotMode = 'D'");
    }
    
    if (readString[1] == 'A'){
      absOrRel = 'A';
      Serial.println("absOrRel = 'A'");
    }
    
    if (readString[1] == 'B'){
      absOrRel = 'B';
      Serial.println("absOrRel = 'B'");
    }
    readString[1]="";
  }
  if (readString[2].length() >0) { 
    readString[2].toCharArray(copy,7);
   
    Serial.println(atof(copy),7);
    // Capture degree/radian angle float value. 7 characters (6 w/ decimal)

    readString[2]="";
  }
}

Old Post below
------------

I reworked the whole thing.

Why is this outputting

serial-delimit-21
rotMode = ‘R’
0.0000000 WHY IS THIS HERE?
absOrRel = ‘A’
14.0000000

// zoomkat 10-29-10 simple delimited ',' string parce 
// from serial port input (via serial monitor)
// and print result out serial port
// CR/LF could also be a delimiter
// for IDE 0019 and later

// expect a 3 piece string like R,A,1.04235
// code for Radian, Absolute, 1.0435 radians

String readString[3];
char copy[7];
int i = 0;
char rotMode; // Rotate mode can be R or D: radians or degrees
char absOrRel; // Angle relative or absolute? A = Absolute, B = Relative
float angle; // Angle inputted

void setup() {
  Serial.begin(9600);
  Serial.println("serial-delimit-21"); // so I can keep track of what is loaded

}

void loop() {


  while (Serial.available()) {
    delay(10);  //small delay to allow input buffer to fill
    char c = Serial.read();  //gets one byte from serial buffer
    
    // if S, stop it
    if (readString[0] == 'S'){
     Serial.println("Stop All"); 
    }
    
    // If Z, calibrate it
    if (readString[0] == 'Z'){
      Serial.println("Calibrate it");
    }
    
    if (c == ',') {
      i++;
      break;
    }  //breaks out of capture loop to print readstring
    readString[i]+=c; //builds the string readString char by char 
    if (c == '\r') {
      i = 0;
    }     
  }
  if (readString[0].length() >0) { //If there is a string built

    
    
    // Set flags if R, D, if A, B
    if (readString[0] == 'R'){
      rotMode = 'R';
      Serial.println("rotMode = 'R'");
    }
    
    if (readString[0] == 'D'){
      rotMode = 'D';
      Serial.println("rotMode = 'D'");
    }
    
    if (readString[1] == 'A'){
      absOrRel = 'A';
      Serial.println("absOrRel = 'A'");
    }
    
    if (readString[1] == 'B'){
      absOrRel = 'B';
      Serial.println("absOrRel = 'B'");
    }

    readString[2].toCharArray(copy,7);
    Serial.println(atof(copy),7);
    // Capture degree/radian angle float value. 7 characters (6 w/ decimal)
    readString[0]=""; //clears variable for new input
    readString[1]="";
    readString[2]="";
  }
}