5 years, 11 months ago.

Packaging Data for LoRa Transmission - C++


I have spent way too much time in other languages and I am having difficulty understanding how data is being "formated" to different data types prior to transmitting said data through LoRa. The following piece of code is from the mDot examples (Team MultiTech https://os.mbed.com/teams/MultiTech/).

uint16_t light; std::vector<uint8_t> tx_data;

get the latest light sample and send it to the gateway light = lux.getData(); tx_data.push_back((light >> 8) & 0xFF); tx_data.push_back(light & 0xFF); logInfo("light: %lu [0x%04X]", light, light); send_data(tx_data);

I understand that data needs to be formatted for transmission, but the how, what, specifically why, and syntax I am a little confused about. I am assuming this is a unsigned 8 bit integer vector, but what is the _t? Why the ">>8" and the "&0xFF" in the push_back method? It appears that it's limiting 8 bits per vector entry? But whats up with the (what appears to be) address (0xFF)? Why is push_back called twice with two slightly different parameters? The string in logInfo get's published to a console/SSH output and it appears there are some formatting characters stuck in there...what is the purpose of that?

Is it common that LoRa transmissions are all assumed to be vectors of uint8? I was using nodeRed and it will interpret the vector into what appears to be a hexadecimal, though I have no code to tell it how to convert the payload (assuming a vector of uint8_t).

I have looked at a lot of forums and C++ learning sites, but I am having a difficult time finding something similar to what is being done in this code (and other similar projects with LoRa comms). I know sometimes it requires knowing what the name of the process/method is to effectively search for instructions/tutorials, so even a keyword would be helpful.

Ultimately, I might need to transmit other data types and possibly large data sets and I will need to have an excellent understanding so I can effectively send, receive, and manipulate the data server side.

Thanks and please feel free to verbally berate me :) .


1 Answer

5 years, 11 months ago.


Let's assume that your light data is 50536 in decimal, which corresponds C4B4 (0xC4B4) in hexadecimal. Which is also two bytes (16 bits = uint16_t)

In payload of the LORA data is sent as uint8_t = 8 bits. So you need to split this 2 bytes data (C4B4) to two bytes (8 bits)

So bit shifting operator ">>" and "<<" is necessery. In here right shift operator is used (>>)

tx_data.push_back((light >> 8) & 0xFF) right shift the data light 8 bits and makes it 1 byte (0xFF is not important here. But the programmer used it to be sure that data is 8 bits). This line gives you C4 value

tx_data.push_back(light & 0xFF) this line gives you B4 value.

PErfect information is given here:

https://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit https://www.cprogramming.com/tutorial/bitwise_operators.html http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/shift.html

Also you can test on calculator in windows by changing mode to the programmer...


Thanks, this make sense.

So what happens when you have a decimal number that has values right of the decimal point? Say we record a voltage of 1.236 volts? How does that get converted into a logical hex value?

posted by Nicholas Hornyak 12 Jul 2018


I generally multiply the float value by 10 100 1000 ... to convert integer. And then divide it again on server side. The reason is float values are 4 bytes.

For example. 1.236 volt x 1000 = 1236

255 < 1236 < 65535... so yu need 2 bytes . And on the receiver side divide to 1000

Thats my method...

posted by Kamil M 12 Jul 2018