True. Decimal 969 is hexadecimal 0x03C9, and when trying to put that into an 8 bits variable of type byte
, uint8_t
or int8_t
, you’d only be storing 0xC9, which is decimal 201. You’ll need a 16 bits variable, like of type uint16_t
or int16_t
, to store two bytes.
Where did you hear that? You cannot really send structs.
What will happen is that each value in the struct is sent, without any meta information about that struct. So for 4 struct values, each with 3 values, you’ll just get a payload that holds a number of bytes that somehow you need to translate back into 12 values, and eventually separate those into 4 objects each holding 3 values at the JavaScript side in TTN Console (or your own application). A struct like:
struct mesure {
uint16_t id_capteur;
int valeur;
int var_size;
};
…will yield 2 bytes (16 bits) for the first uint16_t
value, another 2 or 4 bytes for the second int
(depending on your Arduino version), and yet another 2 or 4 bytes for the third int
. So, I don’t understand why your logging shows 7 bytes. That makes no sense at all.
On an Arduino don’t use int
, but be specific about the number of bits you expect. Like with:
typedef struct {
uint8_t a; // single byte, unsigned, 0..255
int8_t b; // single byte, signed, -128..+127
int16_t c; // two bytes, signed, -32,768..+32,767
} Measurement;
// Reserve space for at most 5 measurements
Measurement measurements[5];
…the following 3 measurements will yield an application payload of 01 02 0300 04 FB FAFF 07 F8 F7FF
(when displayed as hexadecimal):
int count = 0;
measurements[count++] = {1, 2, 3};
// 8 bits decimal -5 = 0xFB, 16 bits decimal -6 = 0xFFFA
measurements[count++] = {4, -5, -6};
Measurement m;
m.a = 7;
// 8 bits decimal -8 = 0xF8
m.b = -8;
// 16 bits decimal -9 = 0xFFF7
m.c = -9;
measurements[count++] = m;
LMIC_setTxData2(1, (byte*)measurements, count * sizeof(Measurement), 0);
Note that multi-byte values are LSB (least significant byte first) in an Arduino, so your decoder needs to use LSB too. It also needs sign extension as JavaScript’s bitwise operators expect 32 bits. Something like:
function Decoder(bytes, port) {
var measurements = [];
while(bytes.length > 0) {
var m = {};
// Single byte, unsigned
m.a = bytes[0];
// Single byte, signed, with sign extension to get
// 32 bits for proper decoding of negative values:
m.b = bytes[1]<<24>>24;
// Two bytes, signed, LSB, with sign extension to get
// 32 bits for proper decoding of negative values:
m.c = bytes[2] | bytes[3]<<24>>16;
measurements.push(m);
// Discard the 4 bytes we just handled above:
bytes = bytes.slice(4);
}
return {
measurements: measurements
};
}
(If, like in your last example, each struct really only has a single value, then using structs is not making your node’s C++ code any more easy to read, and you’d better just use a single value. Not sure what you’re trying to do there, and too lazy to translate the French.)