Skip to main content

Rohdatenformat

Der Dataserver speichert die Logdaten intern auf einem 16MB Flash-Chip. Um hier Daten von ca. 2 Wochen bei einer Aufzeichnungsfrequenz von 1Hz unterbringen zu können, sind die Daten äußerst dicht gepackt.

Die Datei startet mit einem 256 byte langen Header.

Die ersten 128 byte enthalten in Textform die Zeichenkette "PKC datafile" sowie die Softwareversion und die Seriennummer des Geräts.

Der Binärteil des Headers beginnt ab Offset 128 und enhtält derzeit folgende Daten:

 Offset  Länge  Bedeutung 
1281Größe eines "full snapshot"
1291Größe eines "incremental snapshot"

 

Der Rest der Datei besteht aus 256 byte langen Seiten eine Seite ist aufgebaut wie folgt:

Offset Größe Daten 
029Full snapshot
29++20Inc snapshot
2542Checksum

 

/* these are the structures for data storage in the spi memory chip.
we only have 16 megs of space, so we have to pack data as tight as possible.

we use:
 - 4 bytes for timestamp
 - 4 bytes for latitude and longitude each ( signed, divide by 9313225,74615478515625 to get degrees )
 - 2 bytes for depth ( unit: cm )
 - 2 bytes for heading and log speed/kts, where v = round( log10( 1+speed ) * 100 ) * 360 + hdg
 - 2 bytes for wind dir and wind speed/kts, where v = round( log10( 1+speed ) * 100 ) * 360 + dir
 - 2 bytes for cog and sog/kts, where v = round( log10( 1+sog ) * 100 ) * 360 + cog
 - 9 bytes for gyro and accel (1.5 bytes for each axis)

*/

struct SFullSnapshotData
{
    UINT32 timestamp;
    UINT32 lat;
    UINT32 lon;
    UINT16 depth;
    UINT16 hdg_logspeed;
    UINT16 wind_dir_speed;
    UINT16 cog_sog;
    unsigned char gyro_accel[9];
};
// The above struct is written to the beginning of every 256 byte page

struct SIncSnapshotData
{
    UINT16 depth;
    UINT16 hdg_logspeed;
    UINT16 wind_dir_speed;
    UINT16 cog_sog;
    unsigned char gyro_accel[9];
    unsigned char lat_lon[3];
};
/* the above struct is written intra-page. It is written at a frequency of 1 Hz, so we do not need a timestamp.
furthermore, the latitude and longitude are relative to the previous entry, 12 bits each. */

// checksum algorithm

uint16_t CalcPageChecksum( unsigned char *pPage )
{
    union
    {
        uint16_t uiChecksum;
        struct
        {
            uint8_t uiSum;
            uint8_t uiXor;
        };
    } ucs;

    ucs.uiChecksum = 0;
    for( int i=0; i<254; i++ )
    {
        ucs.uiSum += pPage[i];
        ucs.uiXor ^= pPage[i];
        ucs.uiXor = ucs.uiXor << 1 | ucs.uiXor >> 7;
    }
    return ucs.uiChecksum;
}