Pages: [1]   Go Down
Author Topic: Unverständliches Bitshift Problem  (Read 552 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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!
Logged

Germany
Offline Offline
Faraday Member
**
Karma: 59
Posts: 3083
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 174
Posts: 3274
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 2
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
Serial.print()
oder
Code:
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.
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 174
Posts: 3274
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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)
Logged

Forum Moderator
BZ (I)
Offline Offline
Brattain Member
*****
Karma: 271
Posts: 21936
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Pages: [1]   Go Up
Jump to: