hk007
February 27, 2016, 7:19pm
1
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;
hk007
February 27, 2016, 7:27pm
3
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.
hk007
February 27, 2016, 7:31pm
5
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
hk007
February 27, 2016, 7:36pm
7
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)
hk007
February 27, 2016, 7:41pm
9
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);
}
hk007
February 27, 2016, 7:48pm
11
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
hk007
February 27, 2016, 7:55pm
13
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.
hk007
February 27, 2016, 8:16pm
15
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
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. 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
hk007
February 27, 2016, 8:27pm
17
Juhuuuuuuuuuuu
...stolz der Padawan ist auf seine Lösung...
Nochmal danke für den Chat.
Deine Lösung hab ich in meine Codeschnipsel-Sammlung kopiert. Kann ich vllt. mal brauchen.