SODAQONE How to read the uploaded Data

Hey Everyone,

I’ve uploaded the universal tracker code on my SODAQONE beta board from March.
The trackers seems to work pretty good as long as you keep the original settings in place.

I’ve connected it to the KPN thingpark and get the following data readout in the wlogger:

MType : UnconfirmedDataUp

Flags : ADR : 1, ADRAckReq : 0, ACK : 0

Mac (hex) :

Data (hex) : e5319257ff206f55f31e2d64ab02ffff09009005ff

AirTime (s) : 1.64659

LRR[0806033C](RSSI:-97 SNR:7.25 ESP:-97.7495)
LRR[080603E1](RSSI:-121 SNR:-10.75 ESP:-132.101)
LRR[08060312](RSSI:-121 SNR:-13 ESP:-134.212)

The Data (hex) converted to DEC using (
gives the following Decimal number:


On the Sodaq Universal Tracker Github page it says that the data should read as follows:

LoRa Frame content

Description Length
Epoch Timestamp long (4)
Battery voltage (between 3 and 4.5 V) uint8 (1)
Board Temperature (degrees celcius) int8 (1)
Lat long (4)
Long long (4)
Altitude (MSL in meters below sea level is set to FFFF) uint16 (2)
Speed (SOG * 100 km/h) uint16 (2)
Course (COG) uint8 (1)
Number of satellites uint8 (1)
Time to fix (seconds, FF = no fix, in that case the above position is the last known) uint8 (1)
Plus 0 - 3 of the following 10 bytes:
Previous fix (seconds ago, FFFF means longer than) uint16 (2)
Lat long (4)
Long long(4)

I’m new to converting HEX data etc. So all help is welcome.
Right now I can’t find the GPS coordinates within the data.
How do you all read and convert this data?
Is there an easy way to convert it with a PHP script for on my server?

Thanks so much in advance!

it’s little Endian byte order

In your Hex code, the lat = 6f55f31e and long 2d64ab02 convert to Little endian order makes:

0x1ef3556f and

convert that to decimal:
long = 51.9263599
lat = 4.4786733

Now I know your location :slight_smile:


Rotterdam is great:)

Thank you for your help!

I created a very simple (quick and dirty) program to convert the data coming from the SodaqOne. See also

package com.clueless.sodaqone;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;

import lombok.extern.slf4j.Slf4j;

 * @author milo
public class Main {
    // Amsterdam Amstel train station
    // Lat : 52.3460135, 52° 20' 45.649"
    // Long:  4.9177772,  4° 55'  3.998"
    private static final String DEFAULT_DATA = "D170A3574A33275E331FAC64EE023F0002000005FF";

     * @param args - String[]
    public static void main(String[] args) {

        String data = DEFAULT_DATA;

        Integer timeStamp = Integer.reverseBytes(new Long(Long.parseLong(data.substring(0, 8), 16)).intValue());
        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(timeStamp, 0, ZoneOffset.UTC);
        dateTime = LocalDateTime.ofInstant(dateTime.toInstant(ZoneOffset.UTC), ZoneId.of("Europe/Amsterdam"));
        log.debug("Timestamp: {}", dateTime);

        int voltage = Integer.parseInt(data.substring(8, 10), 16);
        log.debug("Voltage: {}", 3.0 + voltage / 100.0);
        int temperature = Integer.parseInt(data.substring(10, 12), 16);
        log.debug("Temperature: {}", temperature);
        showCoord("lat", data.substring(12, 20));
        showCoord("lon", data.substring(20, 28));

    private static void showCoord(String type, String coordString) {
        Integer coord = Integer.reverseBytes(new Long(Long.parseLong(coordString, 16)).intValue());
        int coordDegrees = coord/10000000;
        int coordMinutes = new Double((coord/10000000.0 - coordDegrees) * 60).intValue();
        BigDecimal coordSeconds = new BigDecimal(((coord/10000000.0 - coordDegrees) * 60 - coordMinutes) * 60).setScale(3, RoundingMode.HALF_UP);
        log.debug("{}: {}, {}° {}' {}\"", type, coord/10000000.0, coordDegrees, coordMinutes, coordSeconds);

Enjoy, Milo