「プログラミングを楽しもう」の第5章もLINX無しで楽しめるように改造してみましょう。
LabVIEW Community Editionで「プログラミングを楽しもう」をまだダウンロードしていない方は下記リンクからダウンロードしてください。
「プログラミングを楽しもう」のダウンロードサイト
第5章ではデジタル入力に接続したタクトスイッチの状態で、PWM出力に接続したクーリングファン制御するプログラムについて説明しています。
![MC051199.JPG MC051199.JPG](https://forums.ni.com/t5/image/serverpage/image-id/295627i5146E539D5941F9D/image-size/large?v=v2&px=999)
第6章ではアナログ入力だけでしたので、Arduinoから一定間隔でデータを送信し、LabVIEWではデータを受け取るだけで済みましたが、第5章では入力と出力を使っているのでボタンの状態を調べたり、ファンへのPWM出力を変更したりする必要があります。LINXのようにまじめにコマンドとレスポンスを考えてプログラムするとArduino側もLabVIEW側もそれなりに面倒です。
そこで、簡便に、Arduino側は一定間隔でボタン状態の送信しByteデータを受信したときにPWM値を変更することにします。LabVIEW側は、ボタン状態が送られてくるのを待って、送られてきたデータを受け取り、その後PWM値を出力することにします。こうすればArduino側のペースでデータのやり取りが行われます。
とりあえずArduinoのプログラムは以下の「SendButtonState-ReceiveFanPWM」を使います。
Arduinoのサンプルプログラム「スケッチ例 > 02.Digital > Button」と、「スケッチ例 > 04.Communication > SerialCallResponse」を組み合わせて作りました。
途中経過のプログラム「ButtonInFanOut」と「ButtonInFanPWM」も添付しました。
// constants won't change. They're used here to set pin numbers:
const int buttonPin = 8; // the number of the pushbutton pin
const int fanPin = 9; // the number of the Fan pin
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int fanSpeed = 0;
void setup() {
// initialize the pushbutton pin as an input:
pinMode(buttonPin, INPUT);
Serial.begin(115200);
}
void loop() {
float t = micros();
// read the state of the pushbutton value:
buttonState = digitalRead(buttonPin);
Serial.println(buttonState);
delay(1);
if (Serial.available() > 0) {
// get incoming byte:
fanSpeed = Serial.read();
analogWrite(fanPin, fanSpeed);
}
while((micros()-t)<10000){}
//wait 10ms
}
LabVIEW側はLINXで書いたプログラムをできるだけ変更したくないので、シリアル送受信のプログラムを別ループで動かして、ローカル変数で状態を共有することにします。
改造前のプログラム
![5-2_FanControlWithLINX.png 5-2_FanControlWithLINX.png](https://forums.ni.com/t5/image/serverpage/image-id/295628i99B532EC3BDB82A1/image-size/large?v=v2&px=999)
LINX無しで動くように改造したプログラム
![5-2_FanControlWithoutLINX.png 5-2_FanControlWithoutLINX.png](https://forums.ni.com/t5/image/serverpage/image-id/295629i863CBDF557DD2986/image-size/large?v=v2&px=999)
シリアル通信のループ(上のWhileループ)で送受信している「Button State」と「PWM(0-255)」をファン制御のWhileループで共有するためにローカル変数を使っています。
改造したプログラムを添付します。
「5-1_PushCounterWithoutLINX.vi」
「5-2_FanControlWithoutLINX.vi」
「5-3_FanControlWithLongPushStopWithoutLINX.vi」
「5-4_FanControlWithLongPushImmediateStopWithoutLINX.vi」
「5-5_ Push Counter(LatchWhenReleased)WithoutLINX.vi」
「5-6_Fan Control with Long Push Stop(LatchWhenReleased)WithoutLINX.vi」
ローカル変数は、一般的なプログラム言語では変数に相当するものですが、LabVIEWではデータフローに縛られないジョーカー的な存在です。意識して使わないとバグの原因になりますので、以下の説明をよく理解したうえで使います。
ローカル変数とグローバル変数を慎重に使用する
キューを使ってループ間でデータを受け渡す場合にはデータを確実に受け取るか、削除しないとキューにデータがたまってしまいますが、ローカル変数を使えば必要な時だけ参照することができるので手が抜けます。