Serial liefert Zeichen…

Hallo,
die Serial2 liefert im seriellen Monitor -1.

if (Serial2.available() > 0)

wird aber als wahr angesehen. Wie kann ich das ändern?
Es gibt diese Möglichkeit:

Serial2.end();
delay (50);
Serial2.begin(9600);

das kann aber doch nicht die Lösung sein?
Gruß und Dank
Andreas
Quelle des Elend, hier ab #12

SkobyMobil:
Hallo,
die Serial2 liefert im seriellen Monitor -1.

if (Serial2.available() > 0)

wird aber als wahr angesehen. Wie kann ich das ändern?

Poste doch bitte mal ein vollständiges, minimales Programm das dieses Verhalten zeigt.

Wenn du den von read zurückgegeben Wert in einen char speicherst, baust du dir mit den 0xFF des Nextion ein -1,
das hat aber nichts mit den -1 zu tun, das read liefert wenn kein Zeichen vorhanden ist.

Dann gehe ich mal mit einem Beispiel voran.

Serial - normale PC Verbindung
Serial1 verbunden mit Serial2, logischerweise TX-RX, RX-TX
Serial1 benutzt 0xFF 0xFF 0xFF als Delimiter, die anderen CR.

Eingaben auf Serial werden mit 3 x 0xFF versehen über Serial2 verschickt, von dort an Serial1 zurückgegeben.

Da mir das zu lästig war immer wieder alles neu zu schreiben, habe ich die serielle Verabeitung in eine Klasse gepackt,
die die Details handhabt und eine Routine aufruft, wenn eine ganze Zeile da ist.
Bei mehreren seriellen Schnittstellen gleichzeitig ist das besonders praktisch.

#include <SSerial.h>

void conHandler(const char* buf);
void inHandler(const char* buf);
void outHandler(const char* buf);

SSerial Con(Serial, conHandler);
SSerial In(Serial1, inHandler);
SSerial Out(Serial2, outHandler);

void setup() {
  Serial.begin(250000);
  Serial1.begin(250000);
  Serial2.begin(250000);
  Serial.println(F("Serial Test"));
  Con.begin(32, optEmptyToo | optIgnoreLF);
  In.begin(32, optTripleFF | optDebug);
  Out.begin(32, optIgnoreLF);
}

void loop() {
  Con.loop();
  In.loop();
  Out.loop();
}

void conHandler(const char* buf) {
  report(PSTR("con"), buf);
  Serial2.print(buf);
  Serial2.write(0xFF);
  Serial2.write(0xFF);
  Serial2.write(0xFF);
}

void inHandler(const char* buf) {
  report(PSTR("in "), buf);
  Serial1.println(buf);
}

void outHandler(const char* buf) {
  report(PSTR("out"), buf);
}

void report(const char* on, const char* buf) {
  Serial.print((__FlashStringHelper*)on);
  Serial.print(F(": "));
  byte len = strlen(buf);
  if (len < 10) {
    Serial.write(' ');
  }
  Serial.print(len);
  Serial.print(F(" '"));
  Serial.print(buf);
  Serial.println(F("'"));
}
Serial Test
con:  3 'abc'
00 i 61
01 i 62
02 i 63
03 i FF
04 i FF
05 i FF
in :  3 'abc'
out:  3 'abc'

SSerial.h

#ifndef _SSERIAL_H_
#define _SSERIAL_H_
#include <Arduino.h>

const byte cbLF = 10;
const byte cbCR = 13;

const byte optIgnoreLF = 0x40;
const byte optSkipWS = 0x20;
const byte optEmptyToo = 0x10;
const byte optTripleFF = 0x08;
const byte optDebug = 0x04;

typedef void (*lineProcess)(const char* iLine);

