【変更】以下はArduino1.0まで対応したプログラム内容です。
特にシリアル通信においては、Arduino2.0使用の際、バイト送信する場合、
Serial.print(value,BYTE);
のかわりに、
Serial.write(value);
を使用してください。
前回までは、Arduino基盤に接続したセンサなどからProcessingの画像を動かしていましたが、今回はその逆で、Processingで制作した画像からArduinoを制御したいと思います。前回同様合図用のデータを送り、確認し合いながら通信します。Processingでマウスで動かすことができるスライダをつくり、256段階の値をArduino側に送り、PWM出力を用いてLEDの明るさを調節できる内容とします。Processing側から操作するので、まずProcessing側のプログラムから書きます。
Processingのプログラム:
//シリアルライブラリの取り込み
import processing.serial.*;
Serial port;
//X座標の変数
int x=0;
void setup(){
size(255,100);
//シリアルポートの設定
port=new Serial(this,"/dev/tty.usbserial-A4001Kjl",9600);
}
void draw(){
background(100);
line(x,0,x,height);
}
void serialEvent(Serial p){
//データ数が0個より多いとき
if(port.available()>0){
//X座標を送信
port.write(x);
//Arduinoからの合図用データを
//読み込んでバッファを空にする
port.read();
}
}
void mouseDragged(){
//ドラッグ中のX座標にマウスX座標を
//最小値0,最大値255で入れる
x=constrain(mouseX,0,255);
}
void keyPressed(){
//sキーを押したら
if(key=='s'){
//通信開始用データ送信
port.write(0);
}
}
今回は、キーボードの「s」キーを押すことでシリアル通信を開始することにしました。「s」キーを押さなければ、Processing、Arduinoの両方のプログラムは、どちらも待機中となります。そのため、Processing側から「s」キーを押して、通信開始のきっかけとなるデータを1個(1バイト分)送ります。
Arduino側では、11番ピン(PWMピン)にLEDのプラス側を、GNDにマイナス側をつなぎます。必要に応じてその間に抵抗(220Ω)を直列つなぎします。
Arduinoのプログラム:
//読み取り値の変数
int val=0;
void setup(){
//シリアル通信開始
Serial.begin(9600);
}
void loop(){
//データが0個より多いときの時
if(Serial.available()>0){
//データの読み込み
val=Serial.read();
//合図用データ送信(1バイト)
Serial.write(65);
}
//アナログ出力(11番ピン)に読み込み値を入れる
analogWrite(11,val);
}
手順としては、
(1)両方のプログラムが開始される。
(2)合図用データの待機中。
(3)Processingから「s」キーで通信開始用データを送信。
(4)Arduinoのバッファ内データを数える。
(5)Arduinoバッファ内データが1個以上ならデータ読み込み。
(6)その結果、Arduinoバッファ内データが空になる。
(7)Arduinoから合図用データ送信。
(8)Proccessingバッファ内データを数える。
(9)Processingバッファ内データが1個以上ならX座標データ送信。
(10)合図用データを読み込み、バッファを空にする。
*以後は、(4)へ戻り通信を繰り返す。
追記:
上記プログラムで通信が途切れてしまう場合、ArduinoよりProcessingの処理速度が速すぎるのかもしれません。Processingのvoid setup(){...}内でframeRate(30)程度にするか、draw(){...}内にdelay(20)程度を挿入し少しスピードダウンすると安定するかもしれません。
あるいは、ProcessingからArduinoへ一方向的にデータを送る内容なので非同期通信にしてもいいかもしれません。その場合もProcessingのvoid setup(){...}内でframeRate(30)程度にスピードダウンし、void draw(){...}内にport.write(x)を入れて(serialEvent()は使わず)30fpsで定期的に送信し、Arduino側でそのデータを受け取るようにします(合図用データは送る必要はありません)。
関連:
「
Arduino-Processing シリアル通信1」(一つの値を送る/非同期通信)
「
Arduino-Processing シリアル通信2」(複数の値をバイトで送る/同期通信)
「
Arduino-Processing シリアル通信3」(大きな値を複数送る)
「
Arduino-Processing シリアル通信5」(複数の値を文字列で送信する)
「
Arduino-Processing シリアル通信6」 (2台のArduinoとProcessingを通信させる)