Arduino ASCII Problem und Serial Problem

Guten Abend,

ich sende mithilfe einer Android App über Bluetooth zu meinem Arduino Uno Zahlen. Ich besitze das Bluetooth-Modul HC-06. Meine App sendet unterschiedliche Zahlen. Die Zahlen hängen mit dem Accelerometer zusammen. In einem String sind immer zwei Zahlen. Doch der Arduino empfängt nur die Zahlen in ASCII. Wie kann ich die Zahlen wieder umkonvertieren? Die Zahlen werden über Serial ausgelesen. Ich möchte je nach dem, was für eine Zahl empfangen wird, den Servo nach links oder rechts bewegen, oder den Motor schneller oder langsamer drehen lassen. Die erste Zahl ist für den Servo zuständig und die zweite Zahl aus dem String für den Motor. Meine Frage sind:

  1. Wie kann ich die Zahlen von ASCII in dezimal umwandeln?
  2. Wie kann ich die beiden Zahlen aus dem String, die aus Serial ausgelesen werden, in getrennte Integer Variablen schreiben? Möchte dann per switch-case den Motor und den Servo über die beiden Variablen steuern.

Gruß, quai

Am einfachsten ist man trennt das per Komma ab und markiert das Ende mit einem CR oder LF. Dann kann man es ganz einfach mit strtok() und atoi() Parsen.

Also sowas schicken:
“123,456\n”

Code:

const int SERIAL_BUFFER_SIZE = 16;
char serial_buffer[SERIAL_BUFFER_SIZE];

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

void loop()
{
  if (read_serial())
  {
    parse_serial();
  }
}

bool read_serial()
{
  static byte index;

  while (Serial.available())
  {
    char c = Serial.read();

    if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
    {
      serial_buffer[index++] = c;
    }
    else if (c == '\r' || c == '\n')
    {
      serial_buffer[index] = '\0';
      index = 0;
      return true;
    }
  }

  return false;
}

void parse_serial()
{
  int value1 = atoi(strtok(serial_buffer, ","));
  int value2 = atoi(strtok(NULL, ","));

  .....
}

strtok() kann man auch schön in einer while Schleife ablaufen lassen wenn die Anzahl der Werte unbekannt ist und die Werte in ein Array schreiben (dabei aufpassen ob der Index gültig ist!)

Danke für den Tipp. Werde ich morgen direkt ausprobieren. Wie konvertierte man die empfangenen Zahlen von ASCII in Dezimal?. Das mit den ASCII- Zahlen, ist ja jetzt kein richtiges Problem. Ob ich jetzt nach einer Zahl schaue oder zwei Zahlen, macht gar keinen Unterschied.

Ich wünsche dir noch einen schönen Abend.

Falls morgen Fragen auftreten, melde ich mich nochmal :)

Gruß, quai

Siehe die parse_serial() Funktion. atoi steht für "array to integer": http://www.cplusplus.com/reference/cstdlib/atoi/ Wandelt einen C String in einen int. Da gibt es auch noch andere Konvertierungsfunktionen für long, oder eine die auch Hex oder Binär-Strings wandeln kann.

Allgemein hilft vielleicht mal ein Blick in die ASCII Tabelle. Um eine einzelne ASCII Ziffer (d.h. ein char zwischen '0' und '9') in eine Dezimal Ziffer zu wandeln muss man nur - '0' machen (oder - 48). Da '0' den ASCII Code 48 hat. Das kann man auch Ausnutzen um die Ziffern "on the fly" aufzuaddieren. Also immer die schon gespeicherte Zahl mit 10 Multiplizieren und dann die aktuelle Ziffer addieren.

Aber generell ist es flexibler wenn man erst mal den ganzen String einliest und erst am Ende auswertet. Dann ist man nicht auf Zahlen festgelegt, sondern kann auch Text-Kommandos einlesen. Oder eine Kombination aus Text und Zahlen.

Serenifly: ..generell ist es flexibler wenn man erst mal den ganzen String einliest und erst am Ende auswertet.

Du meinst z.B. indem zunächst auf CR und/oder LF abgefragt wird? Oder meinst Du eine Abfrage der Nullterminierung?

Gruß Chris

CR/LF. Der Terminator wird nicht gesendet.