2008-12-06[n年前へ]
■格安ロボットアームで遠隔リモコン制御
「ハードウェア要らず?の遠隔リモコン制御」のポリシーは、「リモコンにハードウェア改造をしない」「コストをできる限りかけない」というポリシーのもとにない知恵を絞って作成してみました。その結果、実装も見た目もが実に「行き当たりばったり感」に満ちてしまい、遠隔操作システムというよりピタゴラスイッチのようなものになってしまいました。
そこで、「リモコンにハードウェア改造をしない」という前回と同じ方針のもとに、けれど、「コストをできる限りかけない」という「縛り」部分を少しゆるめて、格安ロボットアーム「MR-999 」と「シリアル接続I/Oボード:RBIO-2U」を使いエアコンのリモコン遠隔操作をすることができるか、ロボットアームの先っぽで、リモコンの電源オン・オフを押すことができるか、という検証実験に挑戦してみました。
RBIO-2U (USB-シリアル通信-リレー)I/Fユニットを使うと、シリアル通信経由で命令コマンドを送信するだけで、簡単に、100ms単位でロボットアーム MR-999 の各関節や、可動部を駆動制御することができます。・・・で、挑戦してみた結果、リモコンのスイッチを押すことはできたのですが、残念なことに、(関節モータの遊び量が多いことと、いつの間にか動かないモーターが増えてしまい)何度も動作させることができませんでした。
そこで、検証実験中のようすを撮影したものを貼り付けておきます。しかし、この写真を見ても、「見た目」もどうも今ひとつ「原始的」ですし、「安っぽさ」をぬぐい去ることが全くできていないような気がします。技術のぎ「ギ」の字も感じない割に、ローテク感だけは満ちているように思えるところが実に哀しいところです。
2009-07-26[n年前へ]
■シリアルポートで受信した内容を最前面アプリにキー送信するRubyスクリプト
10年以上前、自分の勉強がてら、シリアル・ポートで受信した内容をエクセルに貼り付けるプログラムをC++で作りました。確か、Windows 98が出た頃で、Windows 2000が出る前だったと思います。
今日、久しぶりに、Windowsでシリアル・ポートで受信した内容をエクセルに貼り付けるプログラムを作り直したくなりました。そこで、Rubyで「シリアル・ポートで受信した内容を最前面アプリにキー送信するスクリプト」を書いてみました。
といっても、スレッドを使いシリアル・ポート送受信を行うRubyのクラス"ComThread"は、少し前に書いています。また、Windowsの(キー操作やマウス操作などを扱う)各種APIを使うためのRubyクラス"Win32GuiTest"も、同じように書いてあります。
ということは、その2つを使うと、こんな風に「シリアル・ポートで受信した内容を最前面アプリにキー送信するRubyスクリプト」を簡単に書くことができます。
require 'comThread' require 'win32GuiTest' class SendKeyComThread < ComThread def receive(data) @gui=Win32GuiTest.new @gui.sendKeys data.strip+"{ENTER}" end end skCom=SendKeyComThread.new(1, Queue.new,nil,0x1807, 9600) skCom.start(:receive=>true) sleep 60 skCom.stopこれだけで?という感じですが、これだけです。このスクリプトを走らせれば、COM1に(9600bpsで)受信した内容を最前面ウィンドーに送信することが(60秒間)できます。
このサンプル・ソースと必要なファイルは、ここに置きました(wincom.rbも必要です)。
計測器等を使う人であれば、この手のスクリプトは結構便利に感じるのではないでしょうか?こうしたスクリプトを書き、自分が使っている計測器や機器の送出コマンドに合わせたデータ加工正規表現を書き、"receive"メソッドをオーバーライドするのがシェフのお勧めメニューになります。もちろん、RubyScript2exeで、アプリケーション化しておけば、さらに便利だと思います。
2009-07-29[n年前へ]
■wincom.rbのCOM10以上対応
以前、スレッドを使い、Rubyでシリアル通信をするクラスComThreadを書きました。このクラスは、wincom.rbを利用しています。
少し前、wincom.rbが、COM10以上の番号のシリアル・ポートを開けないことに気づきました。ソースを眺め調べてみると、WindowsAPIのCreateFile()を使った場合の、COM10 以上のシリアルポートを指定方法に沿っていないことが原因でした。対処としては、wincom.rbの71行目を
comno = "\\\\.\\COM#{icomno}\0"というように変えれば、COM10以上のポートにも(もちろんCOM10以下のポートにも)対応するようになります。
最近の(各種I/Fがたくさん備えている)PCに、USB接続のシリアルポートI/Fを繋いだ場合、自動的にCOM10以上になる場合も多いと思います。そんな状況下で、wincom.rbを使うためのTipsとして、ここにメモを書いておきます。
2009-07-30[n年前へ]
■ComThreadを使った「制御プログラムの作り方」
比較的単純なハードウェア制御、たとえば、(シリアル・ポートから値を得ることができる)センサからの入力を使い、(シリアル・ポートからコマンドを送ることで制御することができる)ハードウェアの制御をしたくなることがあります。実例としては、温度センサの値を使い、扇風機のモーターON/OFFを行いたい、というような場合があります。そんな場合のために、(以前作った)RubyのComThreadを使った「制御プログラムの作り方」を、自分のためのメモがてらここに書いておこうと思います。
まずは、センサーやモーターの各ハードウェア、つまり、各シリアル・ポート毎に個別のクラスを作っておきます。たとえば、センサーの値にアクセスするクラスをこんな感じで作り、
require 'comThread' class SensorComThread < ComThread def start(condition={:receive=>false,:send=>false, :receiveMonitor=>false, :sendMonitor=>false}) @info={} super end attr_reader :info def receive(data) @info=data.gsub(' ','').split(',') end end次に、たとえば、モーターを操作するクラスをこんな感じで作ります。
require 'comThread' class MotorComThread < ComThread def sendStart send("start") end def sendStop send("stop") end end各シリアル・ポートに接続された機器に対する「値解釈」や「送信コマンド作成」といった部分は、上のような具合で、各ポート(に接続された各種機器)を扱うクラスを個別に定義しておく方が頭が整理しやすいように思います。
そして、次は制御用のメイン・コントローラ・クラスを書きます。
require "thread" class ControlerThread def initialize end def start(inf) @sensor=inf[:sensor] @motor=inf[:motor] @thread=Thread.new do while true @motor.sendStop if @sensor.info[0].to_f<hoge @motor.sendStart if @sensor.info[0].to_f>=hoge end end end def stop Thread.kill(@thread) end end
最後に、センサ用コントローラ/モータ用コントローラ/メイン制御コントローラを、それぞれ起動する制御スクリプトを、次のように書きます。
require "sensorThread" require "motorThread" require "controlerThread" sendorRq=Queue.new; MotorSq=Queue.new; sensor=SensorComComThread.new(1,sensorRq,nil, 0x1807,38400) sensor.start(:receive=>true) motor=MotorThread.new(2, nil,motorSq,0x1807,38400) motor.start(:send=>true) controler=ControlerThread.new controler.start({:sensor=>motor,:motor=>motor}) sleep ARGV[0].to_i controler.stop motor.stop sensor.stopこのように、各I/Fに対するコントローラと、メイン制御コントローラと、それらコンローラ・スレッド群を実行するシーケンス・スクリプトを個別に作る、というのが良いように思われます。
というわけで、日曜大工的なハードウェア制御プログラムを書いたので、プログラムを書き連ねながら考えたことを、ここに『ComThreadを使った「制御プログラムの作り方」』として書いてみました。
2009-11-10[n年前へ]
■MSCommLibを使ったRubyによるシリアル通信プログラム
「MSCommでシリアル」「Ruby Serial Ports under Windows」など。Windows & Rubyでバイナリモードでシリアル通信を行うときには、目を通しておくと良いかもしれないので、以前作ったシリアル通信スレッドクラス"ComThread"の「バイナリ通信向けバージョン」を作ってみることにしようか。