How can i read serial data into a string until a certain character is recieved? This is not a duplicate of my other question. This question deals with reading specific data within a serial stream. The other question deals with reading and adding data into a manageable data string.

What I'm trying to do is send a command to serial, get the response, and put it into a string, and then break that string up into usable parts of data. 

The problem I'm having, is there is a delay between the time the serial command is sent, and the response. meaning the serial data isn't being captured before the function moves onto the next line. Using delay() doesn't appear to work, as i believe it halts everything for that delay period.

What I'm hoping to do, is read the data from serial and if the character '&lt;' is received, place it, and everything after it into the buffer until the character ">" is received.  After the last character is received, and placed into the buffer, continue on with the script.

Unless of coarse someone has a better idea on how to approach this. 
i would also like to note that this is just a part of a larger project. If you need to see the entire project, please let me know and i will provide a link where you can download it.

The string i'm expecting as a response would be similar to this:

&lt;Alarm,MPos:0.000,0.000,0.000,WPos:0.000,0.000,0.000&gt;


Here is the code i have so far:

float mx;
float my;
float mz;
float wx;
float wy;
float wz;
String dAlarm;
char buffer;
void gPos() {
  Serial1.print("?\n");
  buffer = Serial1.read();
  char string[80];
  string[buffer];
  char *alarm = strtok(string, ",");
  char *mposX = strtok(NULL, ",");
  char *mposY = strtok(NULL, ",");
  char *mposZ = strtok(NULL, ",");
  char *wposX = strtok(NULL, ",");
  char *wposY = strtok(NULL, ",");
  char *wposZ = strtok(NULL, "&gt;");
  alarm += 1;
  mposX += 5;
  wposX += 5;
  mx = strtod(mposX, NULL);
  my = strtod(mposY, NULL);
  mz = strtod(mposZ, NULL);
  wx = strtod(wposX, NULL);
  wy = strtod(wposY, NULL);
  wz = strtod(wposZ, NULL);

  if (strcmp(alarm, "Idle") == 0) {
    dAlarm = "Idle";
  } else if (strcmp(alarm, "Run") == 0) {
    // Something to do when Busy
    dAlarm = "Run";
  } else if (strcmp(alarm, "Hold") == 0) {
    // Something to do when Busy
    dAlarm = "Hold";
  } else if (strcmp(alarm, "Door") == 0) {
    // Something to do when Busy
    dAlarm = "Door";
  } else if (strcmp(alarm, "Home") == 0) {
    // Something to do when Busy
    dAlarm = "Home";
  } else if (strcmp(alarm, "Alarm") == 0) {
    // Something to do when Busy
    dAlarm = "ALARM!";
  } else if (strcmp(alarm, "Check") == 0) {
    // Something to do when Busy
    dAlarm = "Check";
  }
  dispPos();
}

void dispPos() {
  int state = 0;
  int x = analogRead (0);
  if (x &lt; 800) {
    state = 1;
  }
  if (state == 1) {
    dPos = false;
  }

  if (dPos == true) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("X");
    lcd.print(mx);
    lcd.setCursor(8, 0);
    lcd.print("Y");
    lcd.print(my);
    lcd.setCursor(0, 1);
    lcd.print("Z");
    lcd.print(mz);
    lcd.setCursor(8, 1);
    //lcd.print(" ");
    lcd.print(dAlarm);
    delay(3000);
  } else {
    mainMenu();
  }
}
What you need to do here is implement a small finite state machine.

Basically you need to look at each character as it comes in and make a decision what to do with it depending on what state you're in at the moment.

Basically the operational decisions you need to make are:


Is the character a &lt; and am I currently not reading a string?


Yes, start reading the string.

Is the character a > and am I currently reading a string?


Yes, finish reading the string and process it

Is it any other character and I am currently reading the string?


Yes, add it to the buffer.



So you can see there some common questions:


What is the character?
What am I doing at the moment?


So you need to have a simple state variable that remembers if you're reading the string or not, and something to say where in the buffer you are so you know where in the buffer to add any incoming characters.

boolean readingString = false;


A simple true/false will suffice to depict if we're reading the string or not.  Start off not reading the string.

char buffer[80] = "";


A buffer to store the text - maximum of 80 characters (including the NULL terminating character)

int charPointer = 0;


Something to know where in the buffer are currently.

Now to read the characters:

First get the next character from the serial port:

loop() {
    if (Serial.available()) {
        int incoming = Serial.read();


Now decide what to do with it.  We have a number of possible situations, some of which can be combined into single options.  For instance, if we get a "&lt;" while reading a string it's an error condition - but do we really care?  It could be that we lost the end of the last string and have just started a fresh one - so we can just treat it as the start of a string regardless of what state we're in.  Let's use a switch for this since it's nice and tidy:

        switch (incoming) {
            case '&lt;':
                readingString = true; // Start reading string
                charPointer = 0; // Set the buffer pointer to the start
                buffer[0] = 0; // Make the string empty
                break;

            case '&gt;':
                if (readingString) {
                    processBufferData(); // Do something with the buffer
                }
                readingString = false; // Finish reading
                break;

            default: // Anything that's not &gt; or &lt;
                // If we are reading the string and the buffer isn't full
                if (readingString &amp;&amp; charPointer &lt; 78) {
                    // Add the character to the buffer and increment the pointer
                    buffer[charPointer++] = incoming;
                    buffer[charPointer] = 0; // Don't forget to terminate the string
                }
        }
    }
}


So the reception of a &lt; starts the string reading, the reception of a > stops it and triggers the processing of the string, and anything else (while we are reading the string) gets added to the buffer.