Ende der seriellen Übertragung zeitnah markieren

Hallo,
mit dieser Routine empfange ich verschiedene Sätze in unterschiedlicher
Anzahl. Jeder Satz ist mit CR terminiert.

bool readSerial(Stream& stream)
{

  static byte index;

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

    if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
    {
      serialBuffer[index++] = c;
    }
    
    else

      if ((c == '\n' || c == '\r') && index > 0)

      {
        serialBuffer[index] = '\0';
        index = 0;
        delay(1000); damit ich "sehe" was gesendet worden ist
        return true;
      }
  }
  return false;
}

Es werden Sätze in unterschiedlicher Anzahl empfangen. 3, 9, 5, je nach
dem. Unbestimmte Anzahl eben.

Wie bekomme ich es denn mit millis hin, das nach dem letzen Satz eine
LED, noch 5sec leuchtet?
Oder anders, letzter Satz empfangen- in den nächsten 5 Sekunden nichts
mehr empfangen, Licht an.
Gruß und Dank
Andreas

du musst dir eine variable z.b unsigned log last_receive mit millis setzen, wenn serial available wwarund dann einfach von millis abziehen. wenn das größer o. gleich 5s ist, die led einschalten. das delay bringt dir dabei schwierigkeiten.

btw: wenn serial available ist, dann soll die led vermutlich wieder aus gehen.

/**
 * Wie bekomme ich es denn mit millis hin, 
 * das nach dem letzen Satz eine
 * LED, noch 5sec leuchtet?
 * 
 * Dieses Beispiel erleuchtet die eingebaute LED
 * sobald serielle Daten eintreffen.
 * Die LED geht nach erhalt der letzten Daten, 
 * nach 5 Sekunden, aus.
 */


#include <Streaming.h>
#include <CombiePin.h>
#include <CombieTimer.h>


Combie::Pin::OutputPin<LED_BUILTIN> led;
Combie::Timer::FallingEdgeTimer toff(5000);// abfallende Flanke wird verzoegert

void setup() 
{
  Serial.begin(9600);
  Serial << "Start: "<< __FILE__ << endl;
  led.init();
}

void loop() 
{
  led = toff = Serial.available();
  Serial.read();
}

CombieLib.zip (68.6 KB)

combie:

 * Dieses Beispiel

...
led = toff = Serial.available();

zeigt, dass man in C++ frei programmieren kann, was der Operator
** ** =** **
bedeuten soll.

Sehr hübsch. Und verwendet irgendwo im Verborgenen tatsächlich millis(), wie von Andreas gefordert.
Reagiert allerdings nicht speziell auf Zeilenende-Zeichen.

Reagiert allerdings nicht speziell auf Zeilenende-Zeichen.

Nicht im speziellen.
Zeigt aber, dass Nachleuchtdauern mit millis() realisierbar sind.

led = toff = Serial.available();
Der rote Teil kann durch einen beliebigen anderen Ausdruck ersetzt werden.
Einzige Bedingung: Er muss zu bool auswertbar sein.

Muss allerdings zugeben, dass ich beim verstehen der Eingangsfrage nicht die volle Punktzahl erreicht habe.

oh :open_mouth: war wohl doch zu früh.
die led soll nachleuchten. dann war meine Ausführung unpassrnd.

Ein gutes Beispiel minimiert externe Abhängigkeiten:

const byte led=LED_BUILTIN;

void setup() {
  Serial.begin(9600);
}
unsigned long received;
void loop() {
  if (Serial.available()) {
    received = millis();
    Serial.read();
  }
  digitalWrite(led, (millis() - received < 5000) );
}

Das sollte ziemlich äquivalent zu combies Beispiel sein, mit denselben Einschränkungen der Funktionalität, und das Nachleuchten 5 sec nach dem letzten Zeichen mit Hilfe von millis() zeigen.

man sollte noch das CR berücksichtigen.
denn was ist, wenn der satz (endet ja eigentlich mit satzzeichen statt CR) nie beendet wird? dann müsste die led ewigcan bleiben.

Combie hat es doch schon gesagt und die Routine löst zu bool auf:

led = toff = readSerial(Serial)

Das Delay natürlich raus.

Wobei ich in readSerial das '\r' aus der Endebedingung raus nehmen würde. Das fällt bei >32 mit weg.

Gruß Tommy

Hallo,
ich habe das ganze mal einen Tag nicht angerührt, damit ich wieder runterkomme.
Der Weg nach oben ist also wieder frei :wink:

Mit euren Vorschlägen habt Ihr mich auf den richtigen Weg gebracht, es läuft
bis jetzt so, wie ich es mir vorgestellt habe.
Das habt Ihr richtig gut gemacht.
Andreas sagt Danke schön.
Gruß und Spaß
Andreas

Hier geht es weiter...