What is the maximum number of characters I can send with LMiC?

In computer memory and when transmitting, everything is just a sequence of bits (and 8 bits are then called a byte). That might be hard to understand at first, but you’ll need to read and re-read “Working with Bytes” (and the links it refers to) until you do understand.

When you think you understand, you should be able to see:

  • When (erroneously) using human-readable text, the value 34.51:
    • is stored as the 48 bits 00110011 00110100 00101110 00110101 00110001 00000000 which includes a trailing NUL-character for a null-terminated string,
    • which is the same the decimal ASCII codes 51, 52, 46, 53, 49 and 0,
    • which is the same as hexadecimal 0x33 34 2E 35 31 00,
    • and further below you’ll see that using Serial.println((char *)mydata) will show “34.51” for the above ASCII codes.
  • When (nicely) using an integer number, the value 34.51 can be multiplied by 100 to get 3451, which:
    • is stored as the 16 bits 00001101 01111010,
    • which is the same as 0x0D 7B,
    • and (erroneously) using Serial.println((char *)mydata) might then print a new line (for ASCII code 0x0D) followed by { (for 0x7B), followed by whatever is in memory until it finds the first 0x00 NUL-character, meanwhile printing garbage for all bytes that cannot be converted to ASCII.

Using the (char *)mydata above you’re telling the compiler that the program knows that what is currently in the memory buffer mydata is in fact human-readable text (and not, for example, some image, or a PDF document, or a simple number). The only reason the program knows, is because it has stored the value there itself (like by using strcpy earlier).

So, (char *) does not convert anything; it is already human-readable text in memory. And when trying to use a built-in function such as Serial.println to show its contents, then your program needs to share that knowledge with the compiler, by prefixing mydata with (char *). (Here, (char) tells the compiler it’s human-readable text, and * gives the compiler a “pointer” to the memory location, which is simply what Serial.println expects.) That line would then print garbage if it was in fact not human-readable text. But as it apparently shows the value you expected, you’re still storing human readable text in memory (and so you would also be sending that to TTN).

Just removing the {...} does not suffice. JSON is one of the many human-readable formats. Changing {"x": 123.45, "y": 45.678} into, e.g., 123.45,45.678 would still be a human-readable format, wasting bytes when sending to TTN.

2 Likes