Uwatec 製ダイビングコンピュータ Aladin シリーズの通信方式とデータ構造

Copyright (C) 1999,2000 いとーひさし

このドキュメントは、 いとーひさし (kuro at neko.ac) が自分の Aladin Pro を使って独自 に解析したものに基づきます。 Uwatec に問い合わせることを禁じます。 間違っている部分や、まだわかっていないことは多数あります。 なにか新しいことがわかったら、是非お知らせ下さい。

付記: このノートを作るにあたり、ネット上の情報が大変に役に立ちました。 特に、GLorensen at aol.com さんと S5dive at compuserve.com さんのページ などに記載されていた情報が大変有用でした(これ以外のページもあちこち 参照しましたが、ここでいちいちそれらを挙げることはしません。ごめんなさい)。

この文書の再配布および改変は自由に行なってください。 この文書は、役に立つであろうという期待のもとで配布されていますが、 その内容などに関して保証するものではありません。

    更新履歴 ---
             1999.10.9 いとーひさし (kuro at neko.ac) により作成
             1999.12.9 いとーひさし (kuro at neko.ac) 変更
                         #  FIFO ではなくってリングバッファという
             1999.12.17 いとーひさし (kuro at neko.ac) 変更
                         #  文章のおかしいところを直す
             2000.01.10 いとーひさし (kuro at neko.ac)変更
                         #  logbook で潜水時間の百の位に関する記述の追加
             2000.01.14 いとーひさし (kuro at neko.ac)変更
                         #  SOS bit の位置などの確定
             2000.01.19 いとーひさし (kuro at neko.ac)変更
                         #  最後の2バイトはゴミ
             2000.01.20 このノートを見た方が、情報をくださいました。
                         #  特に、アラジンのタイプのコード
             2000.02.06 Ing. Helmut Oberrauter さんが、SOSモード
                        のデータをくださいました。その結果、200分を
                        超えるような長い潜水でどうなるかがわかりました。
             2000.03.01 Doug Cunningham さんが、Aladin Air と O2 に
                        関する情報をくださいました。
             2000.03.20 Geoff Illing さんが、Type 0x3e が Aladin Sport
                        であることを知らせてくださいました。
             2000.03.21 Sebastian Krolzig さんが、Aladin Air では、
                        profile end をあらわすバイトの上位にゴミが入っ
                        てることをあらわすデータをくださいました。
             2000.07.20 このノートを見た方が、情報をくださいました。
                        0x3D は Spiro Monitor 2 Plus である。
                        Zdenek Sraier さんが、シリアル番号に関して
                        コメントを下さったので付記しました。
             2000.09.29 Nitrox と O2 の情報。(Christian Frining さん)


ハードウエアと、通信プロトコル

アラジンからの微弱な信号は、(自作、あるいは、Uwatec 純正 (MSDOS 版)) インターフェースケーブル内のオペアンプによって、 RS232C の信号レベルに変換される。 インターフェースケーブル内のオペアンプには +Vcc と -Vss をPC側から 供給しなければならない。 そのためには、UART のレジスタで

         DTR = 1  negate(つまり、 RS232C 用語でいうと「スペース」)
         RTS = 0  assert(「マーク」)                      
とする必要がある。(注: DTR と RTS は負論理である。)

アラジンはPCに対し、

           19200 baud, 8bit, No parity, 1 stopbit
で 2050 バイトのデータを次のいずれかのタイミングで送出する:
  1. アラジンの接点を濡れた手で触って、 ログブックモードから 1st ログブックモードに移行させたとき。
  2. SOSモードのとき(毎分1回)。
このようなタイミングで送る限り、 PC側ではアラジンがPCへいつデータを送るかを知ることはできないはずである。 アラジンがデータを送っていなかったり、アラジンが繋がっていないとき、RS232C の RD ラインからはゴミのデータが送られて来ることになる。では、いったいどうやる とゴミとまともなデータを区別できるのだろうか? アラジンがゴミでないまともなデータを送る前には、まず
               UUU\0
という連続する4文字(アルファベットの U が3個とヌル文字1個) を送出している。 つまり、"UUU\0" が引き続くことにより、 ゴミでないデータの先頭が容易に判別できる。

"UUU\0" に引続き、 アラジンからPCへ送られてくるデータの長さが 2046 byte である。 データ中の各バイトは、 最上位ビットの位置から最下位ビットの位置までが完全に反転している。つまり、

    読み込んだバイト   b_0 b_1 b_2 b_3 b_4 b_5 b_6 b_7
とすると、
    PCでのバイト     b_7 b_6 b_5 b_4 b_3 b_2 b_1 b_0
である。 したがって、PCに読み込んだデータは、 ビット順を完全に反転させてから処理する必要がある。

最後の 2045 バイト目と 2046 バイト目はチェックサムであるので、 これを使って、読みとりミスの有無の判別ができる。 チェックサムの計算方法は後述する。


