Problem mit Streaming.h

Hallo,

jetzt suche ich mich schon ne Stunde tot, und finde einfach nicht meinen Fehler:

Wieso funktioniert das

Serial.print("HRemainTime.val=");
Serial.print(HeaterRemainTime);
Serial.write(0xff);
Serial.write(0xff);
Serial.write(0xff);

und das nicht?

Serial << "HRemainTime.val=" << HeaterRemainTime << 0xff << 0xff << 0xff;

Ist ne serielle Kommunikation mit einem Nextion-Display.

Wahrscheinlich weil << print() macht. Und nicht write()

Nachtrag:
Es gibt einen Parameter für Binär:

struct _BYTE_CODE
{
 byte val;
 _BYTE_CODE(byte v) : val(v)
 {}
};
#define _BYTE(a)    _BYTE_CODE(a)

inline Print &operator <<(Print &obj, const _BYTE_CODE &arg)
{ obj.write(arg.val); return obj; }

Das wird sogar in Beispiel gezeigt:

  Serial << "You can use modifiers too, for example:" << endl;
  Serial << _BYTE(lettera) << " is " << _HEX(lettera) << " in hex. " << endl;

Aja.
Also will er den Wert der Variable 0xff rausschreiben?

Und ich muss jetzt einen String basteln der drei Bytes mit ff beinhaltet, und den kann ich dann mit << dranhängen?

Also will er den Wert der Variable 0xff rausschreiben?

Er macht ASCII draus

Und ich muss jetzt einen String basteln der drei Bytes mit ff beinhaltet, und den kann ich dann mit << dranhängen?

Ähhh? Nein. Wie kommst du darauf. Einen String schickst du ja so schon. Das ist ja gerade nicht was du willst

Ich habe aber mal nachgesehen und was dazu editiert. _BYTE() sollte write() machen.

Die Bibliothek ist da sehr flexibel und kann um alle möglichen Parameter erweitert werden.

Kann ich mir dann mit meinen 3 x ff auch so was wie ein "endl" basteln? Diese Endung muss ich nämlich an jeden Befehl dranhängen

Das endl ist doch auch nichts anderes wie 0xa, oder?

Wenn du das oben schicken willst machst du:

Serial << "HRemainTime.val=" << HeaterRemainTime << _BYTE(0xff) << _BYTE(0xff) << _BYTE(0xff);

endl ist println() also CR + LF

Serenifly:

Serial << "HRemainTime.val=" << HeaterRemainTime << _BYTE(0xff) << _BYTE(0xff) << _BYTE(0xff);

Kann man das irgendwie kürzer machen?
Wie gesagt ich brauch das am ende jeder Zeile.
Ich hab mir schon eine Funktion geschrieben, aber die arbeitet nur mit einem String.
Wenn ich da Text mit Werten mischen will, dann geht die nicht.

void NextionSend(String instring){
    Serial.print(instring);
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff); 
}

Dann mach halt eine Funktion draus. Evtl. inline. Dafür sind Funktionen da!

Und das:

void NextionSend(String instring)

Ist Schrott

Besser:

void NextionSend(const String& instring)
void NextionSend(const String& instring)

Was ist da jetzt richtiger?

Damit das Objekt nicht unnötig kopiert wird. & übergibt nur die Adresse. Stichwort: call by reference

Und mit Funktion meinte ich sowas:

void endingSend()
{
    Serial.write(0xff);
    Serial.write(0xff);
    Serial.write(0xff); 
}

OK danke,

aber nochmal zu meinem Denkansatz.

Serial schreibt alles in ASCII raus, oder?
Jetzt bräuchte ich doch nur einen 3byte-Container in dem jedes Byte 0xff ist. (Also alle Bits high)
Und wenn ich den mit << dranhänge, dann sollte das doch auch gehen, oder?

Wenn ich “abc” sende, dann kommt auf der Schnittstelle ja auch nur 0x61 0x62 0x63 raus.

Serial schreibt alles in ASCII raus, oder?

print() macht ASCII. write() ist binär!

Jetzt bräuchte ich doch nur einen 3byte-Container in dem jedes Byte 0xff ist. (Also alle Bits high)
Und wenn ich den mit << dranhänge, dann sollte das doch auch gehen, oder?

Schau dir an wie endl implementiert ist. Ganz am Ende des Headers

Serenifly: Schau dir an wie endl implementiert ist. Ganz am Ende des Headers

Ja, danke für den Tip. Aber das übersteigt meine Kenntnisse. k.A. was die 5 Zeilen genau machen. Sorry da reichts bei mir nicht für...

Ich vermute zu erkennen, dass er hier aus print ein println macht.

Es kann doch nicht so schwer sein das zu kopieren und anzupassen. Auch wenn man nicht alles versteht

enum _NextionEndLineCode { nextionEndl };

inline Print &operator <<(Print &obj, _NextionEndLineCode arg) 
{ 
  obj.write(0xFF); 
  obj.write(0xFF); 
  obj.write(0xFF); 
  return obj;
}

Dann macht nextionEndl drei mal write(0xFF)

Man muss nur einen Datentyp für die << Funktion erstellen. Da hier nichts übergeben wird wird ein enum verwendet. Das ist auch nicht anders wie bei jeder anderen Funktionen. Dann übergibt man einen Parameter namens “arg” von diesem Typ. Machen muss man damit nichts. Der dient nur dazu dass der Compiler beim Aufruf die Funktion identifizieren kann.

Du musst nicht verstehen wie man Operatoren überlad. Oder was inline ist. Oder wie man Operatoren verkettetet. Es geht nur um den Funktionsparameter.

Es kann doch nicht so schwer sein das zu kopieren und anzupassen. Auch wenn man nicht alles versteht

Du siehst das aus der Sichtweise eines Profis :wink:
Ich tu mich da echt schwer mit.

Ich hab in der Zwischenzeit etwas gegoogelt und probiert:
Was hältst du von dem Ansatz:

 Serial << "HRemainTime.val=" << HeaterRemainTime << "\xFF\xFF\xFF";

Das meinte ich mit einem “Container mit 3 Byte FF”. Wusste nur nicht wie ich das zusammenbaue.
Funktionieren tut es …

Und ich müsste nicht in der lib rumändern.

Ja, das würde natürlich auch gehen. Daran hatte ich gar nicht gedacht. :confused: Man kann so viel machen dass man einiges leicht übersieht

Das kann man auch bei HD44870 LCDs verwenden um Sonderzeichen wie das Grad-Symbol zu schreiben

Juhuuuuuuuuuuu

…stolz der Padawan ist auf seine Lösung… :grin:

Nochmal danke für den Chat.
Deine Lösung hab ich in meine Codeschnipsel-Sammlung kopiert. Kann ich vllt. mal brauchen.