Go Down

Topic: Unverständliches Bitshift Problem (Read 578 times) previous topic - next topic

Hallo liebe Forenuser,
ich habe mich für dieses verkraftbare aber seltsame Problem in meinem Arduino Uno Programmcode angemeldet, dessen Verhalten ich einfach nicht verstehe. So wenig, dass ich nicht mal weiß, wonach ich da suchen sollte.

Zunächst der Quelltextauszug:

Code: [Select]
byte clearByte(byte toClear, boolean clearFront, byte shift) {
Serial.write(toClear);
if (clearFront) {
toClear = (toClear << shift);
toClear = (toClear >> shift);

} else {
toClear = (toClear >> (8 - shift));
toClear = (toClear << (8 - shift));
}
return toClear;
}


Diese Funktion soll also Bits aus einem Byte auf 0 setzen, entweder am Byteanfang oder -ende. So wie sie dort steht funktioniert das prima, das seltsame jedoch: Lösche ich die Serial.write(toClear) Zeile aus dem Quelltext, funktioniert das ganze nicht mehr. Die Methode funktioniert nur, wenn ich die Variable zwischendurch (egal wann) ausgebe, ansonsten kann der Rest des Systems nicht richtig damit arbeit.

Kann mir wer erklären warum?

Vielen Dank im voraus!

michael_x

Quote
ansonsten kann der Rest des Systems nicht richtig damit arbeit.

Leider ist nicht ganz klar, was im Fehlerfall passiert:
Gar nichts? Also es wird das toClear Byte unverändert zurückgegeben?

Falls ja, würde ich raten: Der Compiler denkt: shift hin, shift zurück, macht nichts, kann also wegoptimiert werden ?

Was passiert mit einer Hilfsvariablen ?
Code: [Select]
byte clearByte(byte toClear, boolean clearFront, byte shift) {
Serial.write(toClear);
if (clearFront) {
byte result  = (toClear << shift);
return (result >> shift);

} else {
byte result = (toClear >> (8 - shift));
return (result << (8 - shift));
}
}


Aber seltsam ist das schon, bzw. ich sehe es auch nicht wirklich.

jurs


Die Methode funktioniert nur, wenn ich die Variable zwischendurch (egal wann) ausgebe, ansonsten kann der Rest des Systems nicht richtig damit arbeit.

Kann mir wer erklären warum?


Kannst Du uns mal erklären, welche Arduino-Version Du verwendest?

Ich kann das hier beim Kompilieren für UNO-Boards nämlich weder mit Arduino 1.0.1 noch mit 1.0.3 nachvollziehen, das funktioniert hier so oder so.

Hast Du mal einen kompletten Demo-Sketch, mit Variablendeklaration und Funktionsaufrufen, bei dem es nicht funktioniert?


Hallo,

danke für die Antworten, bin ja schon froh, dass es nichts offensichtliches ist^^

Eine Hilfsvariable hat keinen Einfluss auf die Ausführung.

Quote
Kannst Du uns mal erklären, welche Arduino-Version Du verwendest?

Ich verwende Arduino 1.0.1

Leider kann ich das durch einen Demo-Sketch auch nicht reproduzieren, da scheint irgendwo im Rest des Quelltextes der Wurm drin zu sein. Dank eurer Hinweise konnte ich den betroffenen Bereich stärker eingrenzen, in nur einem von 3 Aufrufen in meinem Programm verhält er sich so, dass ich eine 3 reinwerfe und die vorderen 4 löschen möchte:
Code: [Select]
byte a = 3;
byte from = 4;
clearByte(a, true, from); // Ausgabe: 48, erwartet: 3

die Ausgabe aber nur 1 mal nach links verschoben wurde und nicht zurück, außer ich gebe diese 3 erst einmal über
Code: [Select]
Serial.print() oder
Code: [Select]
Serial.write() aus...

Der Rest des Quelltextes ist sehr komplex, nach einem kleinem Demo-Sketch zu suchen ist ein guter Hinweis, auf den ich irgendwie nicht selbst gekommen bin - habe stattdessen endlose Ausgaben als "Debuginformation" hineingeschrieben. Sobald ich das geschafft habe, berichte ich von dem Problem, sollte wer in die gleichen Fallen tappen.
Aber mal ganz allgemein: Macht Serial.write() irgendetwas mit der übergebenen Variablen? Typkonversion oder sowas?

Vielen Dank bisher und entschuldigt den zu frühen Hilferuf.

jurs


Leider kann ich das durch einen Demo-Sketch auch nicht reproduzieren, da scheint irgendwo im Rest des Quelltextes der Wurm drin zu sein.


Ich tippe auf: Dein Programm erfordert mehr RAM-Speicher als Dein Mikrocontroller eingebaut hat.

Dadurch überlagern sich jetzt bereits Heap (Variablenbereich) und Stack (Rücksprungadressen und Funktionsparameter) und führen zu völlig unvorhersehbarem Programmverhalten.

In dem Fall würde helfen:
- RAM-Speicher durch speichersparende Programmierung einsparen
- Mikrocontroller mit mehr RAM-Speicher verwenden (z.B. MEGA statt UNO)

uwefed

Ich hatte mal das Problem daß der Sketch funktioierte wenn ich ein Seriale.print() drinhatte und ohne nicht mehr, eine for-Schleife ging nicht.
Bei mir war der Fehler ein Indexüberlauf eines Arrays.
Grüße Uwe

Go Up