送られてきたデータの構造

アラジンからの 2046 バイトは、大きくわけて、

   アドレス        内容
==============================================
    0x000
      |     (1) 深度プロフィールリングバッファ
    0x5ff
----------------------------------------------
    0x600
      |     (2) ログブックリングバッファ
    0x7bb
----------------------------------------------
    0x7bc
      |     (3) 個々のアラジンの情報
    0x7ef
----------------------------------------------
    0x7f0
      |     (4) 現在のアラジンの状態を表す情報
    0x7fd
となっている。以下に個別に説明する。

(1) 深度プロフィールリングバッファ

(4)の領域中の「深度プロフィールリングバッファにおける最後のデータのアドレス」 (0x7f6--0x7f7)よりも(リングバッファ内で)上位のアドレスで、 そのアドレスの内容が 0xff である所が深度プロフィール中で最旧のデータの始まりである。 1つの深度プロフィールは 0xff で始まり、0xff の直前、 あるいは、「深度プロフィールリングバッファにおける最後のデータのアドレス」 で終る。

1つの深度プロフィールは、

先頭からの   内容
オフセット
====================================================
  0         定数(スタートマーク 0xff)
  1--22     減圧情報 (アラジンナイトロックスの場合は 1--24 で、以下が、
            2バイトずつずれる。アラジンO2の場合は 1--25 で、以下が、
            3バイトずつずれる。)
            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: ?
          (ここから Nitrox だけ
            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
            ここまで Nitrox だけ)
          (ここから O2 だけ
            23: ??
            24:     O2 mix %
            25: ??
            ここまで O2 だけ)
  23--      深度プロフィール
            潜水開始20秒後から20秒毎に深さと警告のデータ
                    1分後から1分毎に減圧関連のデータ
            (*)
            23--24  0:00:20 の深さ(上位10ビット)
                              警告(下位6ビット)
            25--26  0:00:40 の深さ(上位10ビット)
                              警告(下位6ビット)
            27--28  0:01:00 の深さ(上位10ビット)
                              警告(下位6ビット)
            29      0:01:00 の減圧関連のデータ
            (Aladin O2 にはもう1バイト(O2 %)がある)
              以下、(*)からここまでを繰り返す

          水深は、(上位10ビット)* 10 / 64 m である。
          例えば、時刻 0:00:20 における水深は、
               (([23] * 256 + [24]) >> 6) * 10 / 64 (m)
          のように計算できる。
          水深データ付属の警告ビット(下位6ビット)は 
              bit 5: 空気圧の送信エラー(Air シリーズ以外では常に出ている)
              bit 4: 過剰な運動        (Air シリーズ以外では出ない)
              bit 3: 減圧停止の水深を守らない
              bit 2: 浮上スピードが速過ぎる
              bit 1: 潜水可能時間が短くなっている、つまり、5分後には40気圧に
                     なってしまうと推定される。(Air シリーズ以外では出ない)
              bit 0: 減圧停止が出ている
          を表す。

          1分毎の減圧関連の1バイトは、
              運動量 0 -- 7(Air シリーズ以外では、水深の変化から推定した
                             ものになっている)
                bit 6: higher bit
                bit 5:   |
                bit 4: lower bit
              皮膚の温度の推定値
                bit 7: 低温指数が 10% 減った
                bit 3: 低温指数が 10% 増えた
              マイクロバブル発生の危険性 0 -- 7  (2 以上が Atn モード)
                bit 2: higher bit
                bit 1:    |
                bit 0: lower bit
          を表す。
(注記:1本の潜水時間が約216分を越えてしまったときは、バッファーに 入る分のプロフィールデータだけが保存され、おさまらない後半の部分だけが 捨てられてしまう。)

(2) ログブックリングバッファ

1つのログブックは12バイトであり、 最新のログブックの位置は(4)の領域中の 「ログブックリングバッファにおける最新ログブックへのオフセット」(0x7f4) で表される。

1つのログブックの12バイトは、次である。

ログブックの
先頭からの
オフセット     内容
=======================================
0             bit7: 高所潜水  higher bit
              bit6:    同     lower bit
              bit5: SOSモード
              bit4: 過剰な運動があった
              bit3: 減圧停止を守らなかった
              bit2: 潜水時間の百の位
              bit1: 反復潜水
              bit0: 浮上速度警告が長時間出ていた
         高所潜水を表す2ビットは 0--3 の値をとり、
              0 m ---  900 m (0)
            900 m --- 1700 m (1)
           1700 m --- 2700 m (2)
           2700 m --- 4000 m (3)
         である。
         潜水時間の百の位を表すために1ビット用意されており
         0, 1 の値をとる(この直後のバイトと合わせて、0 -- 199 分の潜水
         時間が表せることになる)。潜水時間が200分を超えた時は、
         200で割った余りとなる。(例えば 231 分だったら、31 分に
         なってしまう。)
