2010-06-13 11 views
6

primer usuario, ¡Hola chicos!Operadores de bit a bit y conversión de un int a 2 bytes y viceversa

Así que con suerte alguien puede ayudar ... Mi fondo es php, por lo que ingresar la palabra de lowend cosas como, char es bytes, que son bits ... que es valores binarios ... etc toma algo de tiempo para familiarizarse con ;)

Lo que intento hacer aquí se envía algunos valores de una placa de Ardunio a openFrameWorks (ambos son C++).

Lo que hace este script actualmente (y funciona bien para un sensor, podría añadir) cuando se le pregunta por los datos que se enviarán es ..

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

Al parecer esta es la forma más confiable de obtener los datos a través de .. Así que ahora que se envía a través del puerto serie, los bytes se añaden a una cadena de carbón y convierten de nuevo por ..

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

Así que para recapitular, estoy tratando de conseguir 4 sensores valor de los datos (que im suponiendo que será 8 de esas impresiones en serie?) y tener en t num_01 - num_04 ... al final de todo.

Im suponiendo que esto (como con casi todo) podría ser bastante fácil para alguien con experiencia en estos conceptos ..

Cualquier ayuda sería muy apreciada. Gracias

+1

Desde su pregunta , no está del todo claro con qué tiene problemas ... Si el código anterior funciona, entonces puede, como usted dice, hacer más operaciones de Serial.print y obtener sus valores de otros índices en bytesReadString en el otro extremo. ¿Qué es eso que no funciona? – tgdavies

Respuesta

7

escribir una función para el envío de los datos (Me he librado de sus variables temporales, ya que no añaden mucho valor) Resumen:

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

Ahora se puede enviar fácilmente los datos que desee :

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

Guau, eso limpia bastante bien ... ¡Está funcionando perfectamente ahora, gracias chicos! Comparado con lo que tenía antes (cuando no estaba funcionando) realmente no estoy seguro de por qué no funcionaba (creo que podría haber estado enviando datos incorrectos, lo cual me estaba desbaratando) .. Si esto es el resultado del uso de stackoverflow , ¡Vuelvo enseguida! – aKiwi

+1

@aKiwi: la mejor manera de agradecer al autor de la respuesta que se ajusta a sus necesidades es marcar la respuesta como aceptada :) –

+0

ah me preguntaba qué hacer. gracias, estaba tratando de votarlo (al parecer, un poco más de reputación;) – aKiwi

1

Simplemente envíelas una después de la otra.

Tenga en cuenta que el controlador serie le permite enviar un byte (8 bits) a la vez. Un valor entre 0 y 1023 inclusive (que se parece a lo que está obteniendo) se ajusta en 10 bits. Entonces 1 byte no es suficiente. 2 bytes, es decir, 16 bits, son suficientes (hay algo de espacio extra, pero a menos que la velocidad de transferencia sea un problema, no necesita preocuparse por este espacio desperdiciado).

Por lo tanto, los dos primeros bytes pueden transportar los datos de su primer sensor. Los siguientes dos bytes llevan los datos para el segundo sensor, los siguientes dos bytes para el tercer sensor y los dos últimos bytes para el último sensor.

Le sugiero que utilice la función que R Samuel Klatchko sugirió en el lado del envío, y con suerte puede resolver lo que debe hacer en el lado de recepción.

+0

Muchas gracias por la información en el lado de las cosas en serie, aclara algunas cosas en mi cabeza. Gracias – aKiwi

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

Ese código no hará lo que usted espera.

Cuando cambia un carácter sin signo de 8 bits, pierde los bits adicionales.

11111111 << 3 == 11111000 

11111111 << 8 == 00000000 

es decir, cualquier carácter sin signo, cuando se desplaza 8 bits, debe ser cero.

se necesita algo más a esto:

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])); 

que podría obtener el mismo resultado a partir de:

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

Si el orden de los bytes es OK. Debería funcionar en Little Endian (x86 o x64), pero no en Big Endian (PPC, Sparc, Alpha, etc.)

0

Para generalizar el código "Enviar" un poco -

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)); 
} 
Cuestiones relacionadas