file: gilwnd24_sdhc.html
23 Oct 2020

SDHC CARD STORAGE FORMAT - GILWND24

*** IMPORTANT!! NOTE NUMERIC FORMAT CHANGE FROM OLDER ASIMET MODULES BELOW ***

The following describes the data storage and record format of SDHC memory cards used in ASIMET instrumentation with Ver5.xx and later firmware (on Microchip PIC24-based microcontroller hardware).

Three files are created when the SDHC card is initialized for the ASIMET module. ASGILxxx.ID (where xxx is the last 3 digits of the module serial number) contains ID information from the module. This includes the firmware revision - the SDHC card will NOT store data from the module if the firmware version in the PIC24 FLASH does not match the firmware version written to the ASGILxxx.ID file; a warning is issued in the L (status command). ASGILxxx.INF is a user-writeable file of up to 500 characters of arbitrary text, accessed via the SDOK command. ASGILxxx.DAT is the file containing the one-hour records of module data.


Description of WND data file

The SDHC data file (ASGILxxx.DAT) consumes as much of the SDHC card as needed to store the one-hour data records. Each record is 1296 bytes long, containing the date and time written, record size in ASCII as well as integer, 60 minutes of Wind Velocity East data, 60 minutes of Wind Velocity North data, 60 minutes of Wind Speed data, 60 minutes of Wind Speed Max data, 60 minutes of Last XY direction data, 60 minutes of Last Compass direction data, 60 minutes of Tilt X data, 60 minutes of Tilt Y data, 60 minutes of Gill Speed of Sound, 60 minutes of Gill Temperature, some engineering data, firmware and PC board revision numbers (from CODE), serial number from EEPROM, some spare bytes, a flag which is set to 0xA5A5 when the record is written, and a 2 byte CRC of the previous 1294 bytes (currently not used, set to 0 always). The actual C language struct is reproduced here to show the format of the stored image. Most values are packed.

   /* this is the WND data record structure, 1296 bytes */
   struct WND_record
       {
       struct time_type time1;      /* 8 bytes of time */
       char record_size[6];         /* record size ascii */
       unsigned short rsize;        /* record size */
       short Ve[60];   		/* 60 minutes of Vel East data */
       short Vn[60];   		/* 60 minutes of Vel North data */
       unsigned char WSpeed[60];	/* 60 minutes of WS data */
       unsigned char WSMax[60];	/* 60 minutes of Max WS data */
       unsigned short LastXYDir[60];	/* 60 minutes of Last Gill XY direction data */
       unsigned short LastCompass[60];	/* 60 minutes of Last Compass data */
       char TiltX[60];              /* 60 minutes of Tilt X data */
       char TiltY[60];              /* 60 minutes of Tilt Y data */
       float GillSOS[60];        /* 60 minutes of Speed of Sound */
       float GillTemp[60];          /* 60 minutes of Gill Temperature */
       float v3_3,vbat;  			/* rail & battery in volts DC, once per hour */
       float brdtemp;  				/* board temperature in degC, once per hour */
       char version[24];			/* firmware version (from code) */
       char brdversion[16];		/* PC board version (from code) */
       char modser[4];      /* first 3 digits of module serial number (from eeprom) */
       char senser[8];      /* up to 7 digits of sensor serial number from (eeprom) */
       unsigned char spare[12];
       unsigned short used;     /* set to 0xA5A5 upon record write */
       unsigned short wnd_CRC;  /* CRC of previous 1294 bytes */
       };

   /* time structure */
   struct time_type
      {
      unsigned char sec;
      unsigned char min;
      unsigned char hour;
      unsigned char dow;   /* day of week - Sunday = 1 - not used */
      unsigned char day;
      unsigned char mon;
      unsigned int year;
      };

Note that time structure is NOT ANSI-compatible.


Data packing - this is the packing code from the GILWND24 instrument

     /* every minute, from 0 to 59, pack and store the record */

     /* Vel data 0 to +/- 49.99 m/s packs to 0 to +/- 4999 */
     WND_data.Ve[t_time.min] = (short)(vel_east * 100);
     WND_data.Vn[t_time.min] = (short)(vel_north * 100);

     /* speed data from 0 to 50.0 m/s packs to 0 to 250 (.2 resolution ) */
     WND_data.WSpeed[t_time.min] = (unsigned char)(speed_avg * 5);
     WND_data.WSMax[t_time.min] = (unsigned char)(speed_max * 5);

     /* XY Dir (like vane) data from 0 to 359.9 packs to 0 to 3599 */
     WND_data.LastXYDir[t_time.min] = (unsigned short)(sonic_deg * 10);

     /* compass data from 0 to 359.9 packs to 0 to 3599 */
     WND_data.LastCompass[t_time.min] = (unsigned short)(comp_deg * 10);

     /* tilt data from 0 to 25.0 packs to +127/-128 (.2 resolution) */
     WND_data.TiltX[t_time.min] = (char)(tilt_x_avg * 5);
     WND_data.TiltY[t_time.min] = (char)(tilt_y_avg * 5);

     /* Gill Speed of Sound and Temperature (not packed) */
     WND_data.GillSOS[t_time.min] = gill_SOS;
     WND_data.GillTemp[t_time.min] = gill_Temp;

Data is written to the SDHC card immediately following the acquisition of all data at the rollover to the 59th minute of each hour. This is reflected in the time stamp on each record, typically 1 second into minute 59. The "Last" values of compass and XY direction are taken from the last 5 second vector averaging period of the minute, just prior to writing the record.


*** IMPORTANT NOTE - CHANGE FROM OLDER ASIMET MODULES ***

The byte order of the numeric values stored by the ASIGIL24 firmware used on Microchip PIC24-based module boards is the same as Intel-based PC's. That is, a long integer (4 bytes) or short integer (2 bytes) stored by a PIC24-based module will be LS byte first in memory, and floats are stored with mantissa first. This is opposite to older ASIMET firmware for module boards based on Dallas Semi DS87C530 micros. See the float storage format below.


The "used" flag value is used to simplify finding the end of valid records the .DAT file; as each record is written, the "used" flag is set to A5A5h to provide a distinct pattern to search on for good records.


The CRC is NOT IMPLEMENTED.


"float" 4 byte values are IEEE-754 single-precision float.

Storage format for these float values is as follows:

      byte addr      +0         +1           +2         +3
      contents     MMMMMMMM   MMMMMMMM    EMMMMMMM   SEEEEEEE

            where S => Sign bit;  1 = negative,  0 = positive
                  E => Exponent (2's comp) with offset 127 (decimal)
                  M => 23-bit normal mantissa (highest bit always 1 and
                           therefore not stored)