1        潜水時間(2進符号化10進(BCD)である (0 -- 99))
2--3     最大水深 (([2] * 256 + [3])>>6 ) * 10 / 64 (m)
         (ただし、[3] の下位6ビットはゴミである。)
4--5     水面休息時間 ([4] が BCD で表した、「時」。[5] が BCD で表した
         「分」。)ただし、反復潜水でない場合にはゴミである。
6        消費空気量 (bar) (Air シリーズ以外ではつねに0)
         ただし、Aladin Air (Air X とかではなく)の場合は、20 psi 単位で
         あらわしてある。つまり、[6] * 20 [psi].
7--10    アラジンの固有時間 (1994 年 1 月 1 日 00:00からの時間)で表した
         潜水開始時刻(0.5秒単位)
          [7] * 2^24 + [8] * 2^16 + [9] * 2^8 + [10]
11       水温 [11] / 4 度

(3) 個々のアラジンの情報

0x7bc         アラジンのタイプ
                             Nitrox Air  名前
              [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
                        0x3e no     no   Aladin Sport
                        0x3d no     no   Spiro Monitor 2 Plus
                        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
注意:2000年に Uwatec は製品名を変更した。しかし、上記、タイプ
コードに変更はない:
    新しい名            古い名
  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         最大酸素分圧 (Nitrox のみ)
              [0x7d3] * 0.05 + 1.2 (bar)
0x7de         Reserve (Nitrox のみ)
              [0x7de] (bar)
0x7eb         Sensitivity (Nitrox のみ)
              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         定数 (つねに 0x0b).
0x7ed--0x7ef  シリアルナンバー(アラジンの筐体に書いてあるシリアルとは
              全く一致しない)
              = [0x7ed] * 2^16 + [0x7ee] * 2^8 + [0x7ef]
              付記: 8ビットの値 X = [0x7ed] - [0x7ee の最上位ビット]
              はアラジンの製造日と関係があるようです。おそらく、
                  製造年 = X / 6 + 1994;
                  2ヶ月期間の始まりの月 = (X % 6) * 2 + 1;
              (でも、まだ確実ではありません。。。)
これ以外のバイトの意味はわかっていない。

(4) 現在のアラジンの状態を表す情報

0x7f0         バッテリー残量 
              = [0x7f0] * 99 / 255

0x7f1--0x7f3  このアラジンの全潜水本数(工場出荷時にすでに6本)
              = [0x7f1] * 65536 + [0x7f2] * 256 + [0x7f3]

0x7f4         ログブックリングバッファにおける最新ログブックへのオフセット
              = ([0x7f4] - 1) * 12 + 0x600

0x7f5         深度プロフィールリングバッファに何本分の深度プロフィールがあるか
              = [0x7f5]  (古い Aladin Pro の中にはこの番地の値が、本来
                           あるべき値+1 になっているものがある。したがっ
                           てこの番地に書かれている値を利用したプログラム
                           は書かないほうが良い。)
        
0x7f6--0x7f7  深度プロフィールリングバッファにおける最後のデータのアドレス
              = ([0x7f6] + ([0x7f7] >> 1) * 256) & 0x7ff
              注意1: 上位バイトが上位アドレスにあり、しかも、上位だけ
                       1ビットシフトしていることに注意。(上位バイトの
                       lsb はゴミである。)
              注意2: このアドレスから上位を探して最初に見つかったスター
                       トマーク 0xff が、記録が残っているうちで最旧の深
                       度プロフィールのスタート位置である。
              注意3: [0x7f7] の上位4ビットはゴミである。

0x7f8--0x7fb  1994 年 1 月 1 日からはかったアラジン固有時間(単位は 0.5 秒)
              = [0x7f8] * 2^24 + [0x7f9] * 2^16 + [0x7fa] * 2^8 + [0x7fb]

0x7fc--0x7fd  チェックサム
              チェックサム [0x7fc] * 256 + [0x7fd] は、データ 2046 バイトのう
              ち、最後の 2 バイトを除いた 2044 バイト([0] から [2043])を符号
              なしの 8 ビット整数とみなして、総和を計算し、さらに 0x1fe を加
              えたものの 65536 (2^16) での剰余である。(ちなみに、
                      0x1fe = 0xaa + 0xaa + 0xaa + 0 
              であり、0xaa はアルファベットの 'U' をビット逆順にしたもの
              である。つまり、Aladin がデータを送信し始める合図の "UUU\0" 
              をも含めて、チェックサムは計算されているということになる。)

Aladin 用データ転送ソフトのトップページへ 戻る


ご質問、ご意見などがありましたら、

いとーひさし (ITO N. Hisashi) <kuro@neko.ac>
あてにどうぞ。