Sending Firmware Version Over LoRa

May 13, 2018

There was a case where We need to keep the server informed about the version of firmware that is running on our devices. The devices are not directly connected to the internet, instead they send data through LoRa hence sending the version information can be a little tricky.

We used LoRaWAN instead of LoRa PTP because it is well-defined protocol by LoRa Alliance and is easy to set up on both the edge and the cloud. LoRaWAN limits the maximum amount of payload send over the air depending on your ISM band and data rate. We stick with DR3 on AS923 band which limits the payload size up to 50 bytes. Yes you read it right.

What makes it tricky is we can’t just send the version info using string format. Actually WE CAN use string and send it through LoRa but that would be expensive for us. For example, our firmware version is 1.1.2 and if we use string format, we send 5 bytes amount of data. It’s not that big, right? It’s small enough to be sent over LoRa. But in our case, we send a lot of data via LoRa, not only the version information. The minimum data rate limits the size up to 11 bytes, if we only send the 5 bytes of version information in a single batch it would be a waste of another 6 bytes. So the challenge is how can we send version information along with sensors data through LoRa efficiently.

Our CEO decided to encode the version using the following function (in javascript)

function version(major, minor, patch) {
    return (2 ** major) * (3 ** minor) * (5 ** patch);
} 

The idea is we send the version information in unsigned integer 16 bits form. To achieve that, we calculate the powers of the first three prime numbers with major number as the power for 2, minor as the power for 3, and patch as the power of 5. We cut the 3 bytes from our example and we can fill the remaining 9 bytes for another sensor data if we use the minimum 11 bytes size limit.

That’s on the edge side, on the server side we decode the number using prime factorization algorithm. I made a javascript library for that, it’s called version-transform (I couldn’t find any better name :( ) and you can install it using npm or yarn.

So that’s how it’s done. We encode the version string to an unsigned 2 bytes integer and decode it back to version string on the server side. Can we improve? Sure, we’ll figure it out!