USB-IOの使い方(電子回路初心者向き)

はじめに
USB-IOとはパソコンのUSB端子に接続して外部機器と簡単な入出力を行うインターフェース(間を取り持つもの)基板です。大雑把に言うとこれにワンチップマイコンが乗っていてUSBの通信機能と12ビット=1.5バイト分のメモリーの役目を果たします。これを使ってパソコンからLEDやモター、スイッチ、リレー、ブザーなど色々な外部機器を動作させることができます。身の回りには単にスイッチを押せば良いだけっていう事が結構有りますが、これらをパソコンから簡単に制御するのに便利です。(ビット=一つ一つの入/出力信号の単位)

現在はTECHNOKITKm2Netで外観は違うが機能は同じものがキット\1500、完成品\2500で販売されています。たった数点の部品を半田付けするだけなのに完成品が\1000も高いのはなるべくキットを自分で組み上げることを推奨しているのではないかと筆者は勝手に考えています。なにしろ中学生の教材にも使っているとのことなので、初めての方でも説明書を良く見れば30分もあれば組み上げられると思います。説明書は懇切丁寧には書いてありませんが必要にして十分です。これは電子工作の基本が身につくように(回路図と実際の部品や配線の対応とか)敢えて手取り足取りの説明をしていないのだとこれまた勝手に理解しています。


                TECHNOKIT  USB-IOV8K                              Km2Net USB-IO (KIT)


さて、このUSB-IOを使いこなすにはこのUSB-IOのハードウエアとこれをコントロールするソフトウエアのことを少しだけ知っておく必要があります。ここではそれらのことを簡単に述べています。

このUSB-IOの電源はUSBコネクターから供給される5V電源です。特にこのUSB-IOを動作させるだけなら外部電源は不要です。
ドライバーも不要でパソコンに繋げるとHID(Human Interface Device)として認識されます。
動作としてはUSB1.1なのですがホストコントローラーによってはUSB2.0での高速動作も可能な場合もあります。

最終信号は12ビットの入出力端子を持っていてこれらはポート0とポート1のグループに分けられ、ポート0はP00〜P07までの8ビット、ポート1はP10〜P13までの4ビットの信号名になります。デジタルの場合、ビット(ここでは=ポート)は1からではなく0から数えるのが慣例になっています。

これらの各ビットは入出力共用で双方向バストランシーバー(PCのプリンターポートも)のような感じでブロック図としてはこんな感じ↓に捉えれば良いと思います。

各ビットの出力はあまり大きな電流を取り出し、あるいは吸い込みできません。せいぜい数mAなのですが、ポート0とポート1は少し動作電流の仕様が違っていてポート0が約1mA、ポート1が約15mAとなっていますので外部機器を動作させるためには何らかのドライバー回路(駆動回路)が必要となります。ドライバー回路無しで直接駆動できるのは小入力のフォトモスリレーかポート1につないだLED、フォトカプラーくらいだけです。

各ビットの出力電圧は5VかOV(GND)です。デジタルなので基本的に中間の電圧はあり得ません。
出力電圧が5Vの時を論理値”1”またはLogicHigh(単にH:ハイ)と呼び出力電圧が0Vの時を論理値”0”またはLogicLow(単にL:ロー)と呼びます。(実際には出力電圧をテスターで測るとH(1)は4〜5V、L(0)は0〜0.5Vです)

ポート0の8ビットで0〜255の数値を表すことができます。
1つのビットがH(1)かL(0)のどちらかの状態なので8つのビットの組み合わせは256通り存在します。8ビット全部がL(0)の時が数値の"0"、全部がH(1)の時が"255"と定義します。

他の状態のときはどうかというと、例えばポート0が下表の状態だったとするとポート0は今”170”の数値を表していることになります。(表は最上行を左から右に読んで次の行へ)

P07 P06 P05 P04 P03 P02 P01 P00 ←が
5V 0V 5V 0V 5V 0V 5V 0V ←だったとすると(電圧)
←が論理値(2進数)で
128 64 32 16 8 4 2 1 ←がビットの重み(位)
128 0 32 0 8 0 2 0 ←が論理値と重みの積
上の行を加算 128+0+32+0+8+0+2+0=170 ←が10進数となる。

ちょっと分かりにくいかもしれませんが要はP00=1、P01=2、P03=4・・・・P07=128というようにビットに重みが対応しているということです。
ビットの重みというのは分かりにくい表現だと思いますが10進数で云うところの位(くらい)と考えると分かりやすいと思います。
例えば10進数39800という数値は 各位の重みX値の総和 ということになります。

