有成千上萬的學生,藝術家,設計師,研究人員,和愛好者,用Processing來學習、創意和製作產品。
如果想讓在電腦中設計的藝術作品與外部物理世界進行互動,讓作品能與人和物產生“對話”,就需要傳感器把外部環境的信息,採集到電腦中處理,做到這一點,目前通常的方法是通過Arduino控制器把傳感器數據,通過串口通信,讀到上位機軟件Processing裏,然後通過處理,讓Processing數位作品的某些特徵與傳感器數據產生關聯,於是物理世界的環境數據發生變化時,也會使虛擬數字世界的作品隨之互動,不斷幻化出動態語義的奇妙畫面。
上一篇文章《零成本學Arduino單片機之串行通訊》,講述了採用Proteus仿真方法,來實現Arduino控制器與上位機軟件之間的通信,這種方法同樣適合Arduino與Processing的互動。如果學會了這樣的方法,在零硬件成本情況下,也可以玩一玩互動媒體藝術了。
Proteus界面中的下位機Arduino單片機與上位機軟件Processing進行串行通訊,並沒有硬件連接,需要通過某種軟件虛擬出兩個相互連接的串口,一個串口分配給Arduino單片機,另一個串口分配給上位機軟件,在虛擬環境下,讓兩者能夠完成串行通訊。這種軟件就是VSPD虛擬串口驅動軟件。
VSPD虛擬串口驅動軟件請下載:http://115.com/file/eizd0usu。
我通過VSPD軟件,配對了兩個虛擬串口COM7和COM8,COM7分配給了Proteus仿真圖中的Arduino硬件電路中的串口連接器COMPIM,COM8分配給了Processing,通過Processing程序的“ duankou = new Serial(this,"COM8",9600);”指令,把COM8指定給了Processing。
Proteus仿真圖:
Proteus仿真圖,供下載:Proteus.zip。
通過兩個虛擬串口,進行串行通信的方法見文章:《零成本學Arduino單片機之串行通訊》,網址:http://www.eefocus.com/zhang700309/blog/12-11/288957_ad4bb.html 。
本篇文章仿真項目的任務是:在仿真圖中,用鼠標調節電位計滑動抽頭與地之間的電壓,Arduino控制器採集這個電壓值,正比轉換後,通過串口通信,發送到上位機軟件Processing處理。Processing中有兩個在X,Y軸方向上都相差半個點距的矩形彩盤陣列。當電位計滑動抽頭移動時,Arduino控制器採集的電壓值會隨之增加,同時,Processing的兩個矩形陣列中各個彩盤的直徑也相應增大。由於彩盤直徑增大,使它們相互產生融和,不斷幻化出奇妙的圖案。如下面圖片和視頻所示。
仿真實驗視頻:
雙擊網址,全屏看仿真實驗現象,
http://www.tudou.com/v/dUFtwvQrnTE/&rpid=91074573&resourceId=91074573_04_05_99/v.swf。
仿真圖中的Arduino單片機與上位機軟件Processing相互通信,除了看懂專題文章《零成本學Arduino單片機之串行通訊》,還要關注Arduino程序和Processing程序中有關串口通信的指令,這些指令我用紅色字體在程序中標註出來,仔細研究下。
Arduino程序:
/*任務:調節電位計滑動抽頭與地之間的電壓,並把
電壓值採集到Arduino控制器,經正比轉換後,以單字節數據
的形式,通過串口通信,發送到上位機軟件處理。*/
int potpin = 0; //把電位計連在Arduino模擬端口0
//初始化
void setup()
{
Serial.begin(9600);//啓動串行通訊,波特率爲9600b/s
}
void loop()
{
//讀取電位計電壓量的採樣值,採樣值範圍爲0~1023
int sensorValue = analogRead(potpin);
//把範圍爲0~1023的採樣值正比轉換爲範圍0~255單字節數據
int data= sensorValue/4;
//把包含電壓值信息的單字節數據通過串口發送到上位機
Serial.print(data,BYTE);
delay(20); //延時20ms
}
Processing程序:
/*任務:在畫布中,創建兩個在X、Y軸相差半個點距的兩個矩形彩盤矩陣,
接受下位機Arduino控制器發送的單字節數據,並把該數據與彩盤直徑關聯起來。*/
import processing.serial.*;//導入serial通信庫
Serial duankou;//創建對象duankou
float data;//變量存儲Arduino傳來數據
float d;//彩盤直徑
void setup()
{
//設定通訊端口爲COM8,波特率爲9600
duankou = new Serial(this,"COM8",9600);
size(600,600);//畫布尺寸
background(0);//背景爲黑色
stroke(128);//彩盤線條爲灰色
smooth();
}
//主程序
void draw()
{
background(0);
//當串口緩衝區接受到字符時
if(duankou.available()>0)
{
//把Arduino傳來的字節存入變量data
data=duankou.read();
//把Arduino上傳的字節0~255正比轉換爲彩盤直徑
d=map(data,0,255,5,140);
println(int(d));
}
//生成彩盤陣列
for(float x1=0;x1<=600;x1 =100)
{
for(float y1=0;y1<=600;y1 =100)
{
fill(242,204,47,160);
ellipse(x1,y1,d,d);
}
}
//生成另一個彩盤陣列
for(float x1=50;x1<=550;x1 =100)
{
for(float y1=50;y1<=600;y1 =100)
{
fill(116, 193, 206, 160);
ellipse(x1,y1,d,d);
}
}
}