Serielle Datenübernahme -> digit. Stromzähler

Hallo zusammen,
ich trau mich kaum, weil mein Problem so trivial daher kommt.
Von meinem Stromzähler kommen laufend serielle Daten über Softwareserial in einen NANO. Ich möchte einen Datenstromausschnitt von ca. 1000 Zeichen in ein Char-Array einlesen und dieses Array anschliessend -nach Datenübernahme- auswerten.
Soweit:

#include <SoftwareSerial.h>
SoftwareSerial zaehler(2,3);  // RX , TX
void setup() 
{
  Serial.begin(9600);
  zaehler.begin(9600);  // IR-Lesekopf
  
      lesen();
}

void lesen()
{
int pos=0;
char buffer[1010];    // soll den Datenstrom aufnehmen

Serial.println("einlesen");
while (pos <= 1000)     //einlesen
{ buffer[pos]= zaehler.read();

  Serial.print(buffer[pos],HEX);  // zur Kontrolle... geht! -----> 1)

  pos++;
}
Serial.println("prüfen");
for (int pos=0; pos<=1000; pos++)
{
Serial.print(buffer[pos],HEX);} // identischer Inhalt   --> 2)
}
void loop(){  }   // brauch ich im Monent nicht

Mein Problem:
Die serielle Monitorausgabe zeigt identische Daten.
Wenn ich im Einleseteil die serielle Ausgabe 1) weglasse, dann bekomm ich bei der Prüfung 2) keine Werte angezeigt.
Das selbe passiert, wenn ich in beiden Fällen nur die HEX Formatierung weglasse.

Ich kann mit dem gefüllten(?) Char Array nicht weiter arbeiten!
Wo ist mein Denkfehler?

Grüssle
Peter

Du liest, ohne zu testen, ob ein Zeichen vorhanden ist.

Ergänze mal Serial.available(), wird es besser?

Es kommen pausenlos Daten über Zaehler.read() an. Die kann ich ja über "Serial.read()" am Monitor ausgeben lassen. .......(??)

Ja- hab ich versucht- ohne Effekt. Die Daten kommenja in den buffer[], aber ich komm nicht mehr an die ran!

1 Like

Nein.

Da kommen maximal 1000 Zeichen in der Sekunde, das ist keineswegs immer.

Wenn du dein Einlesen jetzt z.B. mit Ausgaben langsamer machst,
könnte es sein, dass du immer Zeichen siehst, wenn du sie erwartest.

Und ohne den Kode zu zeigen,
weiß also der Geier, wo und wie du Serial.available() verwandt hast.

Das wird nix.
zaehler.read() gibt dir -1 zurück, wenn sich kein Zeichen im seriellen Puffer befindet.

Versuch mal:

#include <SoftwareSerial.h>
int pos = 0;
char buffer[1010];    // soll den Datenstrom aufnehmen
SoftwareSerial zaehler(2, 3); // RX , TX
void setup()
{
  Serial.begin(9600);
  zaehler.begin(9600);  // IR-Lesekopf
}

void lesen()
{
  if (pos == 0)
  {
    Serial.println(F("Starte einlesen"));
  }
  if (pos < 1000)     //einlesen
  {
    int8_t myChar = zaehler.read();
    if (isAscii(myChar))
    { buffer[pos] = myChar; }
    Serial.print(buffer[pos], HEX); // zur Kontrolle... geht! -----> 1)
    pos++;
  }
  else
  {
    Serial.println();
    Serial.println("prüfen");
    for (uint16_t pos = 0; pos < 1000; pos++)
    {
      Serial.print(buffer[pos], HEX);
    } // identischer Inhalt   --> 2)
    pos = 0;
    memset(buffer, '\0', sizeof(buffer));
  }
}
void loop() {
  lesen();
  }  // brauch ich im Monent nicht

OOOOkey!
Wie umgeh ich das? delay() in der Einleseschleife?

Danke my_xy_projekt.
Probier ich......

Nein.

Ich würde die Einlese-Schleife beseitigen und loop() frei laufen lassen.
Wenn eingelesen werden soll, werden Zeichen in den Puffer übernommen, wenn welche da sind.
Wenn der Puffer voll ist, kann man ihn verarbeiten.

Hinweis: Ich würde das erstmal nur auf 30 zeichen begrenzen.
Erst wenn da die Übernahme mit der Ausgabe stimmt weiter machen.

Angeblich dauern die 1000 Zeichen ja nur eine Sekunde.

Noch weniger.

#include <SoftwareSerial.h>
uint16_t pos = 0;

SoftwareSerial zaehler(2, 3); // RX , TX
void setup()
{
  Serial.begin(9600);
  Serial.println(F("Start.... "));
  zaehler.begin(9600);  // IR-Lesekopf
  Serial.println(millis());
  while (pos < 1000)
  {
    zaehler.read();
    pos++;
  }
  Serial.println(millis());
}

void loop() {  }  // brauch ich im Monent nicht
Start.... 
21:18:44.755 -> 0
21:18:44.755 -> 2

also das ist schon mutig.

Dein Nano hat gerade mal 2K SRAM ... und du willst die Hälfte mit deinem Char array belegen.
Welche Daten interessieren dich wirklich?
Parse die Daten schon beim einlesen - und halte nur jene im Speicher die du wirklich brauchst.
Irgendwas willst ja vermutlich dann auch noch machen, irgendwo darstellen oder ausgeben. Das wird alles zusätzlichen Speicher brauchen ...

Und warum sollte man das Problem jetzt zuerst mit 30 Zeichen lösen?

Wegen dem Seriellen Monitor.
Derzeit beschreibt er eine Zeile. Und ich hab das genau so übernommen.
Und nur noch einen zusätzlichen Serial.println() eingefügt, damit er wenigstens das "prüfen" auf einer neuen zeile sieht.

Diese Annahme ist ein Irrtum.

Daher könnte in Deinem Programm ein Fehler stecken, denn bei mir funktioniert available().

Hi noiasca,
Speicher spielt keine Rolle. Der Nano soll die Daten einlesen, und eine Info daraus (Zählerstand) wegschreiben. Natürlich geht das eleganter- ich bin am Thema dran.
Danke.

Danke für eure hifreichen Antworten. Das WE ist zum Ausprobieren reserviert :sweat_smile:........
Melde mich asapst zurück.

Hab ich in einer der zahlreichen Vorversuchen ausprobiert.....
Wahrscheinlich stimmt mein ganzer Denkansatz zum Thema nicht.
Bin weiter dran und melde mich asapst.