Feeble signal comes from Aladin is amplified to gain the RS232C voltage level by an OP amp in electronics of the DIY interface (or the Uwatec interface --- MSDOS version). Since the OP amp needs +Vcc and -Vss, PC must supply both. In order to do this, two flags in the register of UART should be changed to
DTR = 1 negate ('space' in RS232C terminology)and
RTS = 0 assert ('mark').(N.B. DTR and RTS are negative logic.)
Aladin sends 2050 bytes of data to PC at
19200 baud, 8 bits, No parity and 1 stopbit,when either of the following condition is met:
UUU\0(three ASCII character U's followed by one null character). Now it is easy to distinguish garbage and data; the sequence "UUU\0" marks the starting point.
After the sequence "UUU\0", Aladin always sends 2046 bytes of dive data. At PC side, each byte (8 bits) in the received data is in reversed bit order, that is, if
received bit order from Aladin: b_0 b_1 b_2 b_3 b_4 b_5 b_6 b_7then
ordinary bit order of PC: b_7 b_6 b_5 b_4 b_3 b_2 b_1 b_0.We must rearrange every byte before proceeding further data processing.
There are last two bytes of "check sum" for error checking; 2045th byte and 2046th byte. Algorithm for calculating the check sum will be explained later.
The 2046 bytes from Aladin are divided into four parts:
Address Description ============================================== 0x000 | (1) Depth Profile ring buffer 0x5ff ---------------------------------------------- 0x600 | (2) Logbook ring buffer 0x7bb ---------------------------------------------- 0x7bc | (3) Settings Section 0x7ef ---------------------------------------------- 0x7f0 | (4) Current Status 0x7fdExplanation for each part follows.
(1) Depth Profile ring buffer
The beginning of the oldest profile chunk can be found as follows: Start from the address stored in "end of profile ring buffer" (0x7f6--0x7f7) of the part (4), and search higher address direction for a byte 0xff. The mark 0xff designates the oldest beginning.
A profile data block begins with the byte 0xff, and end with just before another 0xff or the address of "end of profile ring buffer." The layout of a profile is:
Offset Description ==================================================== 0 Constant 0xff (marks the beginning) 1--22 Information for decompression Note 1: Aladin Nitrox (not O2) has extra two bytes. This is turned out to be the following memory map shifts by two bytes. Note 2: Aladin O2 has extra three bytes. This is turned out to be the following memory map shifts by three bytes. 1: Ambient temperature when this dive starts (at 1.25m) [1] / 4 degrees (Celsius). Note: This value is not surface temperature nor air temperature. The measurement is done when this dive starts, so it is not reached to stable state. 2--3: Tissue 1 ([3]*256 + [2]) kidney 4--5: Tissue 2 ([5]*256 + [4]) stomach, bowels, liver, central nervous system 6--7: Tissue 3 ([7]*256 + [6]) central nervous system, liver, stomach, bowels 8--9: Tissue 4 ([9]*256 + [8]) skin 10--11: Tissue 5 ([11]*256 + [10]) skin, muscles, heart 12--13: Tissue 6 ([13]*256 + [12]) muscles 14--15: Tissue 7 ([15]*256 + [14]) muscles, joints, bones, fat 16--17: Tissue 8 ([17]*256 + [16]) fat, joints, bones, rest 18-- higher nibble of 19: Microbubble danger in the arterial circulation ([19] & 0xf0)*16 + [18] 0x000 - 0x010: Level 0 0x011 - 0x080: Level 1 0x081 - 0x100: Level 2 0x101 - 0x280: Level 3 0x281 - 0x480: Level 4 0x481 - 0x700: Level 5 0x701 - 0xa00: Level 6 0xa01 - 0xfff: Level 7 lower nibble of 19 --20: Intrapulmonary right-left shunt: Micro bubbles in the venous circulation migrate to the lungs, where they collect in the capillaries and obstruct the exchange of gas, and this effect is termed. ([19] & 0x0f)*256 + [20] 21-- higher nibble of 22: Estimated skin cool at dive start (([22] & 0xf0)*16 + [21])/64 > 30.7 : Level 0 >= 28.0 : Level 1 >= 26.0 : Level 2 >= 24.0 : Level 3 >= 23.0 : Level 4 >= 22.0 : Level 5 >= 21.0 : Level 6 < 21.0 : Level 7 lower nibble of 22: Always zero (Begin Nitrox only 23: Two times of CNS O2 rest saturation percentage at dive start. Aladin shows this value in 5% units as floor(([23] + 4) / 10) * 5, where floor(x) means the maximum integer not exceeding x. For example if [23] = 56 (28 %) then Aladin shows it as 30 %. (Begin Aladin Nitrox (not O2) only 24: Upper nibble: Max ppO2 warning of this dive 0x0*: 1.20 (bar) 0x1*: 1.25 (bar) 0x2*: 1.30 (bar) 0x3*: 1.35 (bar) .... 0x8*: 1.60 (bar) .... (ppO2 value should not be set higher than 1.60 bar) 0xf*: 1.95 (bar) Lower nibble: Nitrox O2 mix 0x*0: 21% O2 0x*1: 22% O2 0x*2: 24% O2 0x*3: 26% O2 .... 0x*f: 50% O2 End Nitrox (not O2) only) (Begin Aladin O2 only 24: Nitrox O2 mix [24] % 25: Upper nibble: bit7: higher bit of Work load (vvO2 max) of this dive bit6: lower bit 3: very high (2.50 l/min O2) 2: high (2.25 l/min O2) 1: medium (2.00 l/min O2) 0: low (1.75 l/min O2) bit5: higher bit of SCR sensitivity of this dive bit4: lower bit 3: sensitive (1) 2: | (0) 1: | (-1) 0: insensitive (-2) Lower nibble: Max pp02 warning of this dive 0x*0: 1.20 (bar) 0x*1: 1.25 (bar) 0x*2: 1.30 (bar) 0x*3: 1.35 (bar) .... 0x*8: 1.60 (bar) .... (ppO2 value should not be set higher than 1.60 bar) 0x*f: 1.95 (bar) End O2 only) End Nitrox only) 23-- Body of depth profile; a word (16 bits) data for depth + warnings in every 20 seconds, a byte (8 bits) data for decompression in every one minute. (*) 23--24 upper 10bits --- depth at 0:00:20 (hour:min:sec) lower 6bits --- warnings at 0:00:20 25--26 upper 10bits --- depth at 0:00:40 lower 6bits --- warnings at 0:00:40 27--28 upper 10bits --- depth at 0:01:00 lower 6bits --- warnings at 0:01:00 29 decompression information at 0:01:00 (Aladin O2 has extra one byte, which represents 02 mix %, here) (repeat from above (*) to here as many times) A depth is stored as [upper 10bits] * 10 / 64 (m). For example, the depth at 0:00:20 can be calculated as (([23] * 256 + [24]) >> 6) * 10 / 64 (m). Each bit of warning (lower 6bits) is bit 5: transmit error of air pressure (always 1 unless Air series), bit 4: work too hard (Air series only), bit 3: ceiling violation of deco stop, bit 2: ascent too fast, bit 1: remaining bottom time too short; 5 min to reserved bar [0x7de] (default: 40 bar). (Air series only), bit 0: deco stop. A decompression information of every minute is: Level of physical effort (min 0 -- max 7) ("Air" computer estimates it from air consumption; Uwatec applied this estimation procedure for the patent. Other computer sets it to Level one in underwater and to zero when surfacing.) bit 6: higher bit bit 5: | bit 4: lower bit Estimated skin cooling bit 7: cold level decrement by one bit 3: cold level increment by one Level of micro bubble danger in the arterial circulation (min 0 -- max 7; if this value is not less than 2 then Aladin enters in "Atn" mode) bit 2: higher bit bit 1: | bit 0: lower bitRemark: If a dive is too long for the ring buffer, then the data will be dropped except for first part filling the buffer (i.e., first about 216 minutes part only remains).
(2) Logbook ring buffer
A logbook consists of a 12 bytes block. The position of the newest logbook is stored in "offset for the newest logbook data" (0x7f4) of part (4). The 12 bytes are:
Offset Description ======================================= 0 bit7: high place diving flag: higher bit bit6: lower bit bit5: SOS mode bit4: work too hard (Air only) bit3: decompression violation bit2: figure of hundreds of bottom time bit1: repeated diving bit0: ascent warning too long Remark: high place diving flag (4 levels) represents (0) 0 m --- 900 m (0 ft --- 3000 ft) ambient pressure above 0.921875 bar (1) 900 m --- 1750 m (3000 ft --- 5700 ft) ambient pressure above 0.828125 bar (2) 1750 m --- 2700 m (5700 ft --- 8800 ft) ambient pressure above 0.73828125 bar (3) 2700 m --- 4000 m (8800 ft --- 13300 ft) ambient pressure below 0.62109375 bar 1 Bottom time (stored in binary coded decimal (BCD)). Remark: The figure of the number of hundreds (0 or 1) is stored in the previous byte. If a divetime exceeds 200 minutes, then divetime will be reset to 0 (e.g. divetime = 231 then stored-divetime = 31). 2--3 Maximum depth (([2] * 256 + [3])>>6 ) * 10 / 64 (m) Note: The lower 6 bits in [3] must be garbage, since Aladin seems to be using a 10 bits (not 16 bits!) A/D converter LSI located outside of the CPU. DataTrak and ROM program of Aladin, however, consider these garbage bits into account and adopt the formula: Maximum depth ([2] * 256 + [3]) * 10 / 4096 (m) Using this formula results in 0 to 0.2m over estimate of max depth, but I think discrepancies are very small :) (See also "Paladin FAQ" Q9). 4--5 Surface time in BCD (hours in [4] and minutes in [5]) (Note: The value is garbage unless repeated dive). 6 Total air consumption (bar) (always zero unless Air series). Note: If type of Aladin is Aladin Air ([0x7bc] == 0x1c) then total air consumption is in 20psi unit: [6] * 20 [psi]. 7--10 Entry time (the value is from 00:00 1 Jan, 1994 GMT) in unit of 0.5 seconds = [7] * 2^24 + [8] * 2^16 + [9] * 2^8 + [10]. 11 Water temperature [11] / 4 degrees (Celsius).
(3) Settings Section
0x7bc Type of Aladin: O2 Nitrox Air Name [0x7bc] = 0x40 no no yes Mares Genius 0x34 no no yes Aladin Air X 0x44 no no yes Aladin Air X 0xa4 yes yes yes Aladin Air X O2 0xf4 no yes yes Aladin Air X Nitrox 0x48 no no yes Spiro Monitor 3 Air 0x1c no no yes Aladin Air 0x1d no no no Spiro Monitor 2 Plus 0x3d no no no Spiro Monitor 2 Plus 0x1e no no no Aladin Sport 0x3e no no no Aladin Sport 0x1f no no no Aladin Pro 0x3f no no no Aladin Pro 0xff no yes no Aladin Pro Nitrox 0x1b no no no AIRE (Aladin Pro) Note 1: In year 2000, Uwatec renamed their products as follows (but the type codes shown above were not changed at all): New name Old name Aladin Pro Ultra Aladin Pro Nitrox Aladin Air Twin Aladin Air Aladin Air Z O2 Aladin Air X O2 Aladin Air Z Nitrox Aladin Air X Nitrox Aladin Air Z Aladin Air X Aladin Sport Plus Aladin Sport And computers of US divers Monitor series are OEMs of Spiro. Note 2: All Nitroxen (except O2) have ([0x7bc] & 0xf0) == 0xf0. The O2 has ([0x7bc] & 0xf0) == 0xa0. All Airs have ([0x7bc] & 0x0f) % 4 == 0. Note 3: 0x1b is the type code for a dive computer that I got at a junk shop. It seems to be compatible with Aladin Pro but the exact name is still unknown (since the name is not written on the casing). 0x7d2 bit7: higher bit of Work load (vvO2 max) (O2 only) bit6: lower bit 3: very high (2.50 l/min O2) 2: high (2.25 l/min O2) 1: medium (2.00 l/min O2) 0: low (1.75 l/min O2) bit5: higher bit of SCR sensitivity (O2 only) bit4: lower bit 3: sensitive (1) 2: | (0) 1: | (-1) 0: insensitive (-2) bit3: always 0 bit2: always 0 bit1: Beep (0: Off, 1: On) bit0: Unit (0: Metric, 1: Imperial) 0x7d3 Upper nibble: Premix reset after XX hours. (O2 only) [0x7d3] = 0x0*: 1 hour 0x1*: 2 hours 0x2*: 3 hours 0x3*: 4 hours 0x4*: 5 hours 0x5*: 6 hours 0x6*: 8 hours 0x7*: 10 hours 0x8*: 12 hours 0x9*: 14 hours 0xa*: 16 hours 0xb*: 18 hours 0xc*: 24 hours 0xd*: 36 hours 0xe*: 48 hours 0xf*: No reset Remark: The value is 0 unless Aladin O2 computer. Lower nibble: Maximum O2 partial pressure ppO2 (Nitrox only) ([0x7d3] & 0x0f) * 0.05 + 1.2 (bar) Remark: For non-Nitrox computers, always ([0x7d3] & 0x0f) = 6. 0x7de Reserve (Air series only) [0x7de] (bar) Remark: For non-Air computers, always [0x7de] = 40. 0x7e1 Constant 0x64: The value seems to be only used by DataTalk for DOS for compensating the full percentage (100 %) of battery, but not to be used by DataTalk for Windows. Thus, we can consider the value as a constant, and safely ignore it. 0x7eb Breath warning sensitivity (Air series only) Ranges are from 0x19 (insensitive) to 0x61 (sensitive). The following is correspondence between sensitivity values (say y) and the displayed values (say x) in DataTalk for Windows: y x [0x7eb] = 0x19: -12 0x1b: -11 0x1d: -10 0x1f: -9 0x21: -8 0x23: -7 0x25: -6 0x27: -5 0x2a: -4 0x2c: -3 0x2f: -2 0x31: -1 0x34: 0 (default: 0x33 or 0x34) 0x37: 1 0x3a: 2 0x3d: 3 0x41: 4 0x44: 5 0x48: 6 0x4c: 7 0x50: 8 0x54: 9 0x58: 10 0x5c: 11 0x61: 12 Remark 1: Some Aladins (including some Nitroxen) have default value 0x01. Remark 2: The above table is calculated by the formula y = rint((exp((x + 12) / 24) * k1 + k2) * 512), where the constants k1 = 0.140625 / (exp(1) - 1) and k2 = 0.048828125 - k1. 0x7ec Unknown (Always 0x0b). 0x7ed--0x7ef Serial number of the Aladin (does not match the 'external serial number' written on the casing). = [0x7ed] * 2^16 + [0x7ee] * 2^8 + [0x7ef] Comment: The 8 bits value X = [0x7ed] - [msb of 0x7ee] seems to be related to the manufacture date of Aladin as year = X / 6 + 1994; beginning of two months period = (X % 6) * 2 + 1;Other bytes are all unknown.
(4) Current Status
0x7f0 Remaining battery = [0x7f0] * 100 / 256 (percent) Note: The above formula is used by DataTalk for DOS. It seems that ROM program of Aladin uses a similar but different formula [0x7f0] * 99 / 255 (percent) for remaining battery. 0x7f1 lower nibble == 0 if battery is OK. lower nibble != 0 if battery is empty. 0x7f2--0x7f3 Total dive numbers this Aladin have experienced (initially every Aladin dives from 6 to 10 times at factory) = [0x7f2] * 256 + [0x7f3] 0x7f4 Offset for the newest logbook = (([0x7f4] + 36) % 37) * 12 + 0x600 Note: The value of [0x7f4] is normally in range from 1 to 37. But some Aladin Pro only when number of total dives is equal to 37 the value becomes 0!! 0x7f5 Number of dive profiles in the ring buffer = [0x7f5] (WARNING: Some older Aladin Pro has a bug in the byte; they have an error value of correct value plus one for this byte.) 0x7f6--0x7f7 End of profile ring buffer = (([0x7f6] + ([0x7f7] >> 1) * 256)) & 0x7ff Note1: Upper byte located in higher address and shifted 1 bit. The lsb of upper byte is garbage (always zero). (Yes, very strange. :) But it may caused by the hardware architecture of Aladin dive computer; SRAM for storing download data is located at I/O port of the CPU. ) Note2: Higher 4 bits of [0x7f7] are garbage, too. 0x7f8--0x7fb Current time of data acquisition (the time value is from 00:00 1 Jan, 1994 GMT) in unit of 0.5 seconds = [0x7f8] * 2^24 + [0x7f9] * 2^16 + [0x7fa] * 2^8 + [0x7fb]. Note: Since we cannot adjust the time of Aladin, this value has some discrepancy. 0x7fc--0x7fd Check sum Check sum is calculated as follows: Sum up every byte in dive data except the last two bytes (from [0x0] to [0x7fb]) as an unsigned character. Add it to 0x1fe. Take modulo 65536 (= 2^16). Then the result is unsigned 2 byte integer [0x7fd]*256 + [0x7fc]. (Remark: 0x1fe = 0xaa + 0xaa + 0xaa + 0, and 0xaa is the bit reverse of ASCII 'U'.)