Estoy tratando de enviar y recibir datos entre Raspberry Pi (usando programación C) y Arduino (usando Arduino IDE).
Según lo que puedo encontrar en Internet, me indica que ambos están en formato little endian.
Estoy enviando números enteros entre ellos usando una comunicación serial (RS232) con la biblioteca "RS-232 para Linux y Windows" en teuniz.net/RS-232
Según mi conocimiento, si ambos están en formato little endian, no necesito hacer ningún cambio en los bits. Sin embargo, en mi caso con los códigos a continuación, es necesario que cambie los bits leídos por Arduino. No estoy seguro de por qué necesito realizar el cambio de bits cuando ambos son little endian (para obtener los datos correctos). Sin más preámbulos....
Código C:
unsigned char buf[4]; int g = 100; memcpy(buf, (char*)&g, sizeof(int)); // port 24 for ttyACM0 if(RS232_SendBuf(24, buf, sizeof(int)) == -1) { // error processing here }código arduino:
long a[4]; long value = 0; void loop(){ if(Serial.available()>=4){ for(int i = 0; i < 4 ; i++){ a[i] = Serial.read(); } // Over here i need to shift the LSB of the byte received to the MSB of the long var until the MSB of byte becomes LSB of long var // i do not have the code which is faulty right now as its already past midnight and my group mates are already asleep so I will post again in the morning value += a[0]; value += a[1] << 8; value += a[2] << 16; value += a[3] << 24; Serial.println(value); // now it prints out 100 correctly value = 0; } }Agradecería toda ayuda! ¡Lo siento, todavía soy nuevo en C y endian!
ACTUALIZACIÓN: ¡Creo que sé por qué sucede lo anterior! ¡Por favor comente a continuación para informarme si mi suposición es correcta o incorrecta!
Estoy enviando un valor int de 170 en C. 170 es 0x000000aa en HEX. Cuando i memcpy (aquí es donde entra Little Endian), se almacena como aa 00 00 00 (LSB a MSB). Entonces, cuando obtenga el valor en arduino, definitivamente necesitaré hacer el cambio a medida que se lee un número entero de MSB a LSB (y debido a que no hay copia/lectura de memoria en arduino, no me importa ningún problema endian aquí).
Sin embargo, como Arduino es lento en el procesamiento (¡tiene muchas otras cosas para calcular!), ¿puedo hacer mi código C de tal manera que:
int g = 170; unsigned char buf[4]; // below line not needed anymore?? //memcpy(buf, (char*)&g, sizeof(long)); if(RS232_SendBuf(24, (char *)&g, sizeof(int)) == -1) { ... }¡Me gustaría saber más para poder aprender más! ¡Parece que me equivoqué al principio cuando hice esta pregunta!
Tu código me parece bien (no lo he ejecutado).
0xaabbccdd .dd , cc , bb , aa . Se enviarían por cable en ese orden.a también contendría dd , cc , bb , aa .value como (dd << 0) + (cc << 8) + (bb << 16) + (aa << 24) , dando 0xaabbccdd .Está analizando un valor little endian de 32 bits, no un valor big endian. El primer byte termina en los bits menos significativos; el último byte termina en los bytes más significativos.
Si estuviera convirtiendo un búfer que contenía un valor big endian, el código se vería así:
uint8_t a[4]; int value = 0; for ( int i = 0; i < 4; ++i ) { value << 8 * i; // shift everything over one byte value += a[ i ]; // add the next byte to the LSByte }¿Ves la diferencia?