Mehrstellige Zahlenwerte per Bluetooth über HC-05 übertragen auf ein Display

Hallo,
ich habe einen Arduino UNO. Er soll Zahlenwerte bis zu 4-Stelligen Zahlen übertragen können und diese dann auf einem transparenten Display ausgeben. Mein Problem ist es das er immer nur die erste Stelle der Zahl z.B. von 500, nur die 5 im seriellen Monitor ausgebt. Kann mir dort jemand helfen.
(Gerne ein hilfreiches Programm erstellen)

Liebe Grüße Pro Helmet

So ganz werde ich aus Deiner Beschreibung nicht schlau.
Meinst Du, dass der Arduino per BT die Zahl bekommt (woher) und diese dann auf einem Display (welches) darstellen soll?
Da das BT-Modul per SoftwareSerial angeschlossen sein sollte, kannst Du alle seriellen Einleseroutinen benutzen.

Zeige ins doch mal, was Du schon hast.

Gruß Tommy

Hallo Tommy, der Arduino bekommt die Zahlen vom Handy geschickt und soll diese dann auf dem transparenten Display von sparkfun ausgeben. Bis jetzt ist mein Programm noch nicht wirklich weit weshalb es dir leider nicht weiter helfen wird, ich hoffe dir helfen die Informationen weiter und du kannst mir helfen.

Liebe Grüße ProHelmet

Na irgendwas musst Du doch haben, wenn Du die erste Ziffer angezeigt bekommst.
Sendet das Handy ein Endezeichen mit oder woher willst Du wissen, wie lang die Zahl ist?

Ohne genauere Infos zu Deinem bisherigen Code und der Beantwortung der Fragen wird das höchstens ein Ratespiel und darauf hat hier keiner Lust.

Gruß Tommy

Du liest immer nur ein char ein.
Dazu müsste wenigstens die Einleseroutine vorliegen um den entsprechenden verantwortlichen Codeteil zu finden.

Ohne wird das nix.

Hallo Zusammen,
das Handy kann ein Zeichen vor und nach der Zahl senden.

     
#include "HyperDisplay_UG2856KLBAG01.h"   
//////////////////////////
//      User Setup      //
//////////////////////////
#define SERIAL_PORT Serial  
#define WIRE_PORT Wire      // Used if USE_SPI == 0
#define SPI_PORT SPI        // Used if USE_SPI == 1

#define RES_PIN 2           // Optional
#define CS_PIN 4            // Used only if USE_SPI == 1
#define DC_PIN 5            // Used only if USE_SPI == 1

#define USE_SPI 0           // Choose your interface. 0 = I2C, 1 = SPI

// END USER SETUP


// Object Declaration. A class exists for each interface option
#if USE_SPI
  UG2856KLBAG01_SPI myTOLED;  // Declare a SPI-based Transparent OLED object called myTOLED
#else
  UG2856KLBAG01_I2C myTOLED;  // Declare a I2C-based Transparent OLED object called myTOLED
#endif /* USE_SPI */




char Incoming_value = 0;                //Variable for storing Incoming_value

void setup() {
  Serial.begin(9600);         //Sets the data rate in bits per second (baud) for serial data transmission
  pinMode(18, OUTPUT);        
  Serial.begin(9600);
  Serial.println(F("Example4_Text: Transparent Graphical OLED"));

#if USE_SPI 
  SPI_PORT.begin();
  myTOLED.begin(CS_PIN, DC_PIN, SPI_PORT);                  // Begin for SPI requires that you provide the CS and DC pin numbers
#else
  WIRE_PORT.begin();
  myTOLED.begin(WIRE_PORT, false, SSD1309_ARD_UNUSED_PIN);  // Begin for I2C has default values for every argument
  Wire.setClock(400);
#endif /* USSE_SPI */
}

