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).
/* 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):
0A222D150707D2010000000000000000841A0604FE0C3E247F4500F07F45A5A50000
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:
0A222D150707CE is time per the time structure. Thus the following:
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:
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.
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.
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).
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.
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.
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.
The final two bytes of the record are for future use and are currently set to 0000h.
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.