Protocol and Data Structure of Uwatec Aladin Dive Computers

Copyright (C) 1999,2000 ITO Hisashi

This information is based on an investigation of me, ITO N. Hisashi (kuro at neko.ac) about data received from my Uwatec Aladin Pro. Never inquire of Uwatec about the contents of the document. There are many unknowns and also may be many errata. So if you find something new to the note, please let me know.

Remark: Infomation on the Net was very useful to complete this note, especially it was owed to the webpages of GLorensen at aol.com, S5dive at compuserve.com and etc. (I'm very sorry if I omit to mention someone else).

This document can be redistributed and/or modified freely. This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY.

    Edition History ---
             Created 1999.10.9 by ITO Hisashi (kuro at neko.ac)
            Modified 1999.12.8 by ITO Hisashi (kuro at neko.ac)
                               #  Correct some typos.
            Modified 1999.12.9 by ITO Hisashi (kuro at neko.ac)
                               #  not FIFO but ring buffer
            Modified 1999.12.17 by ITO Hisashi (kuro at neko.ac)
                               #  clarify some points
            Modified 2000.01.10 by ITO Hisashi (kuro at neko.ac)
                               #  bottom time: figure of hundreds fixed
            Modified 2000.01.14 by ITO Hisashi (kuro at neko.ac)
                               #  SOS bit etc. fixed
            Modified 2000.01.19 by ITO Hisashi (kuro at neko.ac)
                               #  last two bytes are fake!
            Modified 2000.01.20 A friend of mime told me.
                               #  Type of Aladin etc.
            Modified 2000.02.06 Ing. Helmut Oberrauter tell me what happens
                               in SOS mode or in extra ordinary long dive.
            Modified 2000.02.29 A friend of mine told me.
                               Used air in logbook part should be multipled
                               by 1.37634409 if the computer is normal Aladin 
                               Air (not AirX nor AirX Nitrox etc.).
            Modified 2000.03.01 Doug Cunningham 
                               Air O2 has extra bytes in profile, etc...
            Modified 2000.03.20 Geoff Illing
                               Type 0x3e is Aladin Sport
            Modified 2000.03.21 Sebastian Krolzig
                               Higher 4 bits of profileend are garbage!
            Modified 2000.07.20 A friend of mine told me: Type 0x3D is 
                               Spiro Monitor 2 Plus.
                               Comment on serial number added (thanks to
                               Zdenek Sraier).
            Modified 2000.09.29 Christian Frining
                               New info on Nitrox and O2


Hardware and Protocol

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, 8bit, No parity and 1 stopbit,
when either of the following condition is met:
  1. Just before "logbook mode" turned into "1st logbook mode", after touching moist fingers to the two contacts of Aladin.
  2. SOS mode (every one minute).
Thus, from PC side we cannot initiate the data transfer. When Aladin is not sending valid data (or Aladin is not connected), RD line of RS232C is read as garbage from PC side. Then, how can we do to receive valid data? For this purpose, before sending the 2046 bytes of dive data, Aladin sends a consecutive four characters sequence
                       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_7
then
  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.


Data Structure of Received Data

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) Information 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  (Aladin Nitrox has extra two
            bytes.  This is turned out to be the following memory map 
            shifts by two bytes for Aladin Nitrox. And Aladin O2 has extra
            three bytes.  This is turned out to be the following memory
            map shifts by three bytes for Aladin O2.)
            1:      ?
            2--3:   Tissue 1  ([3]*256 + [2])
            4--5:   Tissue 2  ([5]*256 + [4])
            6--7:   Tissue 3  ([7]*256 + [6])
            8--9:   Tissue 4  ([9]*256 + [8])
            10--11: Tissue 5  ([11]*256 + [10])
            12--13: Tissue 6  ([13]*256 + [12])
            14--15: Tissue 7  ([15]*256 + [14])
            16--17: Tissue 8  ([17]*256 + [16])
            18--22: ?
           (Begin Nitrox only
            23:     Restsaturation
                    0x00-0x05:  0% 6 steps
                    0x06-0x0f:  5% 10 steps
                    0x10-0x19: 10% 10 steps
                    0x1a-0x23: 15% 10 steps
                    0x24-0x2d: 20% 10 steps
                    0x2e-0x37: 25% 10 steps
                    0x38-0x41: 30% 10 steps
                    0x42-    : 35% 10 steps
            24:     Nitrox O2 mix
                    0x60: 21% O2
                    0x61: 22% O2
                    0x62: 24% O2
                    0x63: 26% O2
                    ....
                    0x6f: 50% O2
            End Nitrox only)
           (Begin O2 only
            23:    ??
            24:    Nitrox O2 mix [24] %
            25:    ??
            End O2 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 on 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 40 bar.  (Air series only),
              bit 0: deco stop.

            A decompression information of every minute is:
              Level of work (min 0 -- max 7)
              (Air estimates it from air consumption, others from depth variation)
                  bit 6: higher bit
                  bit 5:    |
                  bit 4: lower bit
              Estimated skin cooling
                  bit 7: cold decrement by 10%
                  bit 3: cold increment by 10%
              Level of micro bubble danger (min 0 -- max 7)
              (if this value is not less than 2 then Aladin enters 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 m ---  900 m (0)
                900 m --- 1700 m (1)
               1700 m --- 2700 m (2)
               2700 m --- 4000 m (3).
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] are garbage).
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) Information Section