void loop() { 
    if(Serial.available() > 0)  
  {
    Incoming_value = Serial.read();     //Read the incoming data and store it into variable Incoming_value
    Serial.print(Incoming_value);       //Print Value of Incoming_value in Serial monitor
    Serial.println("");
             


  
   
   
    if(Incoming_value == '1')            //Checks whether value of Incoming_value is equal to 1 
    {
    //Serial.println("");
    delay(1000);
    char Incoming_meter = Serial.read();
    digitalWrite(18,HIGH);  //If value is 1 then LED turns ON
    myTOLED.windowClear();
    myTOLED.setTextCursor(30,30);
    myTOLED.print("   --->");
    
     

 // if(Incoming_meter > 10){
     
        myTOLED.setTextCursor(30,50);
        myTOLED.print(Incoming_meter);
        Serial.println("");
        myTOLED.print(" meter");
        
     
  Ich hoffe es hilft euch die Frage besser zu verstehen

Und die, die benutzt, hälst Du geheim. Die Fragen zu beantworten hast Du auch nicht nötig. Deine Mehrfachverwendung von Serial könnte ein Problem werden.

Gruß Tommy

Wie ist das BT-Modul da dran?
Am Serial-Port?
Auf dem soll auch der Serial-Monitor laufen?
Wenn Du beides verwenden willst, brauchst Du ein Software Serial.

Der Code sollte eigentlich funktionieren.
Beachte die richtige Konfiguration des BT-Moduls. Anschlüsse(!).

/*
  #include "HyperDisplay_UG2856KLBAG01.h"
  //////////////////////////
  //      User Setup      //
  //////////////////////////

  #define USE_SPI 0           // Choose your interface. 0 = I2C, 1 = SPI
  #define WIRE_PORT Wire      // Used if USE_SPI == 0
  #define RES_PIN 2           // Optional
  UG2856KLBAG01_I2C myTOLED;  // Declare a I2C-based Transparent OLED object called myTOLED

  // END USER SETUP
*/

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

char Incoming_value;                //Variable for storing Incoming_value
char charArray[15] = {'\0'};
uint8_t index = 0;

void setup()
{
  Serial.begin(9600);         //Sets the data rate in bits per second (baud) for serial data transmission
  mySerial.begin(9600);
  pinMode(18, OUTPUT);
  Serial.println(F("Example4_Text: Transparent Graphical OLED"));
  /*
    WIRE_PORT.begin();
    myTOLED.begin(WIRE_PORT, false, SSD1309_ARD_UNUSED_PIN);  // Begin for I2C has default values for every argument
    Wire.setClock(400);
  */
  setBlankArray();
}

void setBlankArray()
{
  memset(charArray, '\0', sizeof(charArray));
  index = 0;
}

void ausgabe()
{
  Serial.print(charArray);
  setBlankArray();
}

void loop()
{
  if (mySerial.available() > 0)
  {
    Incoming_value = mySerial.read();     //Read the incoming data and store it into variable Incoming_value
    Serial.print(Incoming_value, HEX);       //Print Value of Incoming_value in Serial monitor
    Serial.print(", ");
    if (!isControl(Incoming_value))
    {
      charArray[index] = Incoming_value;
      index++;
    }
    else
    {
      Serial.println();
      ausgabe();
    }
  }
  if (index == 14)
  {
    Serial.println(F("KEIN ENDEZEICHEN ERKANNT"));
    Serial.print(charArray);
    setBlankArray();
  }
}

Der Wert der gesendet wird muss mindest ein LF oder ein CR haben.

Lieber Tommy,
leider bin ich ein absoluter Anfänger im Programmieren, weshalb ich auch hier unterwegs bin.
Deshalb bedanke ich mich auch sehr bei dir sowie den anderen für die Hilfe.

Vielen Dank,
ich werde das Programm morgen einmal testen und mich dann noch einmal melden.
Liebe Grüße
ProHelmet

Auch Anfänger sollten die Fragen beantworten, wenn sie Hilfe wollen. Wir können nicht Hellsehen.

Gruß Tommy

Natürlich, welche Frage bzw. Fragen habe ich denn vergessen zu beantworten?

Liebe Grüße

z.B. Welches Zeichen davor und danach Du sendest.

Gruß Tommy

Ich benutze Sonderzeichen aber weiß nicht genau wie ich diese richtig Im Programm einbinden muss, # und *

Als '*' und '#'.
Du liest also ein, bis Du ein '#' findest(Anfang). Danach schreibst Du alles in einen Puffer, bis Du '*' findest (Ende) da schreibst Du '\0' in den Puffer, um die Zeichenkette abzuschließen. Dann wandelst Du diese mit atoi in eine Zahl um.
Kommen nur positive Zahlen?

Gruß Tommy

Ja es sind nur positive Zahlen, maximal Vierstellige.

Liebe Grüße

Ungetestet (nur mal runter geschrieben) als Denkanstoß:

// Einlesen eines nicht negativen Integers mit 4 Stellen von einem Stream
// &s Reference auf einen Stream - Serial, SoftwareSerial, ...
// Return: -1 noch nicht fertig, >= 0 gelesene Zahl
int lese(Stream &s) {
  static idx = 0;
  static bool imLesen = false;
  static char puffer[5];
  if (s.available()) {
    char c = s.read();
    if (!imLesen && c == '#') {  / Anfang gefunden
      imLesen = true;
      idx = 0;
      return -1;
    }
    if (imLesen) {
      if (c=='*') { // Ende gefunden
        puffer[idx] = '\0';
        imLesen = false;
        return atoi(puffer);
      }
      else {  // gültiges Zeichen
        puffer[idx++] = c;
        return -1;
      }
    }
  }
}

// Anwendung im loop:
int zahl = lese(Serial);
if (zahl >= 0) {
  Serial.println(zahl);
}

Gruß Tommy

Ich hab mal Deinen Gedankengang aufgenommen und mir selbst eine Aufgabe gestellt, die da lautet: ich will das ohne static-Variablen, um mehrere Streams wechselseitig einzulesen. Dabei abgefallen ist dann auch noch die negative..

Ich konnts noch nicht probieren - aber es kompiliert...

// Forensketch Stream einlesen ohne static Vars 
// angestachelt durch https://forum.arduino.cc/t/mehrstellige-zahlenwerte-per-bluetooth-uber-hc-05-ubertragen-auf-ein-display/1054326/18
// ungetestet

#include <Streaming.h>     // https://github.com/janelia-arduino/Streaming
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11);
constexpr char StartZeichen = '#';
constexpr char EndZeichen = '*';

char zeile[15] = {'\0'};
int32_t zahl;

void setup()
{
  Serial.begin(115200);
  mySerial.begin(9600);
  Serial << (F("\r\nStart...\r\n")) << endl;
}

void loop()
{
  myRead(mySerial, zeile, sizeof(zeile));
}


void myRead(Stream &s, char *buf, uint8_t bufLen)
{
  byte index = 0;                                        // Positionszähler
  int zeichen = s.read();                                //
  if  (zeichen  == -1)                                   // Kein Zeichen?
  { return; }
  for (byte b = 0; b < sizeof(zeile); b++)               // durchlaufe buffer und suche
  {
    if (buf[b] == '\0' )                                 // erstes Vorkommen
    { break; }                                           // wenn gefunden Abbruch Schleife
    else
    { index = b; }                                       // wenn nicht gefunden, wird der index gesetzt
  }
  if (isControl(zeichen) || index >= bufLen - 1)
  { zeichen = EndZeichen; }
  switch (zeichen)
  {
    case StartZeichen:
      memset(buf, '\0', bufLen);                         // buffer leeren;
      buf[0] = StartZeichen;                             // erstes Zeichen setzen als Merker
      break;
    case '+':
    case '-':
      if (buf[0] == StartZeichen)                        // wenn Merker gesetzt
      { buf[0] = zeichen; }                              // ersetzen mit aktuellem
      else                                               // sonst
      { memset(buf, '\0', bufLen); }                     // buffer leeren
      break;
    case '0' ... '9':
      if (zeile[0] == StartZeichen)                      // Wenn Merker gesetzt
      { zeile[0] = zeichen; }                            // wird erstes Zeichen ersetzt
      else                                               // sonst
      { buf[index + 1] = zeichen; }                      // setze nächstes Element
      break;
    case EndZeichen:                                     // Ende der Kette
      if (buf[0] != '\0' && buf[0] != StartZeichen)      // Wenn irgendwas im buffer ist
      {
        zahl = atoi(buf);                                // umrechnen
        Serial << "Konvertierte Zahl: " << zahl << endl; // ausgeben
      }
      memset(buf, '\0', bufLen);                         // buffer leeren
      break;
  }
}

Vielleicht probierts mal jemand aus.

PS: Was mich wundert, das der Compiler beim case '-': / case '+' nicht fall trough meckert

Naja, static oder global ist halt eine Glaubensfrage.
Bei jedem Zeichen in einer Schleife das Ende der Zeichenkette zu suchen, nur um die Indexvariable weg zu lassen halte ich für Verschwendung von Rechenzeit.

Gruß Tommy

Ich auch, aber mich hat die Herausforderung gereitzt :wink:
Vielleicht bietet ja jemand eine elegantere Lösung. Ansonsten bliebe nur die Verarbeitung mit einer zusätzlichen Referenz auf eine Indexvariable passend zum buffer.