power-poler
Goto Top

Int to byte

Guten Tag,

Habe gerade ein kleines Problem, welches mir Kopfzerbrechen bereitet.
Und zwar will ich über den Pi an einen der GPIO pins einen byte ausgeben, mittels digitalWrite(x,x)
Die ganze zeit verwende ich hierfür 8 int werte (0 und 1 halt) was natürlich nicht Sinn der Sache ist.

Ist es möglich einen int (oder einen char) in eine bit folge umzuwandeln, also 1 byte?

also sowas zu schreiben pseudocode:
void WRITE(int a){
 digitalWrite(DATAPIN, inttobit(a,7);
 digitalWrite(DATAPIN, inttobit(a,6);
 digitalWrite(DATAPIN, inttobit(a,5);
 digitalWrite(DATAPIN, inttobit(a,4);
usw...

habe es mit dem Dateitype byte versucht, den kennt aber gcc nicht (oder ich mache etwas falsch).

oder Denke ich gerade in die völlig falsche Richtung?
Schonmal Danke für eine Antwort.
Mit freundlichen Grüßen
Power-Poler

Content-Key: 311143

Url: https://administrator.de/contentid/311143

Printed on: April 23, 2024 at 19:04 o'clock

Member: rubberman
Solution rubberman Jul 28, 2016 at 17:32:28 (UTC)
Goto Top
Hallo Power-Poler,

vielleicht verlinkst du mal auf eine Funktionsreferenz dieser digitalWrite() Funktion, die du nutzen möchtest. Irgendwie scheinst du tatsächlich Bit und Byte zu verwechseln. I.d.R. hat ein char eine Breite von 8 Bit, was in deinem Fall auch einem Byte entspricht. Einen separaten Datentyp kennt weder der C noch C++ Standard.
Das bitweise auseinanderdröseln einer Zahl machst du mit dem & Operator.
zahl & 1 für das niedrigste Bit
zahl & 2 für das zweitniedrigste Bit
zahl & 4 ...
...
zahl & 128 für das höchste Bit
... eben in Zweierpotenzen.

Grüße
rubberman
Member: pelzfrucht
pelzfrucht Jul 28, 2016 at 19:22:40 (UTC)
Goto Top
Hi,

vielleicht verlinkst du mal auf eine Funktionsreferenz dieser digitalWrite() Funktion
Ich vermute mal es handelt sich um die digitalWrite Funktion der WiringPi API.

Soweit ich verstehe möchtest du ein Byte über einen Pin bitweise ausgeben.
Das funktioniert so nicht direkt, du müsstest dafür selber eine Funktion schreiben die dies tut.
digitalWrite() dient zum Schalten eines GPIO Pin und nicht zur (formatierten) Datenausgabe.

Du könntest eine Funktion schreiben die alle 8 Bits nacheinander auf dem Pin ausgibt. Beispiel:

I (6ms)
0 (6ms)
I (6ms)
I (6ms)
0 (6ms)
0 (6ms)
0 (6ms)
I (6ms)

(Der Byte und millisekunden Wert ist jetzt willkürlich gewählt, aber um das zu verdeutlichen face-wink)

Viele Grüße
pelzfrucht
Member: rubberman
rubberman Jul 28, 2016 at 19:37:15 (UTC)
Goto Top
Ich vermute mal
Ja, das könnte sein.

void WRITE(int num)
{
  for (int i = 8; i; )
    digitalWrite(DATAPIN, (num >> --i) & 1);
}
Welche Möglichkeiten du auf dem Pi hast, um ein Delay von ein paar ms einzubauen, weiß ich nicht.

Grüße
rubberman
Member: pelzfrucht
pelzfrucht Jul 28, 2016 at 20:32:20 (UTC)
Goto Top
Welche Möglichkeiten du auf dem Pi hast, um ein Delay von ein paar ms einzubauen, weiß ich nicht.

Ich schätze mal ganz normal

#include <unistd.h>
[...]
usleep(20*1000);

(20 mikrosekunden * 1000 = 20 millisekunden)

Viele Grüße
pelzfrucht
Member: rubberman
rubberman Jul 28, 2016 at 21:14:13 (UTC)
Goto Top
ganz normal
Joa, "ganz normal" wäre ANSI C. Das ist dann wohl eher POSIX face-wink

Grüße
ruberman
Member: pelzfrucht
pelzfrucht Jul 28, 2016 at 21:24:33 (UTC)
Goto Top
Joa, "ganz normal" wäre ANSI C. Das ist dann wohl eher POSIX face-wink

Ups face-smile

Aber trifft in dem Fall trotzdem zu.

Er kann per sleep / usleep verzögern.
Alternativ kann er aber auf seine genutzte WiringPi API zurückgreifen. Dann wäre es:

void delay (unsigned int howLong)
void delayMicroseconds (unsigned int howLong)
Für Sekunden bzw. Mikrosekunden.

Viele Grüße
pelzfrucht
Member: Friemler
Friemler Jul 28, 2016, updated at Jul 29, 2016 at 06:15:49 (UTC)
Goto Top
[EDIT]

back-to-topACHTUNG!!!

Besser nicht verwenden. Siehe hier.

[/EDIT]


Hallo Power-Poler,

in C gibt es einige nettes Features, die für Dein Problem optimal geeignet sind: Bitfelder und Unions. Teste mal folgendes:

typedef struct _bitfield
{
  unsigned int bit0: 1;
  unsigned int bit1: 1;
  unsigned int bit2: 1;
  unsigned int bit3: 1;
  unsigned int bit4: 1;
  unsigned int bit5: 1;
  unsigned int bit6: 1;
  unsigned int bit7: 1;
} bitfield;


typedef union _serializer
{
  unsigned char byteValue;
  bitfield      bitsValue;
} serializer;



void WRITE(unsigned char byteValue)
{
  serializer s;
  
  s.byteValue = byteValue;
  
  digitalWrite(DATAPIN, s.bitsValue.bit0);
  digitalWrite(DATAPIN, s.bitsValue.bit1);
  digitalWrite(DATAPIN, s.bitsValue.bit2);
  digitalWrite(DATAPIN, s.bitsValue.bit3);
  digitalWrite(DATAPIN, s.bitsValue.bit4);
  digitalWrite(DATAPIN, s.bitsValue.bit5);
  digitalWrite(DATAPIN, s.bitsValue.bit6);
  digitalWrite(DATAPIN, s.bitsValue.bit7);
}


Gruß
Friemler
Member: rubberman
rubberman Jul 28, 2016 at 22:49:31 (UTC)
Goto Top
Hallo Friemler.

Bitfelder und Unions
Hab ich mir nicht getraut vorzuschlagen. Keine Ahnung in welcher Reihenfolge die Bits auf einem Pi im Speicher liegen ...

Grüße
rubberman
Member: Friemler
Friemler Jul 29, 2016 at 06:28:30 (UTC)
Goto Top
Moin rubberman,

hast Recht, Bitfelder sind auch eines dieser Desaster in C was die Portierbarkeit anbelangt. Da ich C nur für Hobbyzwecke auf der PC-Plattform verwende, verliere ich solche Dinge öfter aus dem Blick.

[OT]
@Frank: Ich wollte meinem obigen Posting eigentlich etwas mehr Text zur Erklärung hinzufügen, warum man den Code nicht benutzen sollte. Aber 14,28% Änderungsquote war beim Speichern schon wieder zu viel, da das Posting bereits von rubberman kommentiert wurde (da war doch schonmal was... face-wink ). Diese Schwelle finde ich viel zu niedrig, vor allem da es sich nur um eine Ergänzung des bestehenden Textes gehandelt hätte.
[/OT]

Gruß
Friemler
Member: Power-Poler
Power-Poler Jul 29, 2016 updated at 07:30:45 (UTC)
Goto Top
@rubberman

Vielen Dank. Genau so was habe ich gesucht. Macht genau was es soll.
Member: rubberman
rubberman Jul 29, 2016 at 15:44:37 (UTC)
Goto Top
Hallo Friemler

Bitfelder sind auch eines dieser Desaster in C was die Portierbarkeit anbelangt.
Das hat eigentlich nichts mit C zu tun, sondern mit der Implementierung auf dem jeweiligen OS.
Workaround wäre, die union mit byteValue 1 zu initialisieren und anschließend zu prüfen ob die 1 sich im höchsten oder im niedrigsten Bit wiederfindet.
Da ich C nur für Hobbyzwecke auf der PC-Plattform verwende
Da bist du nicht der einzige face-wink

Grüße
rubberman