0x7bc         Type of Aladin:
                    
                             Nitrox Air  Name
              [0x7bc] = 0x00 no     yes  (unknown)             
                        0x14 no     yes  (unknown)
                        0x1c no     yes  Aladin Air
                        0x1d no     no   Spiro Monitor 2 Plus
                        0x1e no     no   Aladin Sport
                        0x1f no     no   Aladin Pro
                        0x24 no     yes  (unknown)
                        0x34 no     yes  Aladin AirX
                        0x3d no     no   Spiro Monitor 2 Plus
                        0x3e no     no   Aladin Sport
                        0x3f no     no   Aladin Pro
                        0x40 no     no   Mares Genius
                        0x41 no     no   (unknown)
                        0x44 no     yes  Aladin AirX
                        0x48 no     yes  Spiro Monitor 3 Air
                        0x73 no     no   (unknown)
                        0xa4 yes    yes  Aladin AirX O2
                        0xbc no     no   (unknown)
                        0xf4 yes    yes  Aladin AirX Nitrox
                        0xff yes    no   Aladin Pro Nitrox

Note: 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 Ultra        Aladin Pro Nitrox
  Aladin Air Twin     Aladin Air
  Aladin AirZ O2      Aladin AirX O2
  Aladin AirZ         Aladin AirX
  Aladin Sport Plus   Aladin Sport

0x7d2         bit7: ?
              bit6: ?
              bit5: ?
              bit4: ?
              bit3: ?
              bit2: ?
              bit1: Beep (0: Off, 1: On)
              bit0: Unit (0: Metric, 1: Imperial)
0x7d3         Maximum O2 partial pressure (Nitrox only)
              [0x7d3] * 0.05 + 1.2 (bar)
0x7de         Reserve (Nitrox only)
              [0x7de] (bar)
0x7eb         Sensitivity (Nitrox only)
              Sensitivity ranges from 25 (-12: insensitive) to 97 (+12: Sensitive).
              Normal is 52 and the range is nonlinear.
              [0x7eb] = 0x00-0x1a: 1
                        0x1b-0x1c: 2
                        0x1d-0x1e: 3
                        0x1f-0x20: 4
                        0x21-0x22: 5
                        0x23-0x24: 6
                        0x25-0x26: 7
0x7ec         Constant (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] 
              is seems to be related to the manifacture date of Aladin as
                 year = X / 6 + 1994;
                 two months period begin = (X % 6) * 2 + 1; 
              (But I'm not sure...)
Other bytes are all unknown.

(4) Current Status

0x7f0         Remaining battery
              = [0x7f0] * 99 / 255 (percent)

0x7f1--0x7f3  Total dive numbers this Aladin have experienced
              (initially every Aladin dives 6 times at factory)
              = [0x7f1] * 65536 + [0x7f2] * 256 + [0x7f3]

0x7f4         Offset for the newest logbook
              = ([0x7f4] - 1) * 12 + 0x600

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. :-))
              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].

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'.)

Back to the top page of Aladin data transfer tools.


Any questions or comments should be made to

ITO N. Hisashi <kuro at neko.ac>
(Please convert the above 'at' to @ sign, this is for spamproof.)