有成千上万的学生,艺术家,设计师,研究人员,和爱好者,用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);
}
}
}