class SSerial {
 Stream& serial;
 byte options;
 byte bSize;
 byte bIndex;
 byte* buffer;
 lineProcess handler;
public:
 SSerial(Stream& inSer, lineProcess iHandler) : serial(inSer), handler(iHandler) {}
 ~SSerial() { delete [] --buffer; }
 void begin(byte buffSize, byte inOpts = optIgnoreLF);
 void loop();
 byte getIndex() { return bIndex; }
 byte getSize() { return bSize; }
};

#endif

SSerial.cpp

#include <SSerial.h>

void SSerial::begin(byte buffSize, byte inOpts) {
 options = inOpts;
 bSize = buffSize;
 buffer = new byte[bSize+1];
 if (buffer == NULL) {
 bSize = 0;
 } else {
 buffer++;
 }
 bIndex = 0;
}

void SSerial::loop() {
  bool doCheck = false;

  while (serial.available()) {
    byte inChar = serial.read();
 if (options & optDebug) {
 if (bIndex < 16) {
 Serial.write('0');
 }
 Serial.print(bIndex, HEX);
 Serial.print(F(" i "));
 if (inChar < 16) {
 Serial.write('0');
 }
 Serial.println(inChar, HEX);
 }
    if (inChar == cbLF && options & optIgnoreLF) {
      continue;
    } else if (inChar == cbCR && !(options & optTripleFF)) {
      // pass up only if non empty, or empty requested
      doCheck = bIndex || (options & optEmptyToo);
    } else if (options & optTripleFF && inChar == 0xFF && bIndex >= 2 &&
 buffer[bIndex-1] == 0xFF && buffer[bIndex-2] == 0xFF) {
      bIndex -= 2;
      // pass up only if non empty, or empty requested
      doCheck = bIndex || (options & optEmptyToo);
    } else {
      // skip whitespace on line start
      if ((bIndex == 0) && isWhitespace(inChar) && (options & optSkipWS)) {
        continue;
      }
      // store in buffer, advancing index
      buffer[bIndex++] = inChar;
      // passup if filled
      doCheck = (bIndex == (bSize - 1));
    }
    if (doCheck) {
      buffer[bIndex] = 0; // make buffer a string
      (*handler)((const char*)buffer); // pass to handler
      bIndex = 0; // empty buffer
    }
  }
}

Hallo,

hier ist das Elend:

ich habe

blah, blah,



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

void loop()
{

  if (Serial2.available() > 0)
  {

    if (readSerial(Serial2) == true);
    {
      NexSer();
    }

  } 
}

//loop ende

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;   
      return true;
    }
  }
  return false;
}


void NexSer()

{

  if (strcmp(serialBuffer, "innen Klima") == 0)
  {
    zlHYT = 0;
    LoopHYT();
    NextionTempIN();
  }

}

Das funktioniert alles, nur das immer ein -1 anliegt- es wird aber nicht gesendet

das Original ist

if (readSerial(Serial2) == true);
    {
      NexSer();
    }

das ist aber immer wahr- die Schleife wollte ich mit

if (Serial2.available() > 0)

eleminieren.
Ich glaube, da stimmt auch etwas grundsätzlich nicht.

Gruß und Dank
Andreas

Es kann daran haken dass wahr nicht größer 0 oder 1 ist, sondern ungleich 0. Also ist -1 wahr wenn man nicht direkt darauf abfragt.

Das sind zwei verschiedene Sachen wenn die Funktion -1 liefern kann:

if (func())
if (func() > 0)

Du meinst aber dass dir Serial.read() -1 liefert, oder? available() ist glaube ich nie negativ.

Deine readSerial Funktion gibt nur true zurück, wenn die Zeile vollständig empfangen wurde.

Erstaunlicherweise benutzt die Routine aber CR/LF als Zeilentrenner, ich denke dass das Nextion rein wie raus drei 0xFF verwendet.

   else if ((c == '\n' || c == '\r') && index > 0)
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;   
      return true;
    }
  }
  return false;
}

Wenn das der Fall ist kann man einfach die Anzahl der 0xFF Zeichen zählen:

