hirax.net::Keywords::「ComThread」のブログ



2009-12-15[n年前へ]

ComThreadを使った「制御プログラムの作り方」図解編 

 以前、Rubyでテキストや(比較的単純低速な)バイナリデータ送受信のためのクラスであるComThreadを作りました(情報ページ)。それでは、どんな風に使うかということも、これまた以前、ComThreadを使った「制御プログラムの作り方」に書いたことがあります。

 ComThreadという名前が、実にありがちな名前であるので、他のライブラリともしかしたら混同されているのかもしれませんが、「送受信に2つのポートを必要とするのか?」という質問があったので、「そんなことはないですよ」とここに書いておきます(もしかしたら、最初に作成した際の紹介記事の2番目の例が、機器間のシリアル通信をモニタリングする例だったから、そういう風に勘違いされたかもしれません)。

 最初の記事の2番目の例、すなわち、機器間のシリアル通信をモニタリングする例は、AとBという機器間で行われている通信をモニタしたい、AとBは通常通り通信しあう関係にしたままで、その互いのやり取りを知りたい、という場合に、シリアル通信の内容を調べる、というプログラムです。つまり、簡略図にすると、A<->Bという関係をA<->PC<->Bというにしてやり、PCはAから受信した内容をBに送り、Bから受信した内容をAに送るわけです。だから、PCからみると、機器Aへの接続を行うCOMポートと、機器Bへの接続を行うCOMポートの2つが必要だったというわけです。

 もちろん、それは2機器間の通信をモニタリングする例だったからで、(最初の紹介記事の)一番最初に挙げた例のように、1つの機器相手に送受信を行うだけであれば、当たり前のはなしですが、COMポートは1つしか必要としません。

 さて、これだけではつまらないので、今日は、ComThreadを使った「制御プログラムの作り方」で書いたことを図にしてみました。つまり、前回、文章とコードで書いた内容を「図」にしてみました。それが下の図になります。

 前回書いたように、(センサーやモーターといった)各ハードウェア機器に対するモデル・クラスをConThreadクラスを継承させて作り、また、制御を行うコントローラをThreadクラスを継承して作り、そのコンローラインスタンスに、各モデルのインスタンスを渡してやる、というのがComThreadを使い、複数機器を制御するのであれば、一番整理しやすいような気がします。

 つまり、(各ハードウェア)モデル・インスタンス(スレッド)を作成し、コントローラ・インスタンス(スレッド)を作成して、(各ハードウェア)モデル・インスタンスをコントローラ・インスタンスに渡した上で、必要な期間だけそれらのスレッドを動かしておく、というようなスクリプトを作る、という具合です。

ComThreadを使った「制御プログラムの作り方」図解編






2009-12-28[n年前へ]

VISTAで使うUSB接続シリアルポート+wincom.rb 

 「TEXCELLのRubyシリアル通信ライブラリ wincom.rb で、(WindowsXP上では受信できるのに)Windows VISTA上では、レガシーなCOM1ではデータ受信できるが、(Prolificのチップ・ドライバーを使った)USB I/F接続シリアルポート接続では受信できなかった」という記事を読んだ。原因は、

 Vista環境にて、USB接続シリアルポートでは、(Windows APIの)ReadFileを実行した際、「読み取ったバイト数」として常にゼロが帰ってくるため。
ということで、USBシリアルI/Fドライバのバグらしいが、考えてみれば、「VISTAマシンでシリアル接続をしたことがないことに気づいたこと」「ATEN製UC-232A・シグマAPO製URS232GFと同タイプを使う可能性もあること」から、リンク先の記事にあった対処法を自分用に書き写しておく。機会があれば、自分でも確認してみよう、と思う。
 対処法:ReadFileの「読み取ったバイト数」は使わず、ClearCommErrorを実行した際に得られたCOMSTAT構造体の「受信バッファにあるデータ・バイト数」を使う(常に0バイトよりはマシだ)。
def receive
# rcvchar=@wcrecv.unpack("a#{irlen[0]}")[0]
rcvchar=@wcrecv.unpack("a#{ilen}")[0]



■Powered by yagm.net