AZヌンチャクをEQ6で使う話があって、EQ6の通信ログをもらいました。
EQ6を壊してしまうといけないので、今年(2020年)1月~2月にかけてプロトコルを解析した資料があったので、復習がてら整理して載せることにしました。
万人の役に立つ情報ではないですが、なにせ本家のドキュメントがあまりにも不親切なので、必要な人には役に立つかなと思います。
(このサイトは2か国語にしてますが、このページは面倒なので日本語のみです。)
免責事項と注意点
この資料は自分の手元にあるAZ GTi(1台のみ)とPC版SyncScanProとの通信ログを解析しながら、SkyWatcher社のモータープロトコルのドキュメントを自分なりに理解したもので、当然間違っている可能性もあります。また本ページ作成時に転記間違いがあるかもしれません。
このページに掲載している情報を元にした結果のいかなる直接的、間接的損害について、当方は一切の保証は致しません。本ページ掲載情報の利用は自己責任で行ってください。
実際の作成にあたっては元にSkyWatcher社のドキュメントを正として、こちらは参考程度にして頂くようお願い致します。
基本的な情報
単純なシリアル通信です。ボーレート9600、データ8 bit、パリティ無し、ストップビット1、フロー制御無し。
シリアル通信の電圧は3.3Vですが5Vでも動きます。間違えてRS232Cレベルの電圧をかけると壊れてしまう可能性があるので、注意してください。
通信は文字(テキスト)によるプロトコルです。クライアント(ハンドコントローラ等)から、マウント(AZ GTiなど)にメッセージを送り、返事を受け取ります。マウント発でメッセージを送ることは(たぶん)ありません。
コマンドを送る時は 「:」 で始まるメッセージで、返事は「=」で始まります。エラーの時の返事は「!」で始まります。メッセージ終わりは全て「\r(0D)」です。
「:」の後の1文字がコマンドコード、その次の1文字が「1」か「2」でこれはAxis(軸)番号です。
接続開始時
まずはクライアント(SyncScanPro、ハンドコントローラ、ヌンチャクなど)とAZ GTiの通信開始時の通信です
モーターボードバージョン問合せ
(–>Mountへ) :e1\r
(<–Mountから) =0314A5\r
(–>Mountへ) :e2\r
(<–Mountから) =0314A5\r
拡張情報要求 ExtendenInquire (AZGTiが赤道儀モード対応かどうか、に使ってます)
(–>Mountへ) :q1010000\r
(<–Mountから) =098000\r
拡張情報設定 ExtendedSetting(ディアルエンコーダON/OFFとか)
(–>Mountへ) :W1050000\r
(<–Mountから) =\r
(–>Mountへ) :W2050000\r
(<–Mountから) =\r
オートガイドスピード設定
(–>Mountへ) :P12\r
(<–Mountから) =\r
(–>Mountへ) :P22\r
(<–Mountから) =\r
CPR値取得 Inquire CPR
(–>Mountへ) :a1\r
(<–Mountから) =00A41F\r
(–>Mountへ) :a2\r
(<–Mountから) =00A41F\r
TI-Freq値の取得 Inquire Timer Inturpput Freq
(–>Mountへ) :b1\r
(<–Mountから) =0024F4\r
(–>Mountへ) :g1\r Inquire Highspeed Ratio
(<–Mountから) =01\r
(–>Mountへ) :g2\r Inquire Highspeed Ratio
(<–Mountから) =01\r
後々、モーターを動かすのに必要な情報は、青字で書いたそれぞれのモータのCPR値と、TI-Freqと書かれている値です。これはマウントによって異なるようで、AZGTi と EQ6では全く違う値でした。ご注意ください。
(2020/9/18 追記)
AZ-GTi ではこの値は1なので気付かなかったのですが、EQ6のログを頂いて、それを解析した結果、この値も取得が必須ということが判明しました。
ちなみにEQ6の場合、値は 0x10(=10進法で16)でした。
この値もモーターの速度計算に使います。
値のデコード
このプロトコルでの値のエンコードはリトルエンディアンです。
例えばモーター1のCPR値は
=00A41F\r
です。
これは
0x00 + 0xA4 * 256 + 0x1F * (256)^2
= 0 + 164 * 256 + 31 * 256 * 256
= 2073600
となります。
また、TI-Freq は
=0024F4\r
なので、
0x00 + 0x24 * 256 + 0xF4 * (256)^2
= 0 + 36*256 + 244 * 256*256
= 9216 + 15990784
= 16000000
となります。
モーター速度の計算
モーターの駆動速度は恒星時基準になってましたが、下記の値を使うことで太陽時、月時等に変えることができます。
1周するのに要する時間 (スケッチでは 「baseSecPR」 回転あたりの基準秒数)は
恒星時 23:56:04.091 = 86164.091(秒)
太陽時 24:00:00.000 = 86400.00(秒)
月時 23:03:39.014 = 83019.014(秒)
ここでは恒星時を例にして計算します。
コマンドで送るTI値は N 倍速で動かすとき、
TI = (1/N) * ((baseSecPR / CPR) * TMR_Freq)
また高速モードの時は
TI = (1/N) * ((baseSecPR / CPR) * TMR_Freq) * (High_Speed_Ratio)
(2020/9/18追記: AZ GTi は High_Speed_Ratio=1 なので気付かなかった)
となります。
実際は整数値に丸めて、マイナスのときは絶対値を取ります。(マイナス=逆方向のときは、別の方法で指示します。)
※ドキュメントでは上の式で 1/N とした所が N になっていて、どうやっても計算が合いません。(2020/9/18追記)
『 T1_Preset = N * TMR_Freq * 360 / Speed_DegPerSec / CPR 』(ドキュメントの式)
式を見直して実際のデータと突き合せた結果、Nは分子じゃなくて分母にくる、という結論になりました。SkyWatcher社に問い合わせてますが返事がないままです。
上記の「Nは分子じゃなくて分母じゃないか」という疑問を出したわけですが、これは私の勘違いであることが分かりました。
ドキュメントで出てくるNは、私は「N倍速駆動するとき」のNと思っていたのですが、式の中のNは「High Speed Ratio」です。
具体例
恒星時駆動 x1.0 のとき
TI = 1/1 * ((86164.091 / 2073600 ) * 16000000 = 664846.381 ≒ 664846
恒星時駆動 x0.5 のとき
TI = 1/0.5 * ((86164.091 / 2073600 ) * 16000000 = 1329692.762 ≒ 1329693
恒星時駆動 x8 のとき
TI = 1/8 * ((86164.091 / 2073600 ) * 16000000 = 83105.798 ≒ 83106
これをステップごとに表にしたものです。1桁目に若干の違いがあるのは、演算精度の問題です。
ステップ | 倍速(N) | TI値 | 16進表記 | メッセージ |
0 | 0.5 | 1329691 | 144A1D | 1D4A14 |
1 | 1 | 664846 | 0A250E | 0E250A |
2 | 8 | 83106 | 0144A2 | A24401 |
3 | 16 | 41553 | 00A251 | 51A200 |
4 | 32 | 20776 | 005128 | 285100 |
5 | 64 | 10388 | 002894 | 942800 |
6 | 128 | 5194 | 00144A | 4A1400 |
7 | 400 | 1662 | 00067E | 7E0600 |
8 | 600 | 1108 | 000454 | 540400 |
9 | 800 | 831 | 00033F | 3F0300 |
この一連の計算の結果のTI値がモーターを動かすときの値となります。
なお、上記の表はAZ GTiの場合のもので、他のマウントの場合はCPR値及びTI-Freq値が違いますので、この表の数字をAZ GTi以外のマウントにそのまま使うと、最悪故障する可能性があります。計算はマウント毎にCPR値及びTI-Freq値を取得して、それを元に計算し直してください。
なお、マウントによってはCPRの値と TMR_Freqの値が違うため、高速で動かす場合は計算結果のTI値が小さくなりすぎることがあります。(例えばEQ6マウントで、ステップ7~9で動かす場合)
その場合、TI値をN倍します。Nは「:g」コマンドで取得した High Speed Ratio で、EQ6の場合は16ですので、出てきたTI値を16倍して使います。
ちなみに High Speed モードかどうか(TIに倍率が掛かっているか)どうかは、後述の「方向をセットする」で指示することで判断しています。
ステップ | 倍速 | 計算した T1値 | 高速 モード | 使用するTI値 高速はx16 | 16進表記 | メッセージ |
0 | 0.501229 | 1237 | 1237 | 0004D5 | D50400 | |
1 | 1.004896 | 617 | 617 | 000269 | 690200 | |
2 | 8.26694 | 75 | 75 | 00004B | 4B0000 | |
3 | 17.22279 | 36 | 36 | 000024 | 240000 | |
4 | 38.75128 | 16 | 16 | 000010 | 100000 | |
5 | 88.57436 | 7 | 7 | 000007 | 070000 | |
6 | 103.3368 | 6 | 6 | 000006 | 060000 | |
7 | 450.924 | 1.375 | 高速 | 22 | 000016 | 160000 |
8 | 708.5949 | 0.875 | 高速 | 14 | 00000E | 0E0000 |
9 | 1102.259 | 0.5625 | 高速 | 9 | 000009 | 090000 |
(倍速数は実測データから逆算)
モータを動かす
※マニュアル操作しか扱ったことが無いので、自動導入に使われる目標をセットしての自動セット(GoTo)は分かりませんので、ここでは扱ってません。
基本
モーターを動かす基本は、次の流れです。
1.モーターがBusyでないか確認する
2.方向と速度をセットする
3.STARTコマンドを送る
ただし、注意点があり
・逆方向に動かすときは、一旦STOPコマンドを送り、停止するのを待ってから、動かす
・高速モードで動いている時は、一旦STOPコマンドを送り、、以下同文(AZ GTiはSTOPを送らなくても速度変更できてしまいますが、急激な速度変更は架台に負荷をかける可能性があります。する場合は自己責任で。ちなみに高速モードのときは、架台側が自動的に加速・減速制御をしてるようです。)
・GoToモードで動いているときは、動かさない
以下、モーター1番について説明します。モーター2番のときは、コマンドの後の数字を2に読み替えてください。
1.モーターがBUSYでないか確認する(状態取得)
コマンド 「:f1」(モータ2の時は「:f2」)
※コマンドは大文字小文字の区別があります
返事例 「=301」
1文字目 0x03 = 0000 0011
右端のビット 動作モードB0: 1=Tracking, 0=Goto
右から2番目のビット 回転方向 B1: 1=CCW, 0=CW
右から3番目のビット 項目モード B2: 1=Fast, 0=Slow
2文字目 0x00 = 0000 0000
右端のビット 動作中かどうか B0: 1=Running,0=Stopped
右から2番目のビット B1: 1=Blocked,0=Normal (何に使われているか分からない…)
3文字目 0x01 = 0000 0001
右端のビット 初期化が終わっているか B0: 0 = Not Init,1 = Init done
右から2番目のビット B1: 1 = Level switch on (何に使われているか分からない…)
2文字目のビット0が1の時は動作中なので、コマンドを送ってはいけない。
ただし、現在が停止中または低速移動中で、かつ同方向への速度変更については動作中でも可能。
それ以外のときは、STOPコマンド 「:K1」を送り、「:f」コマンドで停止するまで待機する。
2.方向をセットする
Set MotionMode コマンド「:G」を使う
例 「:G130」
セットする値は 「30」 = 0000 0011 0000 0000
1文字目 [3] = 0000 0011
B0: 0=Goto, 1=Tracking 動かすときは1にセット
B1: 0=Slow, 1=Fast(T) 128倍速より早く動かすときは1にセットすること
0=Fast, 1=Slow(G) ※Gotoモードでは逆のようです。。。。
B2: 0=S/F, 1=Medium すいません、何か分かりません。0しか見たことないです。Goto時のコマンドかも。
B3: 1x Slow Goto すいません、何か分かりません。0しか見たことないです。Goto時のコマンドかも。
2文字目 [0]=0000 0000
B0: 0=CW、1=CCW モーターの回転方向を指定します。
B1: 0=Noth, 1=South すいません、何か分かりません。0しか見たことないです。Goto時のコマンドかも。
B2: 0=Normal Goto, 1=Coarse Goto すいません、何か分かりません。0しか見たことないです。Goto時のコマンドかも。
3. 速度をセットする
速度をセットするには「:I」コマンドを使います。
速度は「モーター速度の計算」で計算したTI値を使います。
ステップ | 倍速(N) | TI値 | 16進表記 | メッセージ |
0 | 0.5 | 1329691 | 144A1D | 1D4A14 |
1 | 1 | 664846 | 0A250E | 0E250A |
2 | 8 | 83106 | 0144A2 | A24401 |
3 | 16 | 41553 | 00A251 | 51A200 |
4 | 32 | 20776 | 005128 | 285100 |
5 | 64 | 10388 | 002894 | 942800 |
6 | 128 | 5194 | 00144A | 4A1400 |
7 | 400 | 1662 | 00067E | 7E0600 |
8 | 600 | 1108 | 000454 | 540400 |
9 | 800 | 831 | 00033F | 3F0300 |
例えば恒星時の16倍なら、(AZ GTiの場合は )TI値は41553、これは16進数で 0x00A251、このプロトコルでは「51A200」となるので、送るべきメッセージは「:I151A200」 となります。
※この表はAZ GTiのもので、他のマウントでは CPR値、TI-Freq値が異なるので、都度計算する必要があります。他のマウントのコードにこの表の値をそのまま使わないでください。
4.STARTコマンドを送る
上記で回転方向と速度がセットできたので、「:J」コマンドを送ると動き出します。
例 「:J1」
5.STOPコマンドを送る
Tracking時(Gotoで目標ステップまで自動で動かす、ではない場合)、モーターはSTOPを送らないと動き続けますので、注意してください。
ヌンチャクではレバーがニュートラルになった時にSTOPを送っています。停止させるときは 「:K」コマンドを送ります
例「:K1」
2軸同時に動かす場合
SyncScanで斜め上のボタンを押すような場合、2軸同時に動かすことになります。
※初期化時の InquireStatusというコマンドで取ってくる情報に 「Tow axes must start seperately B2: Support」というのがあり、AZGTiは関係ないようですが、ドキュメントの文言からして、ここのビットが1のときは、別々に動かす必要があるかもしません。(ヌンチャクではこのビットは無視しました)
軸は二つありますが、架台とのシリアル通信は1チャンネルしかないので、交互に通信するような感じです。
これはステップ9(800倍速)で右斜め上ボタンを押した時の通信内容です。
(–>Mountへ) :f1\r 軸1 状態確認
(<–Mountから) =101\r
(–>Mountへ) :f2\r 軸2 状態確認
(<–Mountから) =101\r
(–>Mountへ) :G130\r 軸1 回転方向と高速モードセット
(<–Mountから) =\r
(–>Mountへ) :G230\r 軸2 回転方向と高速モードセット
(<–Mountから) =\r
(–>Mountへ) :I13F0300\r 軸1 速度セット
(<–Mountから) =\r
(–>Mountへ) :I23F0300\r 軸2 速度セット
(<–Mountから) =\r
(–>Mountへ) :J1\r 軸1 START
(<–Mountから) =\r
(–>Mountへ) :J2\r 軸2 START
(<–Mountから) =\r
(–>Mountへ) :K1\r 軸1 STOP(ボタンを離した時)
(<–Mountから) =\r
(–>Mountへ) :K2\r 軸2 STOP(ボタンを離した時)
(<–Mountから) =\r
その他の情報
ここで扱ったのはモータープロトコルで、
・HandControllerポートからシリアル通信で送る
・Wifi経由でUDP通信で送る
・SyncScanAppから架台へUDP通信で送る
の時に使われるものです。上記のどの経路からも送れてしまうので、気を付けて使わないとバッティングする可能性があります。稀にバッティングの結果、AZGTiがハングアップして、電源を入れ直ししないと戻りませんが、幸い壊れたことはありません(汗)
AZ GTiにはこれ以外に(SyncScanAppをサーバとして、それに対して)TCP通信できる別のコマンド体系が用意されています。こちらは赤経、赤緯を指定しての移動とかもできるみたいです。こちらはまだちゃんと調べたことがないのですが、SyncScanAppを起動していないと使えないようです。
赤道儀モード対応(9/16追記)
AZ GTiは(自己責任で)ファームウェアアップデートによって赤道儀モードにすることもできます。
Extended Inquireコマンド「:q」で状態を取得すると、
:q1010000 に対して
購入時の経緯台オンリーの時の返事
=018000 ”1″のところは 0000 0001
赤道儀選択可能な時の返事
=098000 ”9″のところは 0000 0101
仕様書によると返事2文字目のビット3は
B3: Support EQ/AZ mode
となっているので、この時SyncScanAppアプリは赤道儀選択可能になるようです。
ただ、SyncScanAppアプリで赤道儀を選択しても、経緯台を選択しても、選択時にはコマンドは何も送られません。これはつまり、経緯台か赤道儀かを判断して制御するのはアプリ側で、架台側では何もしていない事を意味します。
ついでにいうと、アライメント決定時にも何もコマンドが送られないので、アライメント情報を持ってるのはアプリ側、ということになります。
架台側は、アプリからの要求に応じてエンコーダポジションを返すのと、モーターを動かすのみのようです。
追尾について(9/16追記)
経緯台モード、赤道儀モードでの追尾についても、アプリ側に頭脳があるようです。
まず経緯台モードの時は、頻繁に(おそらく1Hz)で、アプリからポジションを問い合わせて、こまめに両方のモーターに指示を出して追尾させています。
現在の架台の状態、方位、高度から対象物の位置をリアルタイム計算するには、アライメントの情報を持っていないとできません。
これをヌンチャクに実装するには、アライメントもヌンチャクでやらないといけないことになり、ちょっと無理なので諦めました。ハンドコントローラをつないだ時は、ハンドコントローラは全部やってるのでしょう。
一方、赤道儀モードの追尾は簡単です。
操作が終了してアイドルになる時に、赤経モーターを恒星時 x1倍速で動かして、そのまま放置するだけです。SyncScanAppもそのようにしています。 太陽時駆動なら、ベースとなる速度が微妙に違うだけで、やってることは同じです。
※南半球の時は、「放置速度」が逆方向になるので注意
赤経モーター追尾時は、ボタンを押していない時はx1倍駆動、ステップ1(x0.5倍駆動)の時は、順方向なら 1+0.5=1.5倍速に、逆方向なら 1-0.5=0.5倍速になります。逆方向にステップ1(x -1)で動かすと、1-1=0 でモータが停止します。
要は全ての速度に恒星時駆動速度が足された値になります。
ステップ | 経緯台モード・赤緯軸 | 赤道儀モードの 赤経(北半球の時) |
4 | x8 | 1+8= x9 |
3 | x4 | 1+4= x5 |
2 | x2 | 1+2= x3 |
1 | x1 | 1+1=x 2 |
0 | x0.5 | 1+0.5=x 1.5 |
停止 | x0 | 1+0= x1 |
0(逆方向) | x -0.5 | 1-0.5= x0.5 |
1(逆方向) | x -1 | 1-1 = x0(停止) |
2(逆方向) | x -2 | 1-2= x -1 |
3(逆方向) | x -4 | 1-4= x -3 |
4(逆方向) | x -8 | 1-8= x -7 |
はじめまして。仔細かつ丁寧に情報が書かれていて、とても役に立ちます。
このページへたどり着くまで、INDI Libraryというフリーの望遠鏡+周辺機器制御ソフト
ライブラリ(私は1.7.4を使ってきました)を情報源としていました。
その中の indi-1.7.4/3rdparty/indi-eqmod/ ディレクトリに skywatcher.h, skywatcher.cpp
というのがありまして、これでコマンドと引数をだいぶ理解することができます。
ご存知のことかも知れませんが、ご参考までに。
コメントありがとうございます。
INDIのソースが見れるのですね。
プロトコルアナライザのログと仕様書をにらめっこして実験しながら解読してたのですが、
コーディングは本業なので、そちらを見た方が早かったのかもしれません(笑)
一度見てみます。
情報ありがとうございました。