bool readSerial(Stream& stream)
{

  static byte index;
  static byte endline;

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

    if (c == 0xFF)
    {
       endline++;
       if (endline == 3)
       {
         serialBuffer[index] = '\0';
         index = 0;
         endline = 0;   
         return true;
       }
    }
    else if (c >= 32 && index < SERIAL_BUFFER_SIZE - 1)
    {
      serialBuffer[index++] = c;
    }
  }
  return false;
}

Das reicht nicht, ich denke die 0xFF müssen aufeinanderfolgend sein um als Delimter zu zählen.

Wenn das Display nur ASCII sendet sollte 0xFF sonst nie vorkommen

Wenn man nicht vorhätte auch binäre Daten zu übertragen, warum sollte man drei 0xFF benutzen?
Dann wäre ein normaler CR/LF doch viel kompatibler,

Hallo,
eigentlich habe ich „alle Informationen“ zur seriellen Kommunikation, die ich
benötige. Aber etwas will ich da wohl noch nicht verstanden haben.

„Es kann daran haken dass wahr nicht größer 0 oder 1 ist, sondern ungleich 0.“

Da bin ich auch schon drauf gekommen, das es so sein könnte. ich habe aber auch in
anderen Sketchen diese Abfrage, da funktioniert es. Habe aber noch nicht auf dem
seriellen Monitor nach -1 gesucht.

Das Nextion sendet:

print „MeinVergleichsText“
print „\r“

Bei print „\n“ gibt das Nextion eiene SequenzZeichenFehler aus. Bei dem „\r“ nicht.
Was das Nextion danach sendet, ist doch völlig egal? Z.B. 3 mal 0xFF

Das wird doch nicht berücksichtigt. Danach wird doch nichts mehr gesendet.

„Du meinst aber dass dir Serial.read() -1 liefert, oder?“
Ja das meine ich. Macht es in einer Tour.

Sendet der Arduino aber zwischendurch auf Serial2. etwas, kommt die -1 danach nicht mehr.

Oder ist es so, das „\r“ und 3 mal 0xFF gesendet wird- der Arduino bis „\r“ auswertet und
verarbeitet- die 3 mal 0xFF aber noch im Seriellen Speicher stehen?
Gruß und Dank
Andreas

Lies die Formate doch mal nach, dann brauchst du nicht vermuten.

print.png

https://www.boecker-systemelektronik.de/epages/63381271.sf/de_DE/?ObjectPath=/Shops/63381271/Categories/Tutorials/Nextion_Tutorials/Datenbefehle

Ein char (int8_t) mit 0xFF ist gleich -1 und wenn Du den Empfangspuffer nicht leer liest, steht das noch drin.

Gruß Tommy

Hallo,
was für Formate gesendet werden, ist mir schon klar- nur was der Arduino draus
macht noch nicht so richtig.
Ich habe es geschafft int zu empfangen (2358) und es wird am Arduino ausgegeben. Auch ein
„Andreas probiert etwas“ kann ich empfangen und ausgegeben. Auch das vergleichen der
gesendeten Daten funktioniert. Das ist schon eine Menge.

Und jetzt dieser Dreck mit der -1.
Lt. ArduinoReferenz bedeutet -1, keine Daten mehr vorhanden.
Und das ist aber eine -1 integer. Auf Die- reagiert auch (Serial2.available() > 0)
Da habe ich mich wohl in Irre führen lassen.

Und wenn die 0xFF noch als „WertX -1“ im Speicher stehen, dann kann
(Serial2.available() > 0) nicht ziehen.

Also ist es sicherer die 64 Byte des Speicher ganz zu lesen und sich das passende
ausschneiden. Oder einfach auf das letze Zeichen auswerten- das hier auch noch
bekannt ist!
man, man, man- da ist Trommeln aber leichter…
Gruß und Dank
Andreas

Deine -1 gibt es nicht (wenn man nur liest wenn etwas da ist und man den von read zurückgegebenen Wert in einem int abspeichert).

