2011年9月28日水曜日

Arduino-Processingシリアル通信

以下はProcessingプログラム上でマウスクリックしてArduinoボード上のLEDを点灯/消灯させるプログラムです。ProcessingとArduinoを連携させるにはシリアル通信という手段を用います。
まずProcessingのプログラムから行います。

import processing.serial.*;
Serial myPort;

void setup(){
myPort=new Serial(this,Serial.list()[0],9600);
}

void draw(){
//描画内容は特になし
}
void mousePressed(){
myPort.write(1);
}

void mouseReleased(){
myPort.write(0);
}

シリアル通信を行うためには、シリアル通信用のライブラリを導入する必要があります。
ProcessingのSketch>Import Library/Serial I/Oを選択すると、
import processing.serial.*;
がプログラムに書き足されます。
今回は画面上をクリックするだけで特に描画しないので、draw(){}内は空白です。
あとはmyPort(名前は任意)を設定し、setup(){}内にシリアルポート設定を上記のように書き足せばシリアル通信を行うことができます。
myPort.write()によって、()内の数値をArduinoに送信するプログラムを書き足します。
マウスを押した時に1を、マウスを放した時に0を送信することにし、Arduino側では1の値を受け取ったらLEDをオンにし、0を受け取ったらオフになるようにします。
マウスクリックする際には、Processingをランさせたときに表示される画面上をクリックしてください(100×100ピクセルのグレーのウィンドウが表示されます)。

以下はArduinoのプログラム:

void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600);
}

void loop(){
if(Serial.available()>0){
if(Serial.read()==1){
digitalWrite(13, HIGH);
}else{
digitalWrite(13, LOW);
}
}
}


Arduino側では、Serial.begin()によってシリアル通信開始を設定します。括弧内の9600は通信速度でありこのままの設定で構いませんが、Processing側と設定速度を同じにしておきます。
Serial.available()によって、Processing側から何個のデータが送られて来ているかをチェックします。Serial.available()>0というのは、受信データが0個より大きいとき、つまり1個データを受信したときに以下のプログラム(LED点灯/消灯)を実行するということになります。
受け取ったデータをSerial.read()で読取り、その内容が1であればdigitalWrite(13, HIGH)によってLEDを点灯させ、0であれば消灯させるという条件式になっています。
つまり、Processing側でマウスを押したとき(押し続けているとき)オンになり放したらオフになります。

この通信の場合は、Processing側からデータを送信し、Arduino側が受信する内容になります。
その逆でArduinoからデータを送信して、Processing側が受信してProcessingでプログラムした描画内容を操作するという場合のサンプルはこちらを参考にしてみてください(建築発明工作ゼミ2008:シリアル通信1)。

また、Xbee、Bluetoothなどを使えばワイヤレス送信させることも可能です。
Xbeeのサンプル
Bluetoothのサンプル
あるいは、インターネット越しに操作することも可能です。
ネットワークのサンプル

Arduinoの基本

Arduinoのセッティング
Arduinoサイトの「Getting Started」ページに、MacOSX、Windows、Linuxごとのセッティングの説明があるので、それに従ってセッティングします。
OSがWindowsの場合やArduinoボードが旧型のDuemilanoveやDiecimilaなどの場合は、付属のドライバソフトをインストールする必要があります。

ArduinoボードをUSBケーブルを通してパソコンに接続します。
Tool>Boardから使用しているArduinoボードのタイプを選択。
Tool>Serial Portから一番上のポートを選択。
動作確認のため次のプログラムをArduinoボードに書き込みます。
File>Examples>1.Basics>Blink
以下がBlink(LED点滅)のプログラムです。
Arduinoボード上端にデジタルピン0〜13番があり、13番ピンの下方にある内蔵LEDが点滅します。あるいは普通のLEDを13ピンとGNDピンに差し込んでも構いません(LEDの足の長い方を13番ピン、短い方をGNDピン)。GNDピンは13番ピンの左側にあります。

void setup() {
pinMode(13, OUTPUT); //13番ピンを出力用に設定
}

void loop() {
digitalWrite(13, HIGH); //13番ピンを5Vで出力:LEDオン
delay(1000); //1秒間待機
digitalWrite(13, LOW); //13番ピンを0Vで出力:LEDオフ
delay(1000); //1秒間待機
}



プログラムをArduinoボードにアップロードするには:
ソフト上のVerifyボタンを押してコンパイルします。

問題なければ「Done Compiling.」が画面下部に表示されます。
そして、「Upload」ボタンを押してAruinoボードにプログラムを書き込みます。

