Bluetooth Serial, zweistellige Variable

Bin am verzweifeln

Ich auch.

EDIT: Na gut, verrätst Du uns auch, woran du so sehr verzweifelst? Dann lässt sich besser helfen :)

Von welchem Typ wäre denn die 2stellige Variable?

So lange die Eingaben sammeln, bis ein Zeilenumbruch kommt, dann zusammenfügen.

TriB: Von welchem Typ wäre denn die 2stellige Variable? So lange die Eingaben sammeln, bis ein Zeilenumbruch kommt, dann zusammenfügen.

Ich versteh Deine Aufgabenstellung vielleicht falsch, was gut geht und flexibel ist: char sammeln. https://de.wikibooks.org/wiki/C%2B%2B-Programmierung/_Weitere_Grundelemente/_Zeichenketten

Die Zeichen sammeln ist so oder so nötig. Char macht mutmaßlich am meisten Sinn!

Die Frage, die sich mir stellt ist wie es dann weiter geht. Handelt es sich um eine zweistellige Ganzzahl 0-99 oder um Binär, Hexadezimal, etc.. Gibt es Trenn- oder Zeilenendzeichen?

Ohne den Infos und/oder dem Wissen woran es akut beim TE scheitert, können wir eh nur raten.

Danke für die konstruktiven Antworten. Dürfte ich meinen Sketch bitte hier einkopieren, er ist auch kurz. Knackpunkt ist meines Erachtens die Zeile "value = SerialBT.read();"

/* App: Über App Inventor programmiert, verbindet sich per Bluetooth mit ESP32 und übergibt Variable OLED: 128x64 WxH Monochrome, korrekt verbunden mit ESP 32, SSD1306 Treiber am I2C Port. */

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

BluetoothSerial SerialBT;

include

include

include "SSD1306Ascii.h"

include "SSD1306AsciiWire.h"

define I2C_ADDRESS 0x3C

SSD1306AsciiWire oled;

include

include

define SCREEN_WIDTH 128 // OLED display width, in pixels

define SCREEN_HEIGHT 64 // OLED display height, in pixels

define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

define LOGO_HEIGHT 16

define LOGO_WIDTH 16

int value = 0; //Deklaration Variable

