[arduino] Convert serial.read() into a useable string using Arduino?

The best and most intuitive way is to use serialEvent() callback Arduino defines along with loop() and setup().

I've built a small library a while back that handles message reception, but never had time to opensource it. This library receives \n terminated lines that represent a command and arbitrary payload, space-separated. You can tweak it to use your own protocol easily.

First of all, a library, SerialReciever.h:

#ifndef __SERIAL_RECEIVER_H__
#define __SERIAL_RECEIVER_H__
    
class IncomingCommand {
  private:
    static boolean hasPayload;
  public:
    static String command;
    static String payload;
    static boolean isReady;
    static void reset() {
      isReady = false;
      hasPayload = false;
      command = "";
      payload = "";
    }
    static boolean append(char c) {
      if (c == '\n') {
        isReady = true;
        return true;
      }
      if (c == ' ' && !hasPayload) {
        hasPayload = true;
        return false;
      }
      if (hasPayload)
        payload += c;
      else
        command += c;
      return false;
    }
};
    
boolean IncomingCommand::isReady = false;
boolean IncomingCommand::hasPayload = false;
String IncomingCommand::command = false;
String IncomingCommand::payload = false;
    
#endif // #ifndef __SERIAL_RECEIVER_H__

To use it, in your project do this:

#include <SerialReceiver.h>
    
void setup() {
  Serial.begin(115200);
  IncomingCommand::reset();
}
    
void serialEvent() {
  while (Serial.available()) {
    char inChar = (char)Serial.read();
    if (IncomingCommand::append(inChar))
      return;
  }
}

To use the received commands:

void loop() {
  if (!IncomingCommand::isReady) {
    delay(10);
    return;
  }
executeCommand(IncomingCommand::command, IncomingCommand::payload); // I use registry pattern to handle commands, but you are free to do whatever suits your project better.
    
IncomingCommand::reset();