【教學】Processing互動專題:結合 LinkIt 7697

作者/攝影曾吉弘
時間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);
  }
}

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *