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
0x7fd
Explanation 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 bit
Remark: 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'.)