AI の挙動不審

AI (Auto Information) でデータが自動でくるようになるけど、その状態でこちらから読み出しコマンドを出したり、書き込みコマンドを出したりすると、それらのコマンドがうまく読みとってくれなかったり、あるいは出力が混ざったりする。

解決方法でいまいち良いのがない

考えた解決案

  • AI はするが、コマンドは何度か送りつける
  • 一旦 AI を止めて、コマンドを送りつけて AI を再開する
  • AI を一切やめて必要な情報だけをポーリングする
AI はするが、コマンドは何度か送りつける
  • 3回程度送りつけても結局失敗することがある

コマンドが成功していることが確認できるまで送り続ける方法もあるが、コマンドごとに確認方法が違うのでコーディングが大変

一旦 AI を止めて、コマンドを送りつけて AI を再開する
  • まず、AI を止めるためのコマンドが認識されないことがある
  • AI を止めてもすぐに止まるわけではないっぽい
AI を一切やめて必要な情報だけをポーリングする

確実に動くけど

  • 情報が反映されるのが非常に遅くなる

例えば読み出しコマンドを発行すると、250ms ぐらいでようやくレスポンスがあるので (何やってんだ?) 、4個値を読み出すだけで1秒かかってしまう。

AI はそのまま

AI はそのままにするのがやはりよさそう。コマンドを送って確実に操作するよりも情報を早く受けとるほうが重要だと思う。

とはいえ、コマンドを送ったのに反映されないのもイラつくので、かなり執拗に送信確認をする必要がある。

  • 書きこみするコマンドを3回送りつける
  • 読みだしする

として、返答があるのを250msぐらい待って、セットできていなかったらリトライする。

  1. トップ
  2. tech
  3. FT-450D の CAT の挙動
  1. トップ
  2. ham
  3. FT-450D の CAT の挙動

RS-232 TTL 変換をフォトカプラでやる。

グラウンドを分離したいと、ノイズ相互の流入を防ぎたいのでRS-232変換を専用ドライバーICではなく、フォトカプラで行うようにした。無線機側とグラウンドを共通にするとインターフェアがでやすいらしい。

面倒な点は、RS-232 側の両電源を別に用意しなくてはならないところだけど、ググってみるとRTSにきてる電圧と RX の電圧をうまいこと利用している例があったので、それに従うことにした。一応RTS CTSをショートさせて電圧を計ってできそうなことを確かめた。

回路

これのコピーです

RS-232 が正負電圧で論理表現をするのでそこが面倒なところ、正電圧はRTSできてるのでいいけど、負電源をとれるピンはないので、TXのアイドル (負電圧がかかってる) を使ってる。47uFの電解コンデンサは電源を安定させるためについてる。

TX のアイドル時にコンデンサに電荷をためといて、RX が正じゃないときはダイオードを通じて RX のレベルを負に保つようになっている。コンデンサの前に 680Ω の抵抗がついているのは正のときにおかしくならないようにかな……

あとは電圧をクリップするダイオードがついていたり、フォトカプラのスペックにあわせるための抵抗がついてたり。

RS-232とTTLは論理が逆だけど、フォトカプラがオープンコレクタなので自動で反転して丁度いい。

手元で試した限りだと、ボーレート 19200 でもうまくうごいた。

挙動を確認する

その後オシロスコープを買ったので再度挙動を確認してみた。

これは Linux → Rig 方向のもの。この方向の負電圧は 47uF に蓄えられているものが使われる (と思う) ので、連続して送信を行うと、だんだん電圧レベルがさがってしまう。最後のほうは 3V 未満になってしまっているので、RS-232 レベル的には動かない。

200uF にすると、だいぶマシになる。適切なのを選択する必要がありそう。

ハマったところ

ハマったのは、USB シリアル変換ケーブルと、無線機のRX TXの配線が逆な点だった。これは普通にドライバーIC使ったときもハマったので比較的すぐ抜けれたけど、毎回ハマる…

あとはTTLレベルのRXをRS232ドライバICに面倒くさがって繋がったままやってたら動かなかったのもハマった (電源が入ったままだったので GND に落ちていたっぽい)。変なことしないほうがよい

あと、もっと簡略化した回路(TXとRXを繋ぐ部分、負電源部分を削除したもの)もググるとでてくるけど、それだと今回はレベルが安定しなくて、エコーする現象が起きてだめだった。

フォトカプラは FOD817B300 というのを使った。応答速度の関係でものによっては動かないとかあるみたいだけど手元にあったのでうまく動いた。

参考文献

  1. トップ
  2. tech
  3. 絶縁型 RS-232 ⇔ TTL レベル変換
  1. トップ
  2. ham
  3. 絶縁型 RS-232 ⇔ TTL レベル変換

クソコード を書いたはいいが、釈然としなかった。 "View independent business logic: Services" とドキュメントに書いてある通りなので、やはり他のやりかたのほうがよい。のでよくよく読んだところ、やはり View にかかわる部分は Directive に集約されるようだ…… しかし使いかたが非常に難しい。

iimsApp.directives.directive('dialog', function ($q) {
    return {
        restrict: 'E',
        transclude : true,
        scope : {
            Dialog : '=name'
        },
        controller : function ($scope) {

            $scope.Dialog = {
                open : function (title) {
                    $scope.deferred = $q.defer();
                    $scope.title = title;
                    $scope.show  = true;
                    return $scope.deferred.promise;
                }
            };

            $scope.close = function () {
                $scope.show = false;
            };

            $scope.ok = function () {
                $scope.close();
                $scope.deferred.resolve();
            };

            $scope.cancel = function () {
                $scope.close();
                $scope.deferred.reject();
            };
        },
        templateUrl : '/static/js/app/dialog.html'
    };
});

こんな感じで dialog という directive を定義して、

<div ng-controller="FooCtrl">
    <dialog name="FooBarDialog">
        {{ message }}
    </dialog>
</div>

というふうにすると、FooCtrl のスコープから FooBarDialog というプロパティで見えるようになる。つまり

        $scope.message = "Hello!";
        $scope.FooBarDialog.open('OKK!!!!!').then(function () {
            alert('ok');
        }, function () {
            alert('cancel');
        });

みたいなあ

難しポイント

  • restrict: 'E'
    • この directive は要素として使うよってこと
  • directive の scope の定義がむずかしい
    • プロパティ名には自分のスコープで見える名前、値には謎の書式で親スコープから見える名前が書いてある属性名を書く
  • controller に渡される $scope
    • 親スコープなどからは分離されているスコープが与えられる。directive が何度も出現することもあるからね!
  • transclude: true の意味。これは dialog 要素内に内包される変数が、外側のスコープをさすようにするもの。例では $scope.message を外側のスコープで代入している

こういう謎の構造体を返すのってわっかりにくいので気持ち悪いなあて思いました。全部メソッドになっているべきなのでは????

directive のプロパティの説明がどこにあるかわかりにくいけど、 http://docs.angularjs.org/api/ng.$compile#description_comprehensive-directive-api_directive-definition-object にある

  1. トップ
  2. tech
  3. Angular JS で View を伴う Service 的なことをしたいとき、あるいは Directive に Controller をつけたいとき。