アップロード中にはArduinoボードのLED(TXとRX)が高速で数秒間点滅します。
問題なければ「Done uploading.」が画面下部に表示されます。
以上でプログラムの書き込みは終了です。
上記プログラムは13番端子のLEDが1秒ごとに点滅する内容です。
プログラム内のdelay(1000);の括弧内の数字を変えれば点滅する速度を変えることができます。単位はミリ秒なので1秒は1000になります。
digitalWrite(13, HIGH)の括弧内のHIGHはそのピンを5Vで出力することを意味しています。
LOWなら0Vの出力となりLEDは消灯します。
またpinMode()とdigitalWrite()の括弧内のピン番号を変えれば、違う箇所に接続したLEDを点灯させることができます。

プログラムする手順としては:
・どのピンを出力用にするか:pinMode(ピン番号)
・どのピンをHIGHまたはLOWで出力するか:digitalWrite(ピン番号,出力値)
・点灯や消灯の継続時間:delay(ミリ秒)
となります。1000ミリ秒=1秒です。


アナログ出力
上記はLEDの点滅でしたが、analogWrite()を使えばLEDの明暗を調節して点灯させることができます。ただし、ボード上にPWMと書かれた3,5,6,9,10,11の6本のピンのどれかに接続する必要があります。つまりこの6本のピンは設定によってdigitalWrite()とanalogWrite()を使い分けできるということになります。
analogWrite(ピン番号,出力値)という感じで、ピン番号と出力値を入れることで設定できます。
出力値は0〜255までの値を設定できます。0の時0V、255の時5Vになり、その間の値であれば数値に応じた出力量になります。
尚、analogWrite()はsetup(){...}内にpinMode()設定する必要はありません。

以下は変数valを用意して、徐々に明るくなって最大値に達したら0に戻るという内容です。
delay()で明るくなっていくスピードを設定しています。
LEDは11番ピンに接続してあります(LEDの足の長い方を11番ピン、短い方をGNDピンに接続)

int val=0;
void setup(){
//pinMode()設定は不要
}

void loop(){
analogWrite(11,val);//11番ピンを変数valの値で出力
val++; //+1ずつ出力値を増大させる
if(val>255){ //出力値が255を越えたら
val=0; //出力値を0に戻す
}
delay(20); //1ループ20ミリ秒にする
}

2011年9月19日月曜日

次回9/26(月):Arduino

次回9/26(月)はArduino(電子工作)を行います。

