file: vm2rec53.html
14 Feb 2003

Data Record Format - Firmware Version 3.xx

The current data record format provides for storage of data at each averaging interval. Data records are stored in the FLASH card beginning at 20000H (the first 128K bytes of the FLASH card are handled separately for system information - see System Info Record Format below).

34 bytes binary are currently stored per data record in fixed format. (Note that this may change in the future). Storage is based upon 2 'C' language structures shown here:

/* this is the VM data record structure - 34 bytes */
struct VM2_record
   struct time_type time1;      /* 7 bytes of time */
   unsigned char mux_parm;      /* which option parameter in this record */
   short vel_e;  		/* vel east data 0 - 655.35 cm/sec */
   short vel_n;   		/* vel north data 0 - 655.35 cm/sec */
   short rotor1;                /* rotor 1 counts 0 - 65535 */
   short rotor2;                /* rotor 2 counts 0 - 65535 */
   unsigned short compass;      /* compass direction in
                                      12 ls bits 0 - 359.9 degrees ;
                                      ms bit = tilt x sign,
                                      2nd ms bit = tilt y sign */
   unsigned char tiltx;         /* tilt x 0 - 25.5 degrees */
   unsigned char tilty;         /* tilt y 0 - 25.5 degrees */
   short sea_temp;              /* sea temperature (standard option) -5 to +55 degrees */
   float res_therm;             /* corrected thermistor resistance */
   float opt_parm;              /* reading of a/d channel indicated in rec_mux */
   unsigned short used;         /* set to 0xA5A5 upon record write */
   unsigned short vm2_CRC;      /* CRC of previous bytes */

/* a 7 byte structure to hold the time values from the real time clock. */
struct time_type
   unsigned char hour;
   unsigned char min;
   unsigned char sec;
   unsigned char day;
   unsigned char mon;
   unsigned int year;

Records may be dumped via XMODE command (very slow!) or by directly reading the removable FLASH storage card in a PC.

A typical 34 byte binary record looks like this (in HEX-ASCII):


Wow! So now what!

First, note the following:
All integers are 2 bytes, stored MS byte first
All floats are IEEE Single-Precision, stored LS byte first

From the strucures above, note that time is stored first, so:

Bytes 0 - 6

0A222D150707CE is time per the time structure. Thus the following:

Byte 7

The next byte, 01, is the multiplexed parameter number. A/D channels 1 to 5 are multiplexed into the record one at a time (i.e. if the record interval is 60 seconds, a record is written each minute, and one of the A/D channels is included). Thus, if the mux parameter number is:

In the example, 01 indicates that the value of A/D Channel 2 is stored later in this record.

Bytes 8 - 23

The next 8 bytes (16 characters) are all 0 since the VM was sitting in a lab when this record was stored. Each value is a signed 2-byte integer, stored MS byte first (same as the 'year' above).

The first 4 of these 8 bytes are the Ve (bytes 8,9) and Vn (bytes 10,11) values. These values are packed to save storage space, and must be divided by 50 to recover the original velocity in cm/sec. Thus a value of 01F2 would unpack to 498 decimal divided by 50 = 9.96 cm/sec

The next 4 of these 8 bytes are rotor counts. Rotor 1 counts are stored in bytes 12,13. Rotor 2 counts are stored in bytes 14,15. The rotor nearest the endcap is #2.

VMCM2 Rotor Calibration:
There are 16 counts per revolution of the rotor, with 2.34375 cm flow per count.

NOTE: this is approximately 4 times more resolution than the original VM cal constant of 9.36 cm/rotor count.

Bytes 16 - 19

The next 2 bytes (16,17) represent compass direction from 0 to 359.9 degrees; the value is a packed value once again. The value is stored as an unsigned integer MS byte first. To recover the compass direction in degrees, use the 12 lsbits only and divide by 10.
- In the current example, the compass value is 841A - the 12 lsbits are 41A = 1050, divided by 10 = 105.0 degrees.

The upper 4 bits of byte 16 are used to hold the sign values for the 2 tilts. The MSbit is the sign for Tilt X (1 = negative), and the 2nd MSbit is the sign for Tilt Y (1 = negative).

