2010-06-13 7 views
6

Erstbenutzer, Hallo Leute!Bitweise Operatoren und konvertieren ein int zu 2 Bytes und wieder zurück

Also hoffentlich kann jemand helfen .. Mein Hintergrund ist php also Eingabe des Wortes von lowend Sachen wie, Char ist Bytes, die Bits sind .. was binäre Werte .. etc dauert einige Zeit, um den Hang zu bekommen ;)

Was ich hier versuchen will, ist ein paar Werte von einem Ardunio-Board nach openFrameWorks geschickt (beide sind C++).

Was dieses Skript gegenwärtig der Fall ist (und funktioniert gut für einen Sensor wie ich hinzufügen möchte), wenn für die Daten gefragt gesendet werden soll ..

int value_01 = analogRead(0); // which outputs between 0-1024 

unsigned char val1; 
unsigned char val2; 

//some Complicated bitshift operation   
    val1 = value_01 &0xFF; 
    val2 = (value_01 >> 8) &0xFF; 

    //send both bytes 
    Serial.print(val1, BYTE); 
    Serial.print(val2, BYTE); 

Anscheinend ist der zuverlässigste Weg, um die Daten über des Erhaltens .. Also jetzt, dass sie senden über die serielle Schnittstelle sind, werden die Bytes in ein char-String hinzugefügt und zurück umgewandelt ..

int num = ((unsigned char)bytesReadString[1] << 8 | (unsigned char)bytesReadString[0]); 

So zu rekapitulieren, im bekommen 4 Sensoren im wert von Daten versuchen (die im angenommen, es werden 8 dieser Seriendrucke sein?) und in t num_01 - num_04 ... am Ende von allem.

Im vorausgesetzt, dies (wie bei den meisten Dingen) könnte in diesen Konzepten mit Erfahrung für jemanden ganz einfach sein ..

Jede Hilfe wäre sehr geschätzt. Dank

+1

Aus Ihrer Frage Es ist nicht ganz klar, was Sie haben Probleme mit ... Wenn der obige Code funktioniert, dann können Sie, wie Sie sagen, mehr Serial.print-Operationen und holen Sie Ihre Werte aus anderen Indizes in die BytesReadString um das andere Ende. Was funktioniert nicht? – tgdavies

Antwort

7

Schreiben Sie eine Funktion zu abstrahieren Senden der Daten (ich habe von temporären Variablen losgeworden, weil sie nicht viel Wert hinzufügen):

void send16(int value) 
{ 
    //send both bytes 
    Serial.print(value & 0xFF, BYTE); 
    Serial.print((value >> 8) & 0xFF, BYTE); 
} 

Jetzt können Sie leicht alle Daten, senden Sie wollen :

send16(analogRead(0)); 
send16(analogRead(1)); 
... 
+0

Wow, das reinigt die Sache ziemlich schön .. Es funktioniert perfekt jetzt, danke Jungs! Verglichen mit dem, was ich vorher hatte (als es nicht funktionierte) bin ich wirklich nicht sicher, warum es nicht funktionierte (ich denke, dass ich schlechte Daten gesendet habe, die mich muckten) Wenn dies das Ergebnis der Verwendung von Stackoverflow ist , Ich komme wieder! – aKiwi

+1

@aKiwi: beste Weise, dem Autor der Antwort zu danken, die Ihrem Bedarf entspricht, ist, die Antwort als angenommen zu markieren :) –

+0

ah fragte sich, was zu tun ist. Danke, versuchte, ihn zu wählen (brauche anscheinend mehr Ansehen) – aKiwi

1

Senden Sie sie einfach nacheinander.

Beachten Sie, dass Sie mit dem seriellen Treiber ein Byte (8 Bits) gleichzeitig senden können. Ein Wert zwischen 0 und 1023 einschließlich (was aussieht wie das, was Sie bekommen) passt in 10 Bits. Also 1 Byte ist nicht genug. 2 Bytes, d. H. 16 Bits, sind genug (es gibt etwas zusätzlichen Platz, aber wenn die Übertragungsgeschwindigkeit kein Problem ist, brauchen Sie sich um diesen verschwendeten Platz keine Gedanken zu machen).

So können die ersten zwei Bytes die Daten für Ihren ersten Sensor übertragen. Die nächsten zwei Bytes tragen die Daten für den zweiten Sensor, die nächsten zwei Bytes für den dritten Sensor und die letzten zwei Bytes für den letzten Sensor.

Ich schlage vor, Sie verwenden die Funktion, die R Samuel Klatchko auf der Sendeseite vorgeschlagen, und hoffentlich können Sie herausfinden, was Sie auf der Empfängerseite tun müssen.

+0

Vielen Dank für die Informationen auf der seriellen Seite der Dinge, klärt etwas in meinem Kopf auf. Vielen Dank – aKiwi

0
int num = ((unsigned char)bytesReadString[1] << 8 | 
       (unsigned char)bytesReadString[0]); 

Dieser Code wird nicht das tun, was Sie erwarten.

Wenn Sie ein 8-Bit-Zeichen ohne Vorzeichen verschieben, gehen die zusätzlichen Bits verloren.

11111111 << 3 == 11111000 

11111111 << 8 == 00000000 

d. H., Alle vorzeichenlosen Zeichen, wenn sie um 8 Bits verschoben sind, müssen null sein.

Sie brauchen etwas mehr wie folgt aus:

typedef unsigned uint; 
typedef unsigned char uchar; 

uint num = (static_cast<uint>(static_cast<uchar>(bytesReadString[1])) << 8) | 
      static_cast<uint>(static_cast<uchar>(bytesReadString[0])); 

Sie könnten aus dem gleichen Ergebnis:

typedef unsigned short ushort; 
uint num = *reinterpret_cast<ushort *>(bytesReadString); 

Wenn die Byte-Reihenfolge in Ordnung ist. Sollte funktioniert auf Little Endian (x86 oder x64), aber nicht auf Big Endian (PPC, Sparc, Alpha, etc.)

0

dem "Senden" Code ein wenig zu verallgemeinern -

void SendBuff(const void *pBuff, size_t nBytes) 
{ 
    const char *p = reinterpret_cast<const char *>(pBuff); 
    for (size_t i=0; i<nBytes; i++) 
     Serial.print(p[i], BYTE); 
} 

template <typename T> 
void Send(const T &t) 
{ 
    SendBuff(&t, sizeof(T)); 
}