必要なもの:
・Arduinoボード(入手方法等についてはこちら
・USBケーブル(Arduinoボードとパソコンをつなぐ用)
・ノートパソコン

Arduinoのソフトをインストールしておいてください。
ダウンロードサイト:http://arduino.cc/en/Main/Software

Arduinoボードを新規購入する場合は「Arduino UNO(2995円)」というタイプをおすすめします(以下参考)。
Arduino Uno
Arduino Uno
posted with amazlet at 11.09.19
スイッチサイエンス
売り上げランキング: 23324

2011年9月14日水曜日

Processingのプログラムをブログに掲載する方法

Processingのプログラムをブログに掲載するには、以下のページを参考にしてください。
http://ken-nou-kou.blogspot.com/2009/06/processing.html

Processing:基本プログラム

授業で行ったシンプルなボタン操作のプログラムです。



画面内の矩形をクリックすると背景が赤に変わります。

プログラム内容としては以下のようなことをしています。
・画面サイズ設定
・図形描画属性設定(色や外形線など)
・ボタンの矩形描画
・マウス座標取得(mouseX,mouseY)
・マウスの位置とボタンの矩形範囲の重なり判定
・マウスクリックによるコマンド
・マウスが押されたか押されていないかの状態をフラグを使って判別


boolean press=false;//ボタンを押したかどうかのフラグ用変数

void setup(){
size(400,400);//画面サイズ設定
fill(0);//ボタンの塗り面を黒に設定
stroke(100);//ボタンの外形線の色設定(256段階あるうちの100のグレー)
strokeWeight(3);//ボタンの外形線の太さ設定(3ピクセル)
}

void draw(){
if(press==true){//ボタンが押されているとき
background(255,0,0);//背景が赤になる
}else{//ボタンが押されていないとき
background(0);//背景が黒になる
}
if(mouseX>200 && mouseX<300 && mouseY>200 && mouseY<250){//ボタンの矩形範囲にマウスがある時
fill(100);//ボタン塗り色を100のグレーにする
}else{
fill(0);//ボタン塗り色を黒にする
}
rect(200,200,100,50);//ボタンの表示(矩形):rect(x座標,y座標,矩形幅,矩形高さ)
}

void mousePressed(){//マウスが押されたら発動する
if(mouseX>200 && mouseX<300 && mouseY>200 && mouseY<250){//ボタンの矩形範囲にマウスがある時
press=!press;//フラグ反転(ONの時OFF、OFFの時ONにする)
}
}


また以下のようなシンプルなゲームのプログラム(壁打ちテニスのようなゲーム)

ゲームするには、画面内をクリックしてください。
プログラム内容としては:
・画面サイズ設定
・図形描画属性設定
・ボールの描画
・パドル(ラケット)の描画
・ボールの動く方向と1フレームに進む量
・マウスに合わせたパドルの動き
・壁3面にボール当たったときの判別と跳ね返り
・パドルにボールが当たったときの判別と跳ね返り
・パドルで何回打ち返したかのカウント
・パドルで打ち返せなかったときの判別
・ボール残数のカウント
・スコアとボール残数の表示
・ゲームオーバー表示
・ゲーム再開のためのクリック処理
簡単なゲームですが、少なくても以上のような内容をすべてプログラムしておく必要があります。
ボールやパドルの基準位置はrectMode(CENTER)を用いて図形中心に設定しています。
ボールが1辺10ピクセルでありボール座標が図形中心なので、例えば画面上端で跳ね返るときは、ボールX座標が5(1辺10ピクセルの半分)のときの跳ね返ることになります。


PFont font;//文字表示のフォントのオブジェクトを用意
int ballX;//ボールのX座標変数
int ballY;//ボールのY座標変数
int directionX;//ボールの動くX座標上の方向の変数(右向き:+1、左向き:-1)
int directionY;//ボールの動くY座標上の方向の変数(下向き:+1、上向き:-1)
int paddleX;//パドル(ラケット)のX座標の変数
int pts;//得点の変数
int balls;//ボール残り数の変数
int speed;//ボールの1フレームあたりの進む量

void setup(){
size(400,400);//画面サイズ設定
noStroke();//図形の外形線無し
ballX=200;//最初のボールが登場するときのX座標値
ballY=0;//最初のボールが登場するときのY座標値
directionX=1;//X座標上のボールの向き(正の向き:右向き)のフラグ
directionY=1;//Y座標上のボールの向き(正の向き:下向き)のフラグ
rectMode(CENTER);//矩形描写の基準点を図形中心に設定
font=createFont("Arial",16);//フォントの準備
textFont(font,16);//フォント設定
pts=0;//ポイント0(初期設定)
balls=2;//残りボール数2(初期設定)
speed=2;//ボールの1フレームあたりの進む量を2に設定
}
void draw(){
background(0);//背景色(黒)
if(ballX<5){//ボールが画面左にぶつかったとき
ballX=5;//ボールの位置を5に設定
directionX*=-1;//ボールの動く向きを反転
}
if(ballX>395){//ボールが画面右にぶつかったとき
ballX=395;//ボールの位置を395に設定
directionX*=-1;//ボールの動く向きを反転
}
if(ballY<5){//ボールが画面上にぶつかったとき
ballY=5;
directionY*=-1;
}
if(ballY>395){//ボールが画面下を越えたとき
if(balls<1){//ボールが残り数1より小さい(ボール数:0)とき
text("GAME OVER",150,200);//ゲームオーバー表示
balls=0;
speed=0;//ボールの1フレームに動く量を0にする(ボール停止)
ballY=410;//ボールを画面外に移動させておく
}else{//残りボールがあるとき
ballY=5;//ボールを画面上部に移動させる
balls--;//残りボール数を減らす
}
}
if(ballX>mouseX-25 && ballX=370 && ballY<=370+speed){//ボールがラケットの位置にあるとき
ballY=370;
directionY*=-1;//ボールの動きの反転(ボールの打ち返し)
pts++;//ポイント加算
}
ballX+=speed*directionX;//ボールのX軸移動
ballY+=speed*directionY;//ボールのY軸移動
rect(ballX,ballY,10,10);//ボールの描画
rect(mouseX,380,50,10);//パドル(ラケット)の描画
text("SCORE: "+nf(pts,4),20,20);//ポイント表示
text("BALL LEFT: "+balls,280,20);//ボール残り数表示
}

void mousePressed(){//マウスを押した時の処理
if(balls==0){//ボールが残り数0の時(ゲームオーバー時)
balls=2;//ボールが残り数を2に戻す
ballY=5;//ボールY座標値を画面上部に戻す
speed=2;//ボールの1フレームに動く量を2に戻す
}
}



各自既存のゲームなどを参考にプログラムを組んでみてください。ゲームすべてをプログラムするのは大変かもしれないので、部分的な動きや表現でも構わないので実験的にプログラムしてみてください。

2011年9月3日土曜日

後期授業について

後期授業は9/12(月)18:30からです。
初回は、引き続きProcessingプログラミングを行う予定です。
各自ノートパソコンを持参して来て下さい。

また前期で行った制作の画像などありましたら、各自ブログへアップしておいて下さい。