[Solved] Seriell empfangenen Text als Integer weiterverarbeiten

Hallo liebes Forum,

ich stecke gerade bei einem ganz grundsätzlichen Problem fest und ich hoffe, dass mir hier jemand helfen kann.
Ich baue zur Zeit einen Sensorprüfstand, mit dem Näherungssensoren auf ihre Genauigkeit geprüft werden können. Der Sensor befindet sich dabei auf dem Schlitten eines Linearantriebs, der über einen Steppermotor angetrieben wird.
Gesteuert wird das ganze über eine App, die Steuerungsbefehle via Bluetooth an einen ESP32 sendet, der den Antrieb entsprechend steuert und die Sensorwerte ausliest.

Jetzt zu meinem Problem:
Ein bestimmter Steuerbefehl ist dafür zuständig, dass der Linearantrieb einen zuvor in der App eingegebenen Festpunkt anfährt. Dieser Wert wird dann seriell als Text über Bluetooth übertragen. Das funktioniert auch reibungslos, allerdings muss der Wert noch umgerechnet werden, um mit ihm dem Stepper seine Schrittanzahl vorzugeben.
Und da ist das Problem. Die Werte werden, wie üblich im Seriellbetrieb schätze ich, als einzelne Ziffern übertragen:
Aus "120" wird beispielsweise "1""2""0". Die Rechenoperation die ich benötige ist "Wert/10". Folglich kommt als Ergebnis nur Kauderwelsch raus.
Meine Frage ist jetzt, ob es einen Weg gibt, diese Ziffern zu einem Integer, bzw. besser noch long int oder float zusammenzufügen? Oder gibt es andere Wege der Bluetooth-Kommunikation, die nicht auf der seriellen Datenübertragung beruhen?
Ich bin für jede Hilfe dankbar.

Der Code beinhaltet nur die, so denke ich zumindest, relevanten Stellen, da alles Andere funktioniert.
Falls der gesamte Code gewünscht ist, liefer ich den gerne nach.

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

String command = "";
char incomingChar;
long incomingtxt

void setup() {
  Serial.begin(115200);
  SerialBT.begin("Sensormessung");


void loop() {

if (SerialBT.available()) {
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n') {
      command = String(incomingChar);
    }
  }

  while (command == "9") {
    if (SerialBT.available()) {
      long incomingtxt = SerialBT.read();
      Serial.write(incomingtxt);
    }
  }
}

Falls ich etwas vergessen haben sollte, einfach fragen
Schon einmal vielen Dank im Voraus.

Gruß

Duffman

Hallo
probiere das mal
alt

(command == "9")

neu

(command == '9')

Das ist leider nicht das Problem.
Ich fürchte aber auch, dass ich mich schlecht ausgedrückt habe.

Die "9" in (command=="9") wird von der App als Steuerbefehl geschickt, sobald das Textfeld für die Festpunktfahrt ausgewählt wird, um dem ESP mitzuteilen, dass der nächste empfangene Wert nicht als direkter Steuerbefehl zu verstehen ist, sondern als Wert, der noch umgerechnet werden muss. Die Umrechnungsformel habe ich noch nicht eingebracht, da die Umwandlung in ein Integer noch fehlt.

google zum Anfangen mal nach

atoi c++

duffmann:
... da die Umwandlung in ein Integer noch fehlt.

Quick'n'dirty aus meiner Linkliste: http://www.cplusplus.com/reference/cstdlib/atoi/

Gruß

Gregor

Leider habe ich mit atoI(), aus welchen Gründen auch immer, auch keinen Erfolg.

Ich habe zwischenzeitlich auch einmal eine Variante hier aus dem Forum von nickgammon ausprobiert, die mir sehr vielversprechend schien.
Leider habe ich keinen Wert am Seriellen Monitor ausgegeben bekommen. Irgendetwas werde ich da wohl übersehen haben.

Der Code sah in etwa so aus

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#define dirPin 33
#define stepPin 32
#define end_max 25
#define end_zero 26

BluetoothSerial SerialBT;
String command = "";
char incomingChar;
String stopstring = "";
long incomingLong;
long korrektur;
const char startDelimiter = '<';
const char endDelimiter = '>';

void setup() {
  Serial.begin(115200);
  SerialBT.begin("Sensormessung");
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  pinMode(end_max, INPUT_PULLUP);
  pinMode(end_zero, INPUT_PULLUP);
}

void processNumber(const long n) {
  Serial.println(n);
}

