LabVIEWでデータ測定用のハードウェア(DAQ)を扱おうという初心者の方に向けて、道しるべになるような情報を発信していこうという試みです。
シリーズ7回目としてDAQでデジタル入出力を扱う際のポイントについて紹介します。
この記事は、以下のような方に向けて書いています。
- デジタル入出力のプログラムについて知りたい
- ポート形式って何?
- デジタル入力データの保存の方法は?
- デジタル出力のデータの指定の仕方は?
もし上記のことに興味があるよ、という方には参考にして頂けるかもしれません。
なお、前回の記事はこちらです。
デジタル入力について
前回まででアナログの入力、出力については一通り説明してきました。サンプルを軸に紹介しているので、もちろんサンプルのまま使用することもできますが、サンプルをベースに自分の目的にあったプログラムに組み替える際の参考になればうれしいです。
そして本記事ではデジタル入出力のタスクを紹介していきます。
これまで同様サンプルプログラムが参考になるので、サンプルと照らしながら適宜サンプルと照らしながら確認してもらえればいいかなと思います。
アナログ信号を扱っていた場合には波形グラフを使用していましたが、デジタル信号を扱うにはデジタル波形グラフという専用のグラフを使用します。
実はここ以外はアナログ入力とタスクの構成の考え方などはだいたい同じです。
違う点としては
- チャンネル設定時の指定方法
- 読み取りの関数から出力されるデジタルデータ
といったことが挙げられます。
チャンネル設定時の指定方法
チャンネル設定時の指定方法とは、ライングループタイプと呼ばれるもので、
- すべてのラインに1チャンネル
- 各ラインに1チャンネル
という選択肢があります。
ここで言う「ライン」とは、デジタル信号を扱う端子のことです。ハードウェアを見てD0.0やD0.1、D0.2などと書かれている際の、点の後の0や1、2の部分の数字のことです。
一方で、点の前の数字(D0.1で言うところの0)はポートの番号を指します。DAQ製品は、物に依りますが例えばライン8つで一つのポートを形成します。そのため読み方で言えばD0.1は「ポート0のライン1」ということになります。
話がそれましたが、ライングループタイプのそれぞれは、すべてのラインをひと固まりで1チャンネルとみなすか、あるいはそれぞれのラインは別のチャンネル扱いとするかという違いになります。
ここのチャンネルという表現は、DAQmx読み取りの関数で指定する1チャンネル、あるいはNチャンネルの設定に関係します。
個人的には、「すべてのラインに1チャンネル」という表現は分かりづらく、「すべてのラインを1チャンネル(とみなす)」とかの方が分かりやすいかなと思ったりします。(英語表記はone channel for all linesになっているようです)
読み取りの関数から出力されるデジタルデータ
直ぐ上の画像で紹介しましたが、デジタルタスクでのDAQmx読み取りの関数では二通りのデータの表し方があり、
- 配列
- 波形
があります。
配列については、アナログ入力のときになかったポート形式を紹介します。このポート形式とは、その名のとおりポートごとのデータを表わす状態です。単一の数値でポートの状態を表して、各ラインの0(LOW)、1(HIGH)を知ることができます。
ポートには複数のラインが含まれているのにそれを単一の数値で表す?この部分が、不慣れな人にとっては少し難しい部分になるかもしれません。
単一の数値で表している背景はこのように考えます。
- ライン0、ライン1、ライン2、・・ライン7をそれぞれ2の0乗、1乗、2乗、・・・7乗のビット値として表すことで、単一の数値とする(1ポートにラインが8つの場合)
例えば、ある瞬間のポートのライン0から7までのデジタル値測定が
(ライン0、ライン1、ライン2、ライン3、ライン4、ライン5、ライン6、ライン7)=(TRUE、FALSE、TRUE、TRUE、FALSE、TRUE、FALSE、FALSE)
となっていたとします。このときには
2^0×1+2^1×0+2^2×1+2^3×1+2^4×0+2^5×1+2^6×0+2^7×0=45
となるので、DAQmx読み取りの値から出るのは45という値になります。
次のサンプリングで
(ライン0、ライン1、ライン2、ライン3、ライン4、ライン5、ライン6、ライン7)=(FALSE、FALSE、FALSE、FALSE、FALSE、FALSE、TRUE、TRUE)
となっていた場合には同じ要領で考えると
2^0×0+2^1×0+2^2×0+2^3×0+2^4×0+2^5×0+2^6×1+2^7×1=192
となります。
これは、デジタル入力のプログラムで「すべてのラインに1チャンネル」としてDAQmx読み取りを「デジタル U8 1チャンネル1サンプル」としたデバイスに対して、同じライン番号同士を配線した別のデジタル出力用のデバイスを動かして簡単に確かめられます。
以下はデジタル出力の方をNI MAXのテストパネルで行った際の例です。
なお、U8としているのはポートにラインが8個あるからです。例えば、NI 9403はポートにラインが32個あるため、たとえチャンネルの指定でそのうちのライン0からライン7までの8個しか指定していなくても、DAQmx読み取りの指定はU8ではなくU32とします。
一方で、ライングループを「各ラインに1チャンネル」とすると、以下のような結果になります。
複数のラインを選択している場合、それは複数チャンネル扱い(各ラインは独立したチャンネルとみなされるため)なので、DAQmx読み取りはNチャンネルを指定する必要があります。
テストパネルの出力の方は左からポート7、ポート6、・・・となっているのに対し、プログラムで配列は左からポート0、ポート1、・・・と左右が反転していることに注意します。
ただ、各ラインに1チャンネルの場合には、数値ではなく直接ブールで表した方がわかりやすいかもしれません。DAQmx読み取りにはブールで表す選択肢もあります。
ここまで紹介したものはどれも「1サンプル」でしたが、これをNサンプルにするとDAQmxタイミングで指定したサンプリングレートの速さで取得したデータを複数個、DAQmx読み取りのサンプル数/チャンネルで指定した数だけ表示するようになります。
上記の配列の場合、数値やブール値によってその時々のデジタル入力の結果を表わせるのですが、そこには時間の情報がないという欠点があります。(サンプリングレートを指定しているのでその情報を使えばもちろんわかりますが)
これに対して波形の場合には、いわゆるアナログの波形データと同様で、始まりの時間(t0)と時間間隔(dt、サンプリングレートの逆数)そしてY(データ)が含まれています。
例えばグラフに表示する際にも時間情報ともども表すことができます。ただし、NIサンプルファインダのサンプルはデフォルトではグラフのX軸は実時間を表わしません。グラフを右クリックして「タイムスタンプを無視」のチェックマークを外す必要があります。
なお、波形データとして読み取る場合であっても、ライングループの考え方は同じです。
「すべてのラインに1チャンネル」であればDAQmx読み取りは「波形、1チャンネル、Nサンプル」とし、「各ラインに1チャンネル」であれば「波形、Nチャンネル、Nサンプル」にするのが基本です。ただし、デジタル波形グラフは1チャンネルでもNチャンネルでもどちらにも対応できます。
どのような形でデジタルのデータを得たいかで配列なのか波形なのかDAQmx読み取りの設定を変える必要がある、ということですね。
デジタルデータの保存
さて、デジタルデータを測定してこれを保存することを考えます。
一番オススメなのは、アナログ入力の時同様、TDMSファイル形式で保存することです。もしデジタルの波形データとしてDAQmx読み取りの関数を設定していても、TDMS書き込みの関数にそのまま配線することができるため、プログラムが圧倒的に楽です。
ただし、TDMS書き込みはなぜか「デジタル波形の配列」を受け付けてくれません(アナログの波形配列は受け付けたのに・・・)そのため、ライングループで「各ラインに1チャンネル」は基本使用しないことになると思います。
また、TDMS書き込みの関数へのチャンネル名入力を特に配線しないと、結果としては最初のラインのみ名前が付きますがあとは「名称未設定1」などというデフォルト名がつくことになるのでそこは注意する必要があります。
もし何らかの理由でライングループを各ラインに1チャンネルにする必要がある場合、チャンネル名入力で分けるのではなくグループ名入力で分ける方法が考えられます。
この場合、TDMSファイルをExcelで開くと、各ラインの結果は異なるタブ(シート)に保存されることになります。
一方で、TDMSではないファイル形式に保存する場合にはどうするか。例えばcsvファイルのような場合です。
これはもう、どのようにデータを保存したいかによると思います。例えばポート形式であればこれは数値なので、単に数値のデータを保存するだけということになります。
ちなみに、上の図の例でBD3の後のBE3が0となっているのは、示したブロックダイアグラムで指定しているNI 9403がシミュレーションデバイスでライン0から7を構成していて、この場合にはライン0から7までが全てHIGHになった後はまたはじめ(ライン0から7までがLOW)に戻っているためです。
この方法は、各ラインごとのHIGH、LOWが分かりにくいという欠点があります。もしこれを明確に示すためには、各ラインごとのHIGHを1、LOWを0として保存する方法が考えられます。
例えば、DAQmx読み取りでは波形を選択し、これを波形パレットの中のデジタル波形パレット、さらにデジタル変換のパレットに進むとある「デジタルからブール配列に変換」の関数を使用してブールの2次元配列とし、そしてブールパレットにある「ブールから(0,1)に変換」とForループの自動指標付けを駆使して変換する方法があります。
なお、この方法、ライン0がH列に、ライン1がG列に、という並びでライン7がA列となるので注意が必要です。
もしこの順番を逆(A列をライン0)にする場合には 「ブールから(0,1)に変換」 が入った内側のForループの出力トンネルと外側のForループの出力トンネルの間に「1D配列反転(配列パレット)」を入れます(下で紹介しています)。
あるいは、文字列にフォーマット関数を用いるという方法もあります。この関数はデジタルデータを文字列に変換する際にはTRUE、FALSEと表現します。
以下の例がその実装例です。1D配列反転を入れているおかげで、A列がライン0、B列がライン1、・・・となっています。
結局はどのような形式でデータを保存しておきたいかで適切なものを選びます。
デジタル出力について
デジタル出力のプログラムも、アナログ出力のプログラムと同様にDAQmx書き込みの関数に出力したいデータを渡して、ハードウェアタイミングで出力したいのであればDAQmxタイミングの関数でレートを指定します。
そして、デジタル入力の時と同じようなデータの指定の仕方として、ポート形式とか波形とか選びます。考え方は同じなので、デジタル入力ができるのであればもうデジタル出力の指定の仕方も難しくないと思います。
一応それぞれの形式について例を紹介します。まずはポート形式について考えてみます。
ラインの指定を例えばあるデバイスのport0/line0:7としていたとしていて、ライングループタイプを「すべてのラインに1チャンネル」(デフォルト設定)としていた場合、書き込むデータが1というのはport0のline0がHIGH、その他(line1からline7まで)はLOWとなる状態を表します。
なお、上の図で書き込むデータとして1を二つ指定していますが、これは仕様上データを2つ以上書き込む必要があるためです。
書き込むデータが2であれば、port0のline1がHIGH、その他はLOWです。書き込むデータが4であればport0のline2がHIGH、その他がLOWです。
間を飛ばしましたが、書き込むデータを3と指定している場合には、port0のline0とline1がHIGH、その他がLOWです(2^0+2^1=3)。書き込むデータを10としていると、line1とline3がHIGHで、その他がLOWです(2^1+2^3=10)。
port0のすべてのlineをHIGHにする場合には、255を指定すればいいということになりますね。
これらのデータがDAQmxタイミングで指定したレートで出力されます。(DAQmxタイミングの関数を使用していた場合)
波形の場合には、デジタル波形の時間情報も指定します。ここに関しては、「ブール配列からデジタルに変換」関数が便利です。フロントパネル上ではブール制御器のTRUE、FALSEを指定するようにして、これをデジタル用の波形データに変換する関数になっています。
実際に各ラインで出力させたいパターンをフロントパネルで表現し、これを指定したサンプリングレートの波形とするように構成します。ポート形式の指定ではわかりにくいよ、という場合にはこの組み方を検討するといいと思います。
出力の場合には、ライングループタイプとして「各ラインに1チャンネル」を指定するのはあまりオススメしません。ポートや波形で全ラインをまとめて指定するのに、チャンネルを分けるのは面倒(波形で指定するなら、波形配列を作らないといけない)だからです。
また、アナログ出力の際にも注意点があったように、デジタルの出力であっても、「プログラムが終わったらすべてのラインはLOWになる」というものではありません。プログラム終了時にLOWにしたい場合には、プログラム終了直前で全ラインがLOWになるようなプログラムを書く必要があります。
ニブル構成に注意
最後に特定デバイスを使用する場合の注意点について少し紹介します。
基本的にデジタルデータを扱うDAQデバイスは入力も出力もどちらも扱えるはずです(私が知っている限り・・・)が、もしDAQデバイスとしてNI 9401という製品を使用する場合には、「ニブル」構成であることに注意する必要があります。
具体的に何を気を付けるかというと、NI 9401はラインが合計8個あるのですが、その中で例えば2個だけデジタル入力、残り6個をデジタル出力、という構成ができず、必ずライン0から3の4個は入力か出力のどちらかで全部統一する、ライン4から7も入力と出力のどちらかに統一する必要がある、というデバイスになっています。
0から7のすべてのラインを入力、あるいは出力も問題ありません。ライン0から3の中、およびライン4から7の中で、入力と出力の混在ができないことに気を付けます。
なぜこれがニブルと呼ばれるか、それは通常ライン8個を1バイトとみなすのに対してその半分をひと固まりとするため、バイト(つづりは違いますが英語biteで噛むという意味)より弱いニブル(英語nibbleでかじるという意味)だから、というシャレのようです。
さて、デジタル入出力についてアナログ信号に対するタスクの時とはまた違った考え方を紹介してきました。アナログ信号のときには波形や数値の配列でアナログデータをそのまま扱うのに対し、デジタルデータであるのにも関わらず数値で表すポート形式は慣れないと難しいかもしれませんが、理屈さえわかれば使えるようにはなると思うので、必要に応じて波形データと使い分けつつ慣れていければいいかなと思います。
ここまで読んでいただきありがとうございました。
コメント