Deine Empfangsroutine kann die binären Daten des Nextion nicht vernünftig bearbeiten und/oder dekodieren.

Hallo,
die -1 hat der serielle Monitor mir aber geliefert. Das 0xFF ist es aber auch
nicht gewesen.
Mit dem Nextion habe ich ja wie beschrieben folgendes gesendet:

print „MeinVergleichsText"
print „\r"

Bei print „\n" gibt das Nextion eiene SequenzZeichenFehler aus. Bei dem „\r" nicht. So weit, so gut.

Nun habe ich mit einem Terminal Programm mal überprüft, was denn tatsächlich
gesendet wird.

Nach “MeinVergleichsText” sendet das Nextion 0x0D 0x0A

und dann zieht

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

nicht mehr.
Hier wird auf “oder” abgefragt, wer zuerst kommt- malt zuerst.

Das Nextion verweigert das senden von Escape-Sequenzen.

Beim senden ‘\n’ kommt ein Nextion-Fehler, aber ‘\r’ wird angenommen.
Sendet man nun print „\r" dann sendet das Nextion 0x0D 0x0A.

Das ist zuerst ein und dann ein

ändert man nun

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

in

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

dann funktioniert das ganze ohne Probleme.
Das läuft also jetzt fehlerfrei. Ist auch schwer genug gewesen.
Gruß und Dank
Andreas

SkobyMobil:
ändert man nun

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

in

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

dann funktioniert das ganze ohne Probleme.
Das läuft also jetzt fehlerfrei. Ist auch schwer genug gewesen.
Gruß und Dank
Andreas

Na ja...

Dir ist schon klar, dass

(c == '\r' && c == '\n')

nur eine unnötig komplizierte Schreibweise von
falseist?

Der neue Ausdruck ist äquivalent zu

else if (c == '\n' || c == '\r')

wenn du das so meinst, solltest du das so schreiben.

Hallo,
das ist mir- schon klar(geworden).
Ich habe die Abfrage nur extrem einfach geändert. So das es wohl jeder verstehen
sollte.
Und es funktioniert so sicher. Es ist eine einfache Möglichkeit so Text vom
Nextion zu empfangen.
Selbstverständlich kann man wohl jede Zeile Code auf eine andere Weise
optimieren. Das soll aber jeder für sich entscheiden.

Ich habe für ein ganz bestimmtest Problem eine Lösung gesucht. Diese Lösung
habe ich gefunden. Ob das nun der beste Weg ist lassen wir noch einmal offen.
Jeder Sketch der fehlerfrei läuft- ist ein guter Sketch.
Gruß und Spaß
Andreas

Wenn der Code mit dieser Bedingung läuft und ohne nicht, dann muss es eine andere Ursache dafür geben.

Diese zusätzliche Bedingung ist einfach sinnlos.
Die Begründung hat Whandall ja bereits geliefert. Das Zeichen kann nicht gleichzeitig '\n' und '\r' sein.

Gruß Tommy

Hallo,
"Wenn der Code mit dieser Bedingung läuft und ohne nicht, dann muss es eine andere Ursache dafür geben.
Diese zusätzliche Bedingung ist einfach sinnlos."

Mit print "\r" liefert das Nextion 0x0D 0x0A

Für den Arduino kommt hier zuerst 0x0D (CR).

Also kann "else if ((c == '\n' || c == '\r') && index > 0)" nicht wahr sein.

Was sollte da denn nicht stimmen? Wenn ich mit 0x0D aussteige, dann habe ich doch 0x0A noch im Speicher.
Und dann kann auch "if (Serial2.available() > 0)" erfüllt sein.

Wenn ich aber mit "(c == '\r' && c == '\n') && index > 0)" austeige, dann ist der Speicher leer.
"if (Serial2.available() > 0)" zieht dann nicht mehr.
Gruß und Spaß
Andreas