Problem in sending negative values in the payload

Like @kersing already wrote: no. The above “cast” only tells the compiler that you know what you’re doing, and that whatever is in the variable payload can be handled as if it were of type uint8_t. That happens to be what this LMIC function expects, but your code has declared payload to be of a different type:

byte payload[16];

Even though that is really the same (both uint8_t and byte define 8 bits unsigned integer values, from 0 thru 255), you need to tell the compiler that you know it’s okay. You could also use:

uint8_t payload[16];
...
// No need to cast now:
LMIC_setTxData2(1, payload, sizeof(payload), 0);

So what’s your code doing? I’ve added some comments:

// Each val holds the sum of 200 samples.
float val[6] = {0};
...
// Arduino int is 16 or 32 bits, depending on the board.
int value[8];
...
// Take the average of the 200 samples and multiply by 100, to
// send 12.35 as 1235. Add +1000 to always send positive values,
// hence assuming the average is larger than -1000. For a 16 bits
// unsigned integer, which supports 0 thru 65,535, this allows
// for actual averages between -10.00 and +645.35. To allow for,
// e.g., -300.00 thru +355.35, one would add 30,000 instead.
value[3]= (val[3] / 2.0) + 1000.0;
...
// Send MSB first
payload[6] = highByte(value[3]);
// ...and LSB next
payload[7] = lowByte(value[3]);

Like I linked to earlier, for the last two lines, you could also use:

// MSB
payload[6] = value[3]>>8;
payload[7] = value[3];

All looks good so far. You’re using two bytes to send each value, MSB first. And you’re not sending negative values, so no magic needed in the decoder.

However, while decoding, you’re using:

var LC = (bytes[6]<<15) | bytes[7];
...
return {
  ...
  LC: (LC-1000)/100,
  ...
}

That’s wrong: why shift the MSB 15 bits to the left when concatening the two bytes into a single value? I’d say this should read:

var LC = bytes[6]<<8 | bytes[7];

(No parentheses needed either. It’s okay to add them, of course.)

If in the Arduino code you would not add the 1,000, so if you would actually be sending signed 16 bits values, then in a JavaScript decoder you would need:

var LC = bytes[6]<<24>>16 | bytes[7];

See Decrypting messages for dummies - #4 by arjanvanb that I linked to before.

2 Likes