Byte 18 holds the value of Tilt X from 0 to 25.5 degrees. Divide the value by 10 to recover the absolute Tilt X value, then if Tilt X sign above is 1, make the result negative. In the current example, Tilt X is 0Dh = 13, divided by 10 = 1.3, but the MSbit of compass is a 1, so the Tilt X = -1.3 degrees.

Byte 19 holds the value of Tilt Y from 0 to 25.5 degrees. Divide the value by 10 to recover the absolute Tilt Y value, then if Tilt Y sign above is 1, make the result negative. In the current example, Tilt Y is 04h = 4, divided by 10 = 0.4 degrees, and the 2nd LSbit of compass is 0, so Tilt Y remains positive.

Bytes 20 - 21

The Sea Temperature option reads directly to the VMCM2 in a floating point value; it is stored as a signed integer in the range +/- 32767. The actual temperature in degrees C is recovered by dividing the signed integer value by 100. In the current example, the value is FE0C = -500, divided by 100 = -5.00 (this is less than sea water should ever read, and in fact is a value stored when no Sea Temperature option is attached, or the option has failed).

Bytes 22 - 25

The Sea Temperature option measures water temperature with a YSI 30k thermistor; to aid in later data analysis, raw thermistor resistance is also returned by the option and logged. The resistance, returned by the temperature option as a float with 1 decimal place, is currently stored as a float value.

Bytes 26 - 29

The current A/D channel, as indicated by the mux'ed parameter number in byte 7 of the record, is store as an IEEE Single-Precision floating point number. The value is stored LS byte first (this is OPPOSITE the storage format for integers!). The value in the example, for A/D channel 2, is stored as 00F07F45. This is interpreted as 457FF000, which per IEEE spec is -5.000 (default value if no temperature option is included in the VMCM2).

Battery Voltage is monitored by A/D channel 5. The value can range from 0 to 25.5 VDC, and is stored in a single byte (0-255). Recover the actual value by dividing by 10; for example, 71h = 113, divided by 10 ==> 11.3 VDC.

Battery Current is monitored by A/D channel 4. The value can range from 0 to 255 MA, and is stored in a single byte (0-255). For example, 11 ==> 11 MA; Note that when the instrument is running on external power, current is not monitored, and will be reported as zero.

Bytes 30 - 31

These bytes are used to indicate that a record in FLASH storage has been written by the VMCM2. It is used internally by the instrument firmware to, for example, determine the next available record location upon power-up. These bytes should always be A5A5h in a used record, and FFFFh in an unused portion of the FLASH card.

Bytes 32 - 33

The final two bytes of the record are for future use and are currently set to 0000h.

System Info Record Format - Firmware Version 3.xx

Various pieces of status and system information are currently stored in fixed format in the first 128K byte FLASH "page". This information serves to "tag" the FLASH card and the raw file dumped from it. Most of this page is empty (it's the smallest increment that can be erased) except for the first several hundred bytes. (Note that this may change in the future).

Each line stored and displayed is based upon the 'C' language structure shown here:

/* this structure contains important system stuff */
struct PCMCIA_sys
   struct time_type time2;      /* 7 bytes of time */ (see  struct time_type above)
   unsigned short interval;	/* record interval */
   char version[32];		/* firmware version */
   char modinf[16];		/* model info */
   char modser[8];		/* serial number */
   char caldat[8];		/* config date */
   char tpod_version[32];	/* TPOD firmware version */
   char tpod_modinf[16];	/* TPOD model info */
   char tpod_modser[8];		/* TPOD serial number */
   char tpod_caldat[8];		/* TPOD config date */
   char tpod_thermistor[32];	/* TPOD thermistor info */
   char spare[5];
   char comment[128];		/* comment field */
   unsigned short sys_CRC;      /* CRC of previous 254 bytes */

Except for the binary time values and record interval, all the other info is ASCII that is taken from EPROM or EEPROM. The EEPROM info is all free-format and, except for the 128 byte comment field, can be arbitrarily changed via the UOK commands on the VMCM2 and VMTPOD boards. See the VMCM2 UOK command or VMTPOD UOK command for details. The comment contained in the 128 byte comment field may be entered when an FW command is issued to write the system info into the FLASH card.

The system info record can be read using the FD command or as hex values using the FB command at Block 1 or by reading the FLASH card directly on a Linux notebook PC.