第5章 Arduino和 Processing互动 Arduino和 Processing之间可以通过串行接口(简称串口)进行通信。本章首先分别说明 Processing如何控制 Arduino和 Arduino如何控制 Processing,然后详细介绍一个两者连接互动的作品——交互艺术装置 ColorfulMelody的实现,最后介绍导电墨水。 5.1 Processing控制 Arduino 案例 5-1展示如何使用 Processing控制 Arduino开发板上的小灯亮灭。首先在Processing端通过 import processing.serial.*语句导入串口库,然后声明一个 Serial变量port。在 Arduino端初始化程序中,通过 Serial.begin(9600)语句设置波特率为9600b/s,插入 Arduino开发板后计算机分配的端口是 COM3,Processing端在初始化程序中通过 new Serial(this,"COM3",9600)语句,就可以在 COM3串口上以波特率 9600 b/s发送和接收数据。 接下来实现发送和接收数据。在 Processing端创建一个 300×300像素的画布,在画布上绘制一个矩形,当鼠标单击矩形内区域,则向串口发送字符a,同时打印 LED turnON方便调试,这样如果出现异常,可以判断是 Processing程序出了问题没有运行到这里,还是串口发送的问题。当鼠标单击矩形外的画布区域,则向串口发送字符 b。Arduino端一直从串口读数据,当判断读到的字符为a(ASCII码为97)时,点亮 Arduino开发板上的 LED灯;字符为b(ASCII码为98)时,熄灭Arduino开发板上的 LED灯。 Processing端的代码: import processing.serial.*; Serial port; void setup(){ port = new Serial(this,"COM3",9600); size(300,300); } void draw(){ rect(100,100,50,50); } void mouseClicked(){ if((mouseX>=100) & (mouseX<=150) & (mouseY>=100) & (mouseY<=150)){ println("LED turn ON"); port.write("a"); } else{ println("LED turn OFF"); port.write("b"); } } Arduino端的代码: int c=0; void setup() { Serial.begin(9600); pinMode(LED_BUILTIN,OUTPUT); } void loop() { if(Serial.available()){ c=Serial.read(); if(c==97) digitalWrite(LED_BUILTIN,HIGH); else if(c==98) digitalWrite(LED_BUILTIN,LOW); } } 同时运行 Arduino和 Processing程序,这时 Processing弹出一个画布窗口,如图 5-1所示,单击矩形框内区域和矩形外画布区域,控制 Arduino开发板上 LED灯的亮灭。 5.2 Arduino控制 Processing 案例 5-2为 Arduino开发板向 Processing发送字符串。在 Arduino端初始化设置波特率为9600b/s,不断向串口发送字符串“a,b,c”。Processing端从串口接收字符串,可以通过 split()函数对字符串进行分割。 Arduino端的代码: void setup() { Serial.begin(9600); } void loop() { Serial.println("a,b,c"); } Processing端的代码: import processing.serial.*; Serial port; String rec; void setup(){ port = new Serial(this,"COM3",9600); } void draw(){ if(port.available()>0){ rec = port.readStringUntil('\n'); String[] a = split(rec,','); println(rec); println(a[0]); } else println("no"); } 5.3 Colorful Melody案例分享 音乐总会引起人们情感的共鸣。交互艺术装置 Colorful Melody(见图5-2)通过与自然元素相近的形式和沉浸式氛围,将每首歌的情感色彩与旋律基调可视化。歌曲的风格以流动的粒子为载体,使心情的表达方式不局限于文字记录。人们通过色彩的展示,在与歌曲中的情感产生共鸣的过程中,逐渐发掘自我的本心,渐渐地用音乐可视化的方式,谱写出属于自己的内心写照。 Colorful Melody交互艺术装置创作流程如图 5-3所示。 5.3.1 创意阶段 1.和弦色彩归纳 常见的联觉现象是“色—听”联觉,对色彩的感觉能引起相应的听觉,音乐色彩的概念便是由此产生的。音区有低音、中音、高音之分,与色彩中的低明度、 中明度、高明度相对应,又如调式音级具有倾向性,与色相的倾向性相对应。每一首歌都有组成它的和弦。通过文献调研,将每个和弦归纳出属于它的颜色,希望通过和弦的颜色,去表达一首歌的情感,如图 5-4所示。总体来看,大调鲜艳而昂扬,小调沉郁而悠长。 2.交互载体设计 参考 Teamlab的作品《台风气球·失重森林·共鸣人生》,营造出的氛围为参与者提供沉浸式体验,如图 5-5(a)所示。将灯箱作为一个小的元件,通过氛围感的营造,使用户置身于歌曲的情感色彩中,与作者的内心产生共鸣。根据歌曲的和弦按下灯箱上对应按键,琴键传感器上的 LED灯会根据和弦亮出其对应的颜色,如图5-5(b)所示。 5.3.2 Arduino端实现 1.硬件搭建 如图 5-6(a)所示,将写好和弦字母的纸条贴在琴键上,避免影响琴键上的触摸传感器,纸条制作要尽可能节省面积。灯箱的制作如图 5-6(b)所示,购买适当尺寸的亚克力板,进行拼接。内部的硬件连接如图5-6(c)。 (a) Typhoon Balls and Weightless Forest of Resonating Life效果图 通过琴键(触摸传感器)输入信号,分别向 LED、蜂鸣器、PC端输出信号,实现在弹奏的同时显示灯光颜色、播放音乐,以及 PC端鼠标的单击和位移,最后通过鼠标动作实现 Processing端的视觉效果。 2.灯箱发光颜色控制 案例 5-3为控制灯箱发光颜色的 Arduino端代码,将每个琴键作为一个和弦,赋予其之前归纳好的颜色,其中 LED灯的 RGB色彩赋值语句以第一键为例,其余以此类推。 #include "FastLED.h" //LED灯光控制 #de.ne NUM_LEDS 4 #de.ne DATA_PIN 4 const int SCL_PIN = 2; const int SDO_PIN = 3; const int buzzer_pin = A0; CRGB leds[NUM_LEDS]; (a)琴键外观制作 (b)灯箱外观制作 void setup() { FastLED.addLeds(leds,NUM_LEDS); Serial.begin(115200); Serial.println("Start Touching Several Keys Simultaneously!"); LEDS.showColor(CRGB(150,0,0)); pinMode(buzzer_pin,OUTPUT); digitalWrite(buzzer_pin,LOW); } void loop() { uint8_t sum=0; uint16_t keys=ttp229.ReadKeys16(); for (uint8_t i=0; i<16; i++) if (keys&(1< //琴键音高控制 void QhBuzzerplay(int num) { switch(num){ case 1:tone(buzzer_pin,261,400); //第一键音高赋值 break; default:break; } } 4.鼠标控制 案例 5-5将鼠标控制代码与琴键传感器进行连接,将触碰琴键转化为鼠标单击, 实现 Arduino与 Processing的连接互动,为后续粒子的变化提供帮助,其中鼠标方向移动控制语句以第一键为例,其余以此类推。 #include //鼠标方向移动控制 void QhBuzzerplay(int num) { switch(num){ //第一键鼠标方向控制 case 1: if (!Mouse.isPressed(MOUSE_LEFT)) { Mouse.press(MOUSE_LEFT);} else { // if the mouse is pressed,release it: if (Mouse.isPressed(MOUSE_LEFT)) { Mouse.press(MOUSE_LEFT);Mouse.move(10,0,0); } } break; default:break; } } 5.代码整合 通过 Arduino开发板将 12个触摸感应器(对应 12键,7白 5黑)感应信号传出,调用 FastLED.h库使 LED灯接收每个信号并分别处理,控制 RGB显示相对应的颜色;同时输出蜂鸣器发声信号,调用 TTP229.h库调整代码声音频率使其与琴键音调相符;最后调用 Mouse.h库,调整代码控制每次触摸琴键的鼠标单击和移动距离,实现传感器硬件结构和对屏幕的总体控制。代码如案例 5-6,其中各部分功能代码仍以第一键为例。 #include //鼠标控制 #include //蜂鸣器控制 #include "FastLED.h" //灯光控制 #de.ne NUM_LEDS 4 #de.ne DATA_PIN 4 const int SCL_PIN = 2; const int SDO_PIN = 3; const int buzzer_pin = A0; CRGB leds[NUM_LEDS]; TTP229 ttp229(SCL_PIN,SDO_PIN); void setup() { Mouse.begin(); FastLED.addLeds(leds,NUM_LEDS); Serial.begin(115200); Serial.println("Start Touching Several Keys Simultaneously!"); LEDS.showColor(CRGB(150,0,0)); pinMode(buzzer_pin,OUTPUT); digitalWrite(buzzer_pin,LOW); } void loop() { uint8_t sum=0; uint16_t keys=ttp229.ReadKeys16(); for (uint8_t i=0; i<16; i++) if (keys&(1<