目次
前
次
Processing
Processingは、シリアルインタフェースを利用して
Arduinoと接続し、情報交換するための環境です。
Wikiからの説明を要約すると、次のようになっています。
- オープンソースプロジェクトで、MITメディアラボで開発
- 電子アートとビジュアルデザインのためのプログラミング言語
- 視覚と連動した内容になるので、初心者のプログラミング学習適する
- 電子スケッチブック基本として使える
- Javaを単純化しグラフィック機能に特化している
Javaを基本にしているので、文字列表示は次のように
メソッドを利用できる。
println("Hello Arduino World!");
GUIを利用できるようにするので、JavaのAppletのように
記述する方が雰囲気がわかるでしょう。
// get Font object
PFont font=loadFont("myfont.vlw");
// set Font size
textFont(font,14);
// show strings on screen
text("Hello Arduino World!",100,100);
Javaの経験があれば、次のような描画処理は簡単に
できます。
Arduinoで計測したデータを、ArduinoでグラフィックLCDに
表示するのは面倒ですが、Processingを利用すると簡単に
なります。
Processing開発環境ダウンロード
Processingのプログラム(これもスケッチと呼ばれる)を
ダウンロードするには、次のURLにアクセス。
http://processing.org/
Download Processingをクリックします。
Donation(寄付)が必要に見えますが
No donationにチェックを入れます。
Downloadをクリックします。
自分の環境がどれに合致する確認します。
スクロールダウンして、自分の環境に合致
するファイルをクリックします。
ダウンロードの確認画面が現れるので
OKをクリックします。
Zip形式ファイルでマシンに保存されます。
ダウンロードしたファイルを解凍して、自分
の環境に合わせたドライブかディレクトリに
保存します。
デスクトップにショートカットを作って
おいておくとよいでしょう。
Arduinoとの通信
ProcessingとArduinoのスケッチが、やり取り
するためには、シリアル通信を利用します。
Arduinoのスケッチで利用できる通信関係の
オブジェクトはSerialで、メソッドは以下。
多くのメソッドがありますが、すべて使う必要は
なく、はじめのうちは次のメソッドだけでよい
でしょう。
- begin
- print
- println
- read
- write
メソッドの使い方を理解するために
簡単なスケッチを作成してみました。
#define LedPin 13
char state ;
int xinterval ;
char tmp ;
// The setup() method runs once, when the sketch starts
void setup() {
Serial.begin(9600);
// initialize the digital pin as outputs :
pinMode(LedPin, OUTPUT);
// set interval
xinterval = 500 ;
// set state value
state = 0 ;
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// impress LED */
tmp = LOW ;
if ( state & 1 ) { tmp = HIGH ; }
digitalWrite(LedPin,tmp);
// wait
delay(xinterval);
// update
state++ ;
if ( state == 16 ) { state = 0 ; }
// show state with alphabetic format
tmp = state + 0x41 ;
Serial.write(tmp);
// new line
if ( (state % 8) == 7 ) Serial.println(' ');
}
このスケッチは、LEDを点滅しながら
シリアルインタフェースを利用して
端末に文字を表示します。
端末を利用するには、ArduinoIDEの右に
ある次のアイコンをクリックするだけ。
スケッチでは、3メソッド利用しています。
Serial.begin(????)
beginは、引数に転送レートを指定します。
Serial.write(???)
writeは、0〜255の値をシリアルインタフェースに
出力します。
端末で認識できる文字にするには、ASCIIコードに
変換してから出力しなければなりません。
Serial.println(文字列)
printlnは、改行付き文字列をシリアル
インタフェースに出力します。
改行しない場合、printメソッドを利用します。
今度は、端末で与えた1文字コマンドを利用して
LEDの動作を変更するスケッチを定義します。
#define LedPin 13
#define OFF 0
#define ON OFF+1
typedef unsigned char UBYTE ;
UBYTE cmd ;
UBYTE state ;
int xinterval ;
char tmp ;
UBYTE flag ;
void show_help()
{
Serial.println("? help");
Serial.println("a active flashing");
Serial.println("b break flashing");
}
// The setup() method runs once, when the sketch starts
void setup() {
Serial.begin(9600);
// initialize the digital pin as outputs :
pinMode(LedPin, OUTPUT);
// set interval
xinterval = 200 ;
// clear
state = 0 ;
// clear flag
flag = OFF ;
}
// the loop() method runs over and over again,
// as long as the Arduino has power
void loop()
{
// impress LED */
tmp = LOW ;
if ( flag == ON ) {
if ( state & 1 ) { tmp = HIGH ; }
}
digitalWrite(LedPin,tmp);
// increment
state++ ;
// wait
delay(xinterval);
// command interpreter
if ( Serial.available() > 0 ) {
// get command
cmd = Serial.read();
// judge
if ( cmd == 'a' ) { flag = ON ; }
if ( cmd == 'b' ) { flag = OFF; }
if ( cmd == '?' ) { show_help() ; }
}
}
loopの中に、LED点滅制御とコマンドインタプリタの
2つのシステムを入れてあります。
Serial.available()
availableは、受信バッファに入っている文字数を
返します。受信バッファに文字が入っていれば、0
より大きくなるので、処理しなければならない文字
が入っていることを確認できます。
コマンドインタプリタ
システム間で、コマンド、パラメータのやりとりを
するには、コマンドインタプリタを定義します。
今回は、1文字コマンドでLEDの点滅を制御します。
コマンドインタプリタを定義する場合、ヘルプを
用意して、コマンドを忘れたときの対応ができる
ようにしなければなりません。
Serial.read()
readは、受信バッファから1文字取出すときに
利用するメソッド。
端末では、文字列送信を、指定枠に文字列を入力して
「送信」ボタンをクリックします。
ヘルプに対応する文字を送信すると、Arduinoから
送信された文字列が、端末に表示されます。
複数システムの実現
コンピュータでは、複数のシステムを一度に動かす
ことが要求されます。その場合、通知フラグを利用
して、システム間の同期を取ります。
今回は、flagを利用してLED点滅を制御しています。
Arduino側のスケッチを作ったので、Processing側の
スケッチを定義します。
import processing.serial.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
Serial sci;
int insci;
int inscix;
int xinterval ;
#define XLOC 50
#define YLOC 50
void setup(){
println(Serial.list());
// 表示されたCOMポートの上から4番目を利用
String arduinoPort = Serial.list()[4];
// Arduinoとの接続ポート指定
sci = new Serial(this, arduinoPort, 9600);
// initialize
insci = ' ' ;
inscix = ' ' ;
// delay設定
xinterval = 100 ;
}
void draw(){
// delay 100ms
delay(xinterval);
// 背景=黒
background(0);
// judge
if ( inscix != insci ) {
insci = inscix ;
// show getting character
text(insci,XLOC,YLOC);
}
}
void serialEvent(Serial p){
// get one character
inscix = sci.read();
}
Processingは、Javaベース言語なので、オブジェクトを
生成してしまえば、メソッドが使えるようになります。
シリアルインタフェースを使うので、複数ライブラリを
importしておきます。
import processing.serial.*;
import java.net.URL;
import java.net.URLConnection;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
シリアル用オブジェクトは、Serialクラスオブジェクトを
生成して(コンストラクタ利用)、メソッドを使えるよう
コードを記述します。
Serial sci;
String arduinoPort = Serial.list()[4];
sci = new Serial(this, arduinoPort, 9600);
Arduinoでは、setupとloopの2関数を利用するという
お約束でしたが、Processingでは、setupとdrawの2
関数を利用します。
割込み処理は、xxxEventで表示されるオブジェクト
メソッドの中に隠蔽されています。
これを理解していないと、Event処理=割込みが
思いつかないので、えらく苦労することに。
Processingでは、GUIでの動作を基本とします。
ボタン操作は、矩形領域を関数rectで描画し、マウスカーソルが
その範囲にあるときの、クリックによるイベントドリブン処理を
記述していきます。
矩形領域を利用した単純なスケッチは、以下。
PImage imgNeko ;
PImage imgLoad ;
PImage imgRev ;
PImage imgExit ;
int FRATE = 30 ;
int WX = 600 ;
int WY = 440 ;
int XBEGIN = 20 ;
int YBEGIN = 402 ;
int WIDTH = 50 ;
int HEIGHT = 20 ;
boolean lflag ;
boolean rflag ;
boolean isRangeOk(int x,int bx,int ex)
{
boolean result ;
/* default */
result = false ;
/* judge */
if ( bx <= x && x <= ex ) { result = true ; }
return result ;
}
void setup()
{
/* title caption */
frame.setTitle("Test 01");
/* select framerate */
frameRate(FRATE);
/* select display dimension */
size(WX,WY);
/* select back ground color with WHITE */
background(255);
/* get image */
imgLoad = loadImage("load.png");
imgRev = loadImage("rev.png");
imgExit = loadImage("exit.png");
/* event flag */
lflag = false ;
rflag = false ;
}
void draw()
{
/* button */
image(imgLoad,XBEGIN,YBEGIN);
image(imgRev ,XBEGIN+100,YBEGIN);
image(imgExit,XBEGIN+200,YBEGIN);
/* show Image */
if ( lflag == true ) {
/* clear flag */
lflag = false ;
/* set pointer */
imgNeko = loadImage("neko.jpg");
/* show */
image(imgNeko,20,20);
}
if ( rflag == true ) {
/* clear flag */
rflag = false ;
/* set pointer */
imgNeko = loadImage("nekor.jpg");
/* show */
image(imgNeko,20,20);
}
}
void mouseClicked()
{
/* each branch */
if ( mouseButton == LEFT ) {
/* load */
if ( isRangeOk(mouseX,XBEGIN,XBEGIN+WIDTH) &&
isRangeOk(mouseY,YBEGIN,YBEGIN+HEIGHT) ) {
println("load");
/* set flag */
lflag = true ;
}
/* reverse */
if ( isRangeOk(mouseX,XBEGIN+100,XBEGIN+100+WIDTH) &&
isRangeOk(mouseY,YBEGIN,YBEGIN+HEIGHT) ) {
println("reverse");
/* set flag */
rflag = true ;
}
/* exit */
if ( isRangeOk(mouseX,XBEGIN+200,XBEGIN+200+WIDTH) &&
isRangeOk(mouseY,YBEGIN,YBEGIN+HEIGHT) ) {
println("Exit");
exit();
}
}
/* exit */
if ( mouseButton == RIGHT ) {
exit();
}
}
スケッチを入れたディレクトリのサブディレクトリdataに
利用する画像ファイルを用意します。
関数setupで、必要なボタン領域の内容を読込んでおき
関数drawで、表示します。
ボタン「LOAD」の左クリックで画像を入力して、表示。
ボタン「rev」の左クリックで左右を反転した画像を入力して、表示。
ボタン「EXIT」の左クリックかマウス右ボタンのクリックで終了。
イベント通知フラグを使い、関数drawの中で対応した
処理を実現するのが、Processingスケッチになります。
目次
前
次