void setup() { Serial.begin(9600); SerialBT.begin("Ich bin ein ESP32 mit Bluetooth"); //Bluetooth device name if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Addresse des OLED Displays Serial.println(F("SSD1306 allocation failed")); for(;;); }

display.display(); // Show initial display buffer content on screen or Adafruit splash screen delay(2000); // Pause Wire.begin(); Wire.setClock(400000L); oled.begin(&Adafruit128x64, I2C_ADDRESS); }

void loop() { if (Serial.available()) { SerialBT.write(Serial.read()); } if (SerialBT.available()) { value = SerialBT.read(); Serial.write(value); oled.setFont(fixed_bold10x15); // Auswahl der Schriftart auf dem OLED oled.clear(); //Löschen der aktuellen Displayanzeige oled.print(value-48); // Umrechnung serieller Wert in Ausgabewert delay(20); }}

define XPOS 0 // Indexes into the 'icons' array in function below

define YPOS 1

define DELTAY 2

markusweih: Danke für die konstruktiven Antworten. Dürfte ich meinen Sketch bitte hier einkopieren, er ist auch kurz.

Was sind denn Antworten die nicht konstruktiv sind? - ok. ich stelle die Frage hinten an.

Der darf gerne auch lang sein, aber grundsätzlich sollten die Codetags Also das -Symbol verwendet werden, um möglichst allen Lesern auf den unterschiedlichsten Geräten Zugang zu verschaffen - und das ebenso lesbar zu machen.

Knackpunkt ist meines Erachtens die Zeile "value = SerialBT.read();"

Der Knackpunkt dürfte eher sein, das Du versuchst irgendwas aus irgendwelchen Quellen zusammen zu kopieren und das Konstrukt dann nicht die erwartete Lösung bringt. Das kann am Verständnis liegen, oder am Unwillen, oder sonst was. Erklär es.

/* 
App: Über App Inventor programmiert, verbindet sich per Bluetooth mit ESP32 und übergibt Variable
OLED: 128x64 WxH Monochrome, korrekt verbunden mit ESP 32, SSD1306 Treiber am I2C Port.
*/

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

BluetoothSerial SerialBT;

include

include

include "SSD1306Ascii.h"  

include "SSD1306AsciiWire.h"

define I2C_ADDRESS 0x3C

SSD1306AsciiWire oled;

include

include

define SCREEN_WIDTH 128 // OLED display width, in pixels

define SCREEN_HEIGHT 64 // OLED display height, in pixels

define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

define LOGO_HEIGHT   16

define LOGO_WIDTH    16

int value = 0; //Deklaration Variable

void setup() {  Serial.begin(9600);    SerialBT.begin("Ich bin ein ESP32 mit Bluetooth"); //Bluetooth device name  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Addresse des OLED Displays    Serial.println(F("SSD1306 allocation failed"));    for(;;);  }

 display.display(); // Show initial display buffer content on screen or Adafruit splash screen  delay(2000); // Pause  Wire.begin();  Wire.setClock(400000L);  oled.begin(&Adafruit128x64, I2C_ADDRESS); }

void loop() {  if (Serial.available()) {    SerialBT.write(Serial.read());  }  if (SerialBT.available()) {    value = SerialBT.read();    Serial.write(value);    oled.setFont(fixed_bold10x15); // Auswahl der Schriftart auf dem OLED    oled.clear(); //Löschen der aktuellen Displayanzeige    oled.print(value-48); // Umrechnung serieller Wert in Ausgabewert  delay(20);  }}

define XPOS   0 // Indexes into the 'icons' array in function below

define YPOS   1

define DELTAY 2

Nachdem du deinen Sketch lesbar in Code-Tags gesetzt hast, darfst du auch gern beschreiben, was der Sketch machen soll und was dieser dann nicht macht. Oder was er für Fehler zeigt.

Dann fällt uns evtl. eine Fehlersuche leichter.

Du liest ein Zeichen aus. Allerdings möchtest Du zwei Zeichen auslesen.

Dementsprechend benötigst Du z.B. ein charArray[] in welches Du die Eingaben (temporär) überträgst. Im nächsten Schritt baut man daraus dann wieder eine Ganzzahl zusammen.

Da kann man eine schöne while(SerialBT.available())-Schleife verwenden, die so lange Dein Puffer-Array füllt, bis:

  • Der Puffer voll ist
  • Die Daten komplett sind

Dann hast Du die gepufferten chars, welche die Zahl des Zeichens repräsentieren, umrechnen. Ein Trick ist es, einfach das Zeichen für die 0abzuziehen, damit man auf den echten Wert kommt.

Also, kommt eine 25 rein, pufferst Du die Werte 50 (Dezimalwert für die 2) & 53 (Dezimalwert für die 5). 50 - 48 (Dezimalwert für die 0) = 2 53 - 48 = 5

Zusammenbauen, fertig!

Ein Programm zum Testen, da ich die App nicht habe, mit dem seriellen Monitor:

// getestet mit ESP32
#include 
#include 
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("\nStart");
  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Addresse des OLED Displays
    Serial.println(F("SSD1306 allocation failed"));
    for (;;);
  }
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.print("Zwei Zahlen eingeben!");
  display.display(); // Show initial display buffer content on screen or Adafruit splash screen
  delay(1000);
}

void loop() {
  if (Serial.available()) {
    char zeichen[3];
    zeichen[0] = Serial.read();
    zeichen[1] = Serial.read();
    zeichen[2] = '\0';
    Serial.println(zeichen);
    display.clearDisplay();
    display.setCursor(0, 0);
    display.print("Zeichen: ");
    display.print(zeichen[0]);
    display.print(zeichen[1]);
    display.display();
  }
}

EDIT: Entsprechend #10 geändert, denn '\0' muß man Platz einräumen! Danke!

Der Code ist fehleranfällig. 1. Es ist nicht sicher, dass zeichen mit '\0' abgeschlossen ist (lokale Variable), also besser

    char zeichen[3];  // <---- + Platz für '\0'
    zeichen[0] = Serial.read();
    zeichen[1] = Serial.read();
    zeichen[2] = '\0';
    Serial.println(zeichen);
  1. Es ist nicht sicher, dass beide Zeichen im Realfall schon da sind (beim Seriellen Monitor als Quelle geht das)

Gruß Tommy

Dass man nicht zweimal direkt hintereinander read() machen kann solltest du eigentlich wissen. Die serielle Übertragung ist auch bei hohen Baudraten immer langsamer als der Controller. Genau deswegen verwendet man ja normalerweise Endzeichen

Sauber:

const unsigned int READ_BUFFER_SIZE = 3;

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

void loop()
{
  char* str = readLine(Serial);  //liefert einen Zeiger ungleich 0 wenn das LF eingelesen wurde
  if (str != nullptr) 
  {
    Serial.print("Eingelesen: "); Serial.println(str);

    byte nr = atoi(str);
    Serial.print("Konvertiert: "); Serial.println(nr);
}

char* readLine(Stream& stream)
{
  static byte index;
  static char buffer[READ_BUFFER_SIZE];

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

    if (c == '\n')              //wenn LF eingelesen
    {
      buffer[index] = '\0';     //String terminieren
      index = 0;
      return buffer;            //melden dass String fertig eingelesen wurde
    }
    else if (c >= 32 && index < READ_BUFFER_SIZE - 1)   //solange noch Platz im Puffer ist
    {
      buffer[index++] = c;    //Zeichen abspeichern und Index inkrementieren
    }
  }
  return nullptr;               //noch nicht fertig
}

Und am Ende ein Linefeed als Abschluss schicken. Sonst geht es nicht

Als Alternative kann man die Ziffern direkt aufsummieren wenn sie reinkommen. Das ist bei so einfachen Sachen ganz praktisch. Aber auch da muss man irgendwie das Ende erkennen