ich habe hier ein kleines Programm das am Seriellen Port Daten empfängt.
Das klappt schon mal sehr gut.
Mein Empfangspuffer ist so vereinbart:
const int MaxEmpfangsZeichen = 199;
char Emfangszeichenkette[MaxEmpfangsZeichen + 1]; // immer eins mehr
int ZaehleEmpfangzeichen = 0;
hier die Empfangsroutine:
void serialEvent() {
while (Serial.available()) {
byte inChar = Serial.read();
if (ZaehleEmpfangzeichen < MaxEmpfangsZeichen - 2) {
Emfangszeichenkette[ZaehleEmpfangzeichen++] = inChar;
}
}
}
In den Empfangenen Zeichen kann auch 0FEh (Hexadezimal) vorkommen.
Wenn ich mit einer Schleife durch die empfangenen Zeichen gehe und sie vergleiche
finde ich 0xFE nicht !?!?
for (int n = 2; n < ZaehleEmpfangzeichen; n++) {
if (Emfangszeichenkette[n] == 0xFE) {
auch folgende Konstruktion hilft nicht:
for (int n = 2; n < ZaehleEmpfangzeichen; n++) {
if (Emfangszeichenkette[n] & 0x00FF == 0xFE) {
suche ich nach 0xFFFE, dann ist es wahr !
for (int n = 2; n < ZaehleEmpfangzeichen; n++) {
if (Emfangszeichenkette[n] == 0xFFFE) {
ich habe ja char = 8 Bit deklariert, woher kommen dann die oberen 8 Bit FFxx ? also ein word ?
Bemerkung: Die Schleife beginnt bei 2 da die ersten beiden Zeichen nie FE sein können.
Dann mach mal aus byte Empfangszeichenkette unsigned Byte. oder vergleiche statt mit 0xFE mit (char) oder besser
(unsigned char) 0xFE.
Deine Konstante ist von Typ int. Bei Operationen wird immer auf die Kardinalität des größten Datentyps erweitert.
Also ein Element aus Empfangszeichenkette wird umgewandelt von char auf int.
Da du aber signed char hast ist bei 0xFE das Vorzeichenbit gesetzt also wir haben den Wert -2 Das expandiert
auf int gibt 0xFFFE also auch -2.
Sind die Datentypen unsigned dann ist 0xFE 254 und auch als int 254 also 0x00FE.
Je nach Compiler kann man sich bei char nicht darauf verlassen ob signed char oder unsigend char die
Voreinstellung ist. Also immer "ausformulieren".
ich habe ja char = 8 Bit deklariert, woher kommen dann die oberen 8 Bit FFxx ? also ein word ?
Empfangszeichenkette[n] ist ein char, da hast du Recht.
0xFE ist aber einint
Der Vergleich == wird daher mit zwei int gemacht.
char c = 0xFE; ist vorzeichenbehaftet. Also -2 oder als int gesehen das gleiche wie 0xFFFE; const int i = 0xFE; ist natürlich 254, und damit ungleich -2
Wenn es dich tröstet: du bist nicht der einzige, dem das erst beim Testen auffällt.
Trotz der fehlenden Grundkenntnisse wäre der Vergleich in ASSEMBLER 'völlig Banane' - da ist 0xFE == 0xFE, fertig!
Einzig beim Rechnen macht sich das Vorzeichen bemerkbar - vll. wurden hier einfach Grundlagen gemacht, wo Keine nötig gewesen wären - aber da die Sprache schon etwas älter ist, wohl so eingebürgert.
Trotzdem 'nice²know' - man kann (will) halt nicht Alles in Assembler erschlagen - auch, weil man da doch mehr an die Zielhardware gebunden ist.
Ich schrieb, daß in Assembler die Prüfung von 0xFE mit 0xFE true ergibt - da es dem Assembler egal ist, was für ein Typ dieses 0xFE ist - dafür hast Er einen Programmierer - Der kümmert sich darum, daß das 0xFE Das ist, was Es sein soll.
Dort kann ich auch 0x31 mit "1" vergleichen und bekomme true raus - Gleiches will mir der Arduino gerade nicht machen, da ich ein byte mit einem char vergleichen will (wenn ich mich recht entsinne).
Ich schrieb auch nicht, daß Das in Assembler kein Problem wäre oder Ähnliches - ich schrieb, daß das Problem in Assembler kein Problem wäre - schrieb ich aber oben schon.
In Assembler kann man noch viel blödere Fehler machen, zumal es in AVR-Assembler gar keinen int Datentyp gibt, höchstens Register einzeln und im Doppelpack.
Ob man in Assembler 100 oder 1000 mal mehr Fehlermöglichkeiten hat, die erst beim Testen auffallen, darüber will ich jetzt mal nicht streiten.
Der größte Fehler ist immer, Assembler zu verwenden, obwohl es nicht nötig wäre.
Und es ist nur ganz selten nötig.
Der wichtigste Anwendungsfall für Assembler ist