2008-03-18

Mar.18 Anduino+processing 受驚嚇的圓之章

又到了週二Arduino實驗時間,沒想到這個小小心得的專欄(?什麼時候的事了)竟然變成教學用途,彥齊和鹿子竟然還說,就算其他文章都不要po也沒關係(不重要!?),至少要把每次上課的心得整理成教學。好吧其實我發現最近算很有毅力的在整理生活心得,就算不說這種其他文章不知道該哭或該笑的話還是會po上來的,呵呵。

今天延續上星期已經讀到可變電阻的測試,把原本out put出去給LED做明暗變化的參數,丟進processing裡,利用processing比較強大的繪圖功能做一個可以互動的圓。

首先要先用Arduino program把以下程式碼upload到板子上,這部份直接從官網copy下來就可以了。主要是要將讀取到的類比和數位訊號變化值可以持續的送出去,後面我們要用processing來接。


/*
Sensor Reader
Language: Wiring/Arduino
Reads two analog inputs and two digital inputs
and outputs their values.
Connections:
analog sensors on analog input pins 0 and 1
switches on digital I/O pins 2 and 3
*/

int leftSensor = 0; // analog input for the left arm
int rightSensor = 1; // analog input for tht right arm
int resetButton = 2; // digital input for the reset button
int serveButton = 3; // digital input for the serve button

int leftValue = 0; // reading from the left arm
int rightValue = 0; // reading from the right arm
int reset = 0; // reading from the reset button
int serve = 0; // reading from the serve button

void setup() {
// configure the serial connection:
Serial.begin(9600);
// configure the digital inputs:
pinMode(resetButton, INPUT);
pinMode(serveButton, INPUT);
}

void loop() {
// read the analog sensors:
leftValue = analogRead(leftSensor);
rightValue = analogRead(rightSensor);

// read the digital sensors:
reset = digitalRead(resetButton);
serve = digitalRead(serveButton);

// print the results:
Serial.print(leftValue, DEC);
Serial.print(",");
Serial.print(rightValue, DEC);
Serial.print(",");
Serial.print(reset, DEC);
Serial.print(",");
// print the last sensor value with a println() so that
// each set of four readings prints on a line by itself:
Serial.println(serve, DEC);
delay(10);
}



傳好之後記得將Arduino program關掉或是把com3(或是看哪個埠)換掉,否則等等開啟processing的時候序列埠會被它佔用住就抓不到數據了。開啟processing後可以從官網copy這段程式碼再去修改,下面是今天梁老師試出來的程式碼,紅字是加寫進去或修改的部份,藍色字是說明。

/*
Serial String Reader
Language: Processing
Reads in a string of characters from a serial port until
it gets a linefeed (ASCII 10). Then splits the string into
sections separated by commas. Then converts the sections to ints,
and prints them out.
*/

import processing.serial.*; // import the Processing serial library

int linefeed = 10; // Linefeed in ASCII
Serial myPort; // The serial port
int r = 0;
int [] sensors; //要把原本下面的int Sensor[] = 那段殺掉換成這行,因為這邊是用全域函數來宣告後面draw才不會出問題(大概是這樣還在理解)

void setup() {
size(400, 400); //這裡以下是繪圖的一些語法,這行是定義程式要開多大解析度
smooth(); //這還不知道XD
background(0); //這段是背景顏色,0的話就是黑色
noStroke(); //了解中...

//frameRate(10);
// List all the available serial ports
println(Serial.list());

// I know that the first port in the serial list on my mac
// is always my Arduino module, so I open Serial.list()[0].
// Change the 0 to the appropriate number of the serial port
// that your microcontroller is attached to.
myPort = new Serial(this, Serial.list()[2], 9600); //中括號裡的數字要看連接的是哪一個序列埠決定,但要注意的是第一個是從0開始算,所以如果是com3的話就要填2才抓得到訊號

// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(linefeed);

}

void draw() {
// twiddle your thumbs
background(0); //繪圖的部份再宣告一次背景顏色
fill(226); //要填滿色塊

ellipse(width/2, height/2, r, r);
//因為這邊是畫圓,所以用橢圓形,只要長短半徑一樣就是正圓了,括號裡代表的分別是(圓心X,圓心y,直徑,直徑),如果要一直畫在中心只要把解析度長寬除以2就可以


}


// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():

void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil(linefeed);

// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

// split the string at the commas
// and convert the sections into integers:
sensors = int(split(myString, ','));

// print out the values you got:
for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "\t");
}
// add a linefeed after all the sensor values are printed:
println();
r = (int)sensors[1];//這個部份應該是bug,原本這段應該寫在draw裡面也是可以的,但是今天卡在這邊一直無法解決,最後梁老師把這段放在最後結束前先給它強制宣告就成功了,這裡是宣告接收到的sensor值變成 r 再代入圓的半徑
}

}


如果順利的話應該可以控制可變電阻(或光敏電阻等等),然後畫面中的圓大小也會跟著變化,例如今天做的實驗是利用光敏電阻控制,所以當我用手遮住光線的時候,光變暗,圓就會變小,手拿開圓就會再變大(我在Arduino program那邊寫了一個delay(10),也就是每百分之一秒就會傳送一次訊號,這讓變化看起來比較流暢),看起來就很像一個膽小受驚嚇的圓一樣,很有趣。依著這個方式,其實已經可以延伸出許多變化,再來就是去思考怎麼去創造有意思的互動關係而已 : )

後記,梁老師雖然今天說我很巧每次都玩出很有趣的東西,不過很想說....都不是我在用的啊!程式的部份幾乎都是靠梁老師才玩得出來的,而且我很不專心都只是亂玩些有的沒的,呵。

2 則留言:

  1. 誤會~不是其他文章不重要啦!
    是有PO這篇文章幫助很大,真的~~~

    回覆刪除
  2. 呵呵...我知道
    開玩笑的啦:P

    回覆刪除