Forum: PC-Programmierung Arduino Bitmanipulation


von Manfred V. (dg4aai)


Lesenswert?

Kann mir jemand diesen Befehl erklären?
In einem Sketch für DTMF Töne auswerten gibt es einen Befehl:
number= (0x00 | (digitalRead(3) <<0) | (digitalRead(4) <<1 | 
(digitalRead(5) <<2) | (digitalRead(6) <<3));
Ich bin Neuling auf dem Gebiet der Arduino Programmierung, möchte aber 
dazulernen.
Ich weiß digitalRead(X) ließt den Wert des entsprechenden Pin aus.
Was macht der oben aufgeführte Befehl aber im Einzelnen?

von DerEinzigeBernd (Gast)


Lesenswert?

Zerlegen wir das ganze in seine Bestandteile.
1
number = 
2
3
  (0x00 | (digitalRead(3) <<0)                //  (1)
4
5
| (digitalRead(4) <<1 | (digitalRead(5) <<2)  //  (2)
6
7
| (digitalRead(6) <<3));                      //  (3)

Gelesen werden die Digitaleingänge 3, 4, 5 und 6.

Der Wert des Digitaleingangs 3 landet im untersten Bit des Ergebnisses, 
der Wert des Digitaleinganges 4 landet im nächsten Bit und so weiter.

Der Shiftoperator << schiebt einen Wert um die angegebene Anzahl von 
Bitstellen nach links.

Das kann man auch als Multiplikation mit einer Zweierpotenz betrachten:
1
   x = y << z;
2
3
entspricht
4
5
  x = y * (2 ↑ z);


Der Code ist unübersichtlich geschrieben und enthält überflüssige Dinge.
In Zeile (1) steht
1
  (0x00 | (digitalRead(3) <<0)

Das Verodern des Wertes 0x00 bewirkt rein gar nichts, das kann 
entfallen.
Den Wert um Null Bits nach links zu verschieben, bewirkt rein gar 
nichts, und kann daher auch entfallen.

In Zeile (2) steht
1
  | (digitalRead(4) <<1 | (digitalRead(5) <<2)  //  (2)

Da ist wohl jemand mit den Klammern durcheinandergekommen, das sollte 
wohl so aussehen:
1
  | (digitalRead(4) <<1) | (digitalRead(5) <<2)  //  (2)

womit die abschließende Klammer in Zeile (3)
1
  | (digitalRead(6) <<3));                      //  (3)

entfallen kann.

Damit sieht das ganze so aus:
1
number = 
2
    digitalRead(3)
3
 | (digitalRead(4) << 1)
4
 | (digitalRead(5) << 2) 
5
 | (digitalRead(6) << 3);

von Manfred V. (dg4aai) (Gast)


Lesenswert?

Hallo DerEinzigeBernd (Gast),
herzlichen Dank für deine verständliche Erklärung.
Hat mir weiter geholfen den Sketch zu verstehen.
Gruß
Manfred

von mIstA (Gast)


Lesenswert?

Manfred V. schrieb:
> In einem Sketch für DTMF Töne auswerten gibt es einen Befehl:
> number= (0x00 | (digitalRead(3) <<0) | (digitalRead(4) <<1 |
> (digitalRead(5) <<2) | (digitalRead(6) <<3));

Wenn der Befehl tatsächlich so im Sketch steht, dann wird Dir der 
Compiler die Mitarbeit verweigern; zähl mal jeweils die öffnenden und 
schließenden Klammern nach. ;)

Solltest Du den Befehl vom Sketch nicht mit Copy&Paste hier ins Forum 
transportiert, sondern per Look&Type, dann laß Dir das am Besten gleich 
eine Lehre sein und mach sowas nie wieder!

Das ist nämlich nicht nur mühsam, sondern auch verdammt fehleranfällig - 
und spätestens wenn Du das erste Mal eine Frage bzgl. nicht 
funktionierenden bzw. compilierenden Code stellt, wirds dann für die 
Helfer nervig, wenn sie oft als erstes Deine Abtipp-Fehler finden.


DerEinzigeBernd schrieb:
> Da ist wohl jemand mit den Klammern durcheinandergekommen

Schaut mir stark nach Abtipp-Fehler des OP aus.


DerEinzigeBernd schrieb:
> womit die abschließende Klammer in Zeile (3)
> …
> entfallen kann.

Nur wenn man neben der sinnlosen Veroderung mit 0 auch gleich die 
allererste Klammer mitentsorgt hat; genaugenommen könnte man ohnehin 
alle Klammern bis auf die Funktionsaufrufe entsorgen, die 
Shift-Operatoren haben sowieso höhere Priorität als die 
Bitweisen-Verknüpfungen.


DerEinzigeBernd schrieb:
> Den Wert um Null Bits nach links zu verschieben, bewirkt rein
> gar nichts, und kann daher auch entfallen.

Korrekt. - Aus Compiler-Sicht bleibt dieser Shift wirkungslos, für den 
(menschlichen) Betrachter macht er aber ggf. das Verarbeitungsmuster 
offensichtlicher (alle Eingangssignale werden nach dem gleichen Schema 
behandelt, nämlich auf die passende Bit-Position geschoben), so wie eben 
auch die wirkungslosen Klammern die Lesbarkeit tendenziell erhöhen.

von Wolfgang (Gast)


Lesenswert?

Manfred V. schrieb:
> Was macht der oben aufgeführte Befehl aber im Einzelnen?

Das hat nichts speziell mit Arduino zu tun.
https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Bit-Shifting

von Ruminantia (Gast)


Lesenswert?

Wurde erst vor 2 Wochen durchgekaut, siehe dort: 
Beitrag "Bits in Register setzten (Schreibweise)"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.