作者/攝影 |
曾吉弘 |
時間 |
1小時 |
難度 |
★★★☆☆
|
材料表 |
|
Processing 互動介面開發環境
CAVEDU 使用 Processing 來教學也算有一段時間了,相當好用。學生用相對簡短的程式碼就可以產生相當豐富的互動介面、對於顏色、位置、聲音都有很不錯的效果(以下為阿吉老師FB貼文示範)。
雖然沒有圖形化介面這麼簡易,但就豐富度與支援度來說都相當不錯。今年我在北科互動系就再次嘗試使用 Processing 來完成 1/3 個學期的課程(後半學期為 Python)。
要匯入 opencv、Kinect 等各種的函式庫也很方便,當年很想寫一本 Processing的書啦,但就…算了。
更別說 p5.js 最近與 Google Teachable machine 有很好的連結,可以吃訓練好的神經網路模型做到視覺辨識的效果,超棒!
來看看創辦人 Daniel 的教學影片:
因此 Arduino 這類平價開發板來取得真實環境中的訊號變化,再由 Processing 來呈現聲光效果,是個相當不錯的選擇。
這樣的思維我覺得對於互動設計背景的同學而言:你要好好思考到底要呈現怎樣的效果,才去思考要用怎樣的軟硬體技術來支援你。
Processing 端程式
執行畫面如下,按下畫面不同顏色按鈕會送出字元 ‘A’ 與 ‘B’ 給 7697,7697 自然是接受什麼指令就做什麼事。比較重要的指令說明如下:
myPort = new Serial(this, Serial.list()[0], 9600);
宣告一個 Serial 序列通訊物件,baudrate 為 9600。請注意 Serial.list()[0] 代表您電腦 USB 裝置清單中的第一個裝置。但這有時候不一定會抓到 7697,可以改為 () 來指定 COM port
com port 請以 Windows 裝置管理員為準
MAC Linux 可在 terminal 下指令來看,會是 /dev/ttyACM0 這樣的結果
myPort.write('B');
送出字元給對應裝置(7697)
myPort.read();
從對應裝置端讀取資料,預設格式為 ASCII code.
影片連結:
import processing.serial.*;
int rectX, rectY; // Position of square button
int circleX, circleY; // Position of circle button
int rectSize = 90; // Diameter of rect
int circleSize = 93; // Diameter of circle
color rectColor, circleColor, baseColor;
color rectHighlight, circleHighlight;
color currentColor;
boolean rectOver = false;
boolean circleOver = false;
int bg=0;
Serial myPort;
void setup() {
myPort = new Serial(this, Serial.list()[0], 9600);
size(640, 360);
rectColor = color(0);
rectHighlight = color(51);
circleColor = color(255);
circleHighlight = color(204);
baseColor = color(102);
currentColor = baseColor;
circleX = width/2+circleSize/2+10;
circleY = height/2;
rectX = width/2-rectSize-10;
rectY = height/2-rectSize/2;
ellipseMode(CENTER);
}
void draw() {
update(mouseX, mouseY);
while (myPort.available() > 0) {
int inByte = myPort.read();
if (inByte == 'C') {
bg++;
if (bg>1) bg=0;
if (bg==1) currentColor=color(0,255,0);
if (bg==0) currentColor=color(255,0,0);
}
}
background(currentColor);
if (rectOver) {
fill(rectHighlight);
} else {
fill(rectColor);
}
stroke(255);
rect(rectX, rectY, rectSize, rectSize);
if (circleOver) {
fill(circleHighlight);
} else {
fill(circleColor);
}
stroke(0);
ellipse(circleX, circleY, circleSize, circleSize);
}
void update(int x, int y) {
if ( overCircle(circleX, circleY, circleSize) ) {
circleOver = true;
rectOver = false;
} else if ( overRect(rectX, rectY, rectSize, rectSize) ) {
rectOver = true;
circleOver = false;
} else {
circleOver = rectOver = false;
}
}
void mousePressed() {
if (circleOver) {
currentColor = circleColor;
myPort.write('A'); #送出字元A
}
if (rectOver) {
currentColor = rectColor;
myPort.write('B'); #送出字元B
}
}
boolean overRect(int x, int y, int width, int height) {
if (mouseX >= x && mouseX <= x+width &&
mouseY >= y && mouseY <= y+height) {
return true;
} else {
return false;
}
}
boolean overCircle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
7697端程式
如果您想用一般的 Arduino (Uno, Mega 2560等等,請參考本文即可,會更簡單。Arduino端只要下載內附的範例 StandardFirmata 就可接收來自 Processing 端的指令。但由於 7697端的 Firmata 還要改,所以先使用 serial 送字元的方式處理。
void setup()
{
Serial.begin(9600);
pinMode(3,INPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
digitalWrite(4,LOW);
digitalWrite(5,LOW);
}
void loop()
{
if (Serial.available()) {
char code = Serial.read();
if (code == 'A') {
digitalWrite(4,HIGH);
digitalWrite(5,LOW);
}
if (code == 'B') {
digitalWrite(4,LOW);
digitalWrite(5,HIGH);
}
}
if (digitalRead(3)==LOW) { //如果#3按鈕被按下,送字元 C 給 Processing
Serial.print('C');
delay(200);
}
}