10000 1000 100 10 1 ←重み(位)
30000 9000 800 00 0 値X位

10進の場合の位は 一(1)、十(10)、百(100)、千(1000)、万(10000)・・・・・・・となり桁上がりする毎に10倍づつ増えますが
 2進の場合の位は 1、2、4、8、16、32、64,128,256,512 ・・・・・ のように2倍づつ増えていきます。
文章は左から右に向かって読むので並び方が逆ですが数字としては位の低いほうが右で高い方が左という慣例に従っています。

ここで覚えておくべきはビットの重み(位)1,2,4,8、16・・・ということです。これはデジタルの信号線をある単位でまとめて扱う時の基本中の基本なので理解しておく必要があります。

同様にポート1は4ビットなので0〜15までの数値を表すことができます。しかし実はこれらの数値自体にはあまり意味はありません。ここでは計算をするわけではなく各ビットをスイッチとして使う場合が殆んどなので各ビットがH(1)かL(0)かが重要です。しかし、プログラム上では各ビットそれぞれ単独にコントロールすることはできません。ポート0ならばP00〜P07まで、ポート1ならばP10〜P13まで一度に書き換えることしかできないためソフト的にこの数値が必要なだけです。

もう一つ注意しておかなければならないことにロー(Low)アクティブとハイ(High)アクティブという言葉があります。
目的の動作をさせるためにビットの出力が論理値”1”(High)が必要なのか論理値”0(Low)”が必要なのかということです。論理値”1”で目的の動作をすることをハイアクティブ(正論理)、論理値”0”で目的の動作をすることをローアクティブ(負論理)といいます。これは回路の組み方によって変わります。

例えばLEDを点灯させることを考えると上図左のように結線してUSB-IOのP10がHigh(5V)の時点灯させることをハイアクティブ、右のように結線してP10がLow(0V)の時点灯させることをローアクティブといいます。(現実的には左のハイアクティブでは何らかの付加回路が必要です)


以上を踏まえて、このUSB-IOを動作させるためにはソフトウエア(プログラム)が必要です。
プログラムというと難しそうですが、たった数個のコマンドを覚えるだけで動作させることができます。手っ取り早いのはフリーウエアのHSP(Hot Soup Processor)とかAB(ActiveBasic)VB(Visual Basic)などの言語です。USB-IOのベンダーIDやプロダクトIDも公開されているのでその気になれば他の言語でもOKです。 

中でもお勧めなのはHSPです。HSPはインタープリター言語なのですがZ80などの時代と違って今はCPUが格段に早くなっているので大抵の機器を制御するのにスピードが問題になることはありません。なんといっても無料でとっつき易く簡単なことはC言語の比ではありません。主にゲーム用に開発された言語なのでグラフィック関係は特に充実していますがWindowsAPIを使ったちょっと高度なWindowsプログラムも開発できます。現在のVer.3.Xになってからは浮動小数点実数も扱えるようになったので天文計算プログラミングにも使えます。
最新のRCバージョン(HSP3.21RC3)ではUSB-IOを操作するプラグイン(hspusbio.dll)が同梱されより使いやすくなっています。
このプラグインはK-Kさん が開発したUSB-IOのディバイスドライバーとも呼ぶべきもので無料公開されてていてベンダーIDやプロダクトIDのことなど意識しなくてもOKです。このプラグインのおかげでUSB-IOが飛躍的に使いやすくなっています。

ここではHSPを前提に記述しますがUSB-IOに対するコマンド自体は公開DLLを使うかぎりVBやABでも同じです。
まず初めにHSPをダウンロードしPCにインストール(Windows用)されているものとして話を進めます。

実験のため上図LowActiveの回路でLEDを点滅させることを考えます。具体的にはインターバルタイマーで使っているLEDを点滅させます。
HSPのスクリプトエディター(hsed3.exe)を開いて

#include "hspusbio.as"
uio_out 1,0


と打ち込みます。
たった2行のプログラムですが、F5を押してプログラムを実行します。
真っ白なウインドウが現われてLEDが点灯すると思います。

このプログラムが意味するところは
最初の#include "hspusbio.as"はUSB-IOのコマンドを使用するという宣言でUSB-IOを使う時は必ず最初に書きます。
次のuio_out 1,0がUSB-IOに対するコマンドでUSB-IOのポート1に0を書き込めという意味になります。
ポート1が0ということはP10〜P13の全てがLow(0V)となってLEDが点灯します。

次にウインドウを閉じてスクリプトエディターに戻りuio_out 1,0のところをuio_out 1,255に変更しF5を押してプログラムを実行します。
今度は点灯していたLED が消灯するはずです。これはポート1に255を書き込みP10〜P13の全てがHigh(5V)となってLEDが消灯します。

すでにお気付きかと思いますがポート1は4ビットなので15までしか扱えないのですが上位の4ビットは無視されるのでuio_out 1,255と書いてもuio_out 1,15と書いても同じです。
また実験の回路ではP10しか使っていないのでLEDを点灯させる時はuio_out 1,X (X=偶数=0,2,4,6・・254)でもOKです。同様に消灯させる時はuio_out 1,X (X=奇数=1,3,5,7・・255)でもOKです。

ここで注意しておかなければならないことは、例えば1を書き込むということは2進数では 0001であり、14ならば 1110を書き込むことで前の状態が何であろうとP10〜P13まで"0"も"1"も同時に書き込まれるということです。だからあるビットだけ書き込むということはできないのですが、ソフト的にあるビットだけ書き込むように見せかけることはできます。

以下を実行すると
#include "hspusbio.as"
repeat
uio_out 1,0
wait 50
uio_out 1,15
wait 50
loop


こうなります。簡単ですね。

USB-IOのコマンド詳細はK-Kさんのプラグインhspusbio.dllに同梱されているhspusbio.txtに書いてありますのでインストールしたフォルダーを検索してください。またHSPのコマンド詳細はスクリプトエディターのヘルプから HSPマニアル目次/プログラミングマニアル基本仕様ガイドを一通り読むことをお勧めします。


USB-IOはこの出力コマンドだけで大抵のことは事足りるのですがせっかくですから入力コマンドのことにも触れておきます。
今まではPCから外部機器を作動させるための方法でしたが今度は、例えばドアが開いたとか、電燈が点いたとか外部機器からの情報を取得することもできます。

入力機能を使ってスイッチが押されたかどうかを調べてみます。
実験回路としては以下のようなものです。矢印の部分をP00からP07までどこに繋いでもOKです。スイッチと50オームの抵抗は単なるリード線でGNDと各ポートをショートさせるだけでも良いのですが万一間違ってVCCとGNDがショートしてしまうと危険なので50オームの抵抗を入れてあります。間違ってもVCCとGNDをショートさせないで下さい。最悪PCが壊れます。


以下のプログラムを前述のエディターを使って入力します。
#include "hspusbio.as"
uio_out 0,255
repeat
uio_inp data,0
wait 1
title ""+data
loop


これを実行すると前回と同様に真っ白なウインドウが開きます。ここでスイッチをON/OFFするとウインドウ一番上のタイトルバーに数字が表示されるはずです。スイッチOFFの時は255、スイッチONの時は255−ビットの重みの数値となります。例えば上図のようにP07につないでスイッチONすると255−128=127が表示されます。この数値でどのビットに繋がったスイッチが押されたかが分かりますのでスイッチをドアなどに付けておけばドアが開いたかどうか検知することができます。もちろん複数のポートを使って複数の状態を一度に監視することもできます。

ここで入力として使用する場合注意しておかなければならないことは上のプログラムのように最初にUSB-IOの出力をHighに保っておかなければならないということです。2行目のuio_out 0,255がそれをしています。出力がLowだとスイッチONのときとOFFの時の区別がつかないからです。
uio_inp data,0がUSB-IOのポート(=ビット)の状態を読み込んでくるコマンドでdataという変数にP00〜P07の状態を数値にした値が読み込まれます。repeat〜loopはこの間を繰り返す命令(コマンド)なのでポート0の状態を監視することになります。

ここでは詳しく触れませんがUSB-IOにはもう一つ別の使い方があります。今まではモード0を前提に記してきましたがモード1というのがあってデーターの入出力時にパルスを出して外部機器に知らせることができます。パソコンのプリンターインターフェースのストローブ信号のような信号をだしてデーターのやり取りのタイミングをとることができます。本来USB-IOはUSB−パラレル変換用に開発されたと聞いています。

ここまでくればもう後は工夫次第で色々な身近な機器を作動させたり監視したりすることができますよね。

2010/04 記

inserted by FC2 system