void processInput() {
  static long receivedNumber = 0;
  static boolean negative = false;

  long c = SerialBT.read();

  switch (c) {
    case endDelimiter:
      if (negative) {
        processNumber (- receivedNumber);
      }
      else {
        processNumber (receivedNumber);
      }

    case startDelimiter:
      receivedNumber = 0;
      negative = false;
      break;

    case '0' ... '9':
      receivedNumber * 10;
      receivedNumber += c - '0';
      break;

    case '-':
      negative = true;
      break;
  }
}

void loop() {
  if (SerialBT.available()) {
    char incomingChar = SerialBT.read();
    if (incomingChar != '\n') {
      command += String(incomingChar);
    }
  }
  if (command != "") {
    Serial.println(command);
  }

    if (command == "2") {
      digitalWrite(dirPin, HIGH);
      while ((command == "2") && (digitalRead(end_zero) == HIGH)) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(1000);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(1000);
        char incomingChar = SerialBT.read();
        stopstring = String(incomingChar);
        if (stopstring == "8") {
          break;
        }
      }
      Serial.flush();
      SerialBT.flush();
      command = "";
      stopstring = "";

    }
    if (command == "3") {
      digitalWrite(dirPin, LOW);
      while ((command == "3") && (digitalRead(end_max) == HIGH)) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(1000);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(1000);
        char incomingChar = SerialBT.read();
        stopstring = String(incomingChar);
        if (stopstring == "8") {
          break;
        }
      }
      Serial.flush();
      SerialBT.flush();
      command = "";
      stopstring = "";
    }
    if (command == "4") {
      digitalWrite(dirPin, LOW);
      while ((command == "4") && (digitalRead(end_max) == HIGH)) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(1000);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(1000);
        char incomingChar = SerialBT.read();
        stopstring = String(incomingChar);
        if (stopstring == "5") {
          break;
        }
      }
      Serial.flush();
      SerialBT.flush();
      command = "";
      stopstring = "";
    }
    if (command == "6") {
      digitalWrite(dirPin, HIGH);
      while ((command == "6") && (digitalRead(end_zero) == HIGH)) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(1000);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(1000);
        char incomingChar = SerialBT.read();
        stopstring = String(incomingChar);
        if (stopstring == "7") {
          break;
        }
      }
      Serial.flush();
      SerialBT.flush();
      command = "";
      stopstring = "";
    }
    if (command == "9") {
      while (command == "9") {
        if (Serial.available()) {
          processInput();

        }
      }
    }
    command = "";
  }

(es sind noch eine Menge Code-Häppchen enthalten, die für die fertige Version noch rausgelöscht/geändert werden müssen)

Falls irgendwer noch eine Idee hätte, wäre ich sehr dankbar dafür.

duffmann:
Leider habe ich mit atoI(), aus welchen Gründen auch immer, auch keinen Erfolg.

Angesichts der Tatsache, dass Fehler Fehlermeldungen erzeugen, die man lesen kann, ist das ein ziemlich peinlicher Satz.

atoi() funktioniert.

Gruß

Gregor

Bist du sicher, dass BTSerial so etwas wie "9<-12345>" empfängt?
Falls ja, könnte dein Problem sein, dass du zwischen dem Lesen der '9' und dem '<' nicht wartest. Aber das wäre eine Frage an "BluetoothSerial.h"

PS Ausserdem nebenbei:

String command;

... ist Mist, das zeigt deine Ansicht

Aus "120" wird beispielsweise "1""2""0".

String soll alles vereinfachen, macht es aber in Wirklichkeit komplizierter.
Wenn es geht ist es ok. Wenn es aber damit Probleme gibt, ist man ohne String-Objekte besser dran.

Da command nur 1 Zeichen enthält, ist dein Vergleich per operator==(String, const char*) sicher nichts, was du von Nick Gammon übernommen hast. Solltest du durch Beschäftigung mit dem Unterschied zwischen char, char*, und String (3 völlig unterschiedliche Sachen) in den Griff kriegen.

So, ich habe mich jetzt nochmal in aller Ruhe hingesetzt und es nochmal versucht.
Mit gestresstem Kopf hatte heute Mittag nichts mehr geklappt :confused:

Der einfache Lösungsweg mit atoi() funktioniert natürlich.

Ich wusste nur nicht, dass man den String zuvor in ein Array umwandeln muss.
Die Kommunikation haut jetzt hin.

Danke für den Tipp.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.