Descomponer un long en bytes para enviarlo por XBee

Hola a todos,

Estoy desarrollando un proyecto de nodos de sensores con placas Arduino UNO y comunicaciones mediante XBee para enviar los datos a un coordinador, encargado de almacenarlos. Estoy usando la librería xbee-arduino.

La cuestión es que los diferentes valores los tengo que descomponer en bytes y almacenarlos en un array que es lo que XBee envía. Con varios valores int no he tenido problema alguno, pero para la presión atmosférica tengo que usar una variable de tipo long (4 bytes), pero a la hora de recomponerla en el coordinador, los 2 bytes más altos los pierdo, alterando el valor de la variable.

He hecho un sketch de prueba donde descompongo y vuelvo a componer diversos valores. Es el siguiente:

// Array que almacenará los datos a enviar mediante XBee
uint8_t payload[] = { 0 ,  0 , 0 ,  0 , 0 ,  0 , 0 ,  0 , 0 ,  0 ,
                     0 ,  0 , 0 ,  0 , 0 ,  0 , 0 ,  0 , 0 ,  0 ,
                     0 };

// Variables para almacenar los datos leidos de los sensores
float temperaturaFo, humedadFo, presionFo;
float temperaturaFd, humedadFd, presionFd;

// Variables para almacenar los datos como enteros
int nodoOrigenO, temperaturaIo, humedadIo;
int nodoOrigenD, temperaturaId, humedadId;
long presionLo, presionLd;

void setup() {
  Serial.begin(9600);
}

void loop() {

  // Simula las lecturas de los sensores
  temperaturaFo = 11.11;
  humedadFo = -22.22;
  presionFo = 933.33;

  temperaturaIo = temperaturaFo * 100;
  humedadIo = humedadFo * 100;
  presionLo = presionFo * 100;

  
  // Almacena los datos en el payload
  payload[0] = 101;                    // Identificación del nodo
  payload[1] = temperaturaIo >> 8 & 0xff;
  payload[2] = temperaturaIo & 0xff;       // 2 Bytes para la temperatura ambiente
  payload[3] = humedadIo >> 8 & 0xff;
  payload[4] = humedadIo & 0xff;           // 2 Bytes para la humedad ambiente
  payload[5] = presionLo >> 24 & 0xff;
  payload[6] = presionLo >> 16 & 0xff;
  payload[7] = presionLo >> 8 & 0xff;
  payload[8] = presionLo & 0xff;           // 4 Bytes para la presión atmosférica

  // Simula la reconstrucción de los datos en el coordinador
  nodoOrigenD = payload[0];
  temperaturaId = ( payload[1] << 8 | payload[2] );
  humedadId = ( payload[3] << 8 | payload[4] );
  presionLd = ( payload[5] << 24 | payload[6] << 16 | payload[7] << 8 | payload[8] );
                
  temperaturaFd = temperaturaId / 100.0;
  humedadFd = humedadId / 100.0;
  presionFd = presionLd / 100.0;
  
  while(1);
}

La cuestión es que al ejecutarlo, imprimiendo los valores por el puerto serie obtengo:

temperaturaFo es 11.11
humedadFo es -22.22
presionFo es 933.33
-----------------------
temperaturaIo es 1111
humedadIo es -2222
presionLo es 93333
-----------------------
-----------------------
payload[0] es 101
payload[1] es 4
payload[2] es 87
payload[3] es 247
payload[4] es 82
payload[5] es 0
payload[6] es 1
payload[7] es 108
payload[8] es 149
-----------------------
-----------------------
temperaturaId es 1111
humedadId es -2222
presionLd es 27797
-----------------------
temperaturaFd es 11.11
humedadFd es -22.22
presionFd es 277.97

Y si imprimo las variables presionFo y presionFd mostrándolas a nivel de bits obtengo:

10110110010010101
110110010010101

Con lo cual estoy perdiendo los dos byte más altos.

Creo que el error está a la hora de hacer los desplazamientos y los OR para recomponer el número, pero no soy capaz de averiguar por qué.

Muchas gracias a todos y un saludo.

Si se te hace complicado, esto debería hacertelo más sencillo:

byte* temperaturaVect = (byte*)&temperaturaIo;
byte* humedadVect = (byte*)&humedadIo;
byte* presionVect = (byte*)&presionLo;

Así; temperaturaVect, humedadVect y presionVect se convierten en vectores de cuatro elementos (bytes en este caso); los cuales en conjunto representan el valor de esas variables.

Ya con eso lo único que resta es realizar las operaciones de vector con vector necesarias...

Muchas gracias por tu respuesta Lucario448

Al final he conseguido hacerlo cambiando la línea:

presionLd = ( payload[5] << 24 | payload[6] << 16 | payload[7] << 8 | payload[8] );

Por la línea:

presionLd = ( (long) payload[5] ) << 24 | ( (long) payload[6] ) << 16 | ( (long) payload[7] ) << 8 | payload[8];

Pero la verdad, no sé por qué antes no funcionaba y ahora sí...

Porque ahora le dices al compilador que cada elemento es un long o sea de 32 bits y antes lo hacia como int

Si no le pones el (long) y especificas debidamente el compilador asume int siempre.