Já faz tempo que ando a procura de uma maneira simples de enviar informação do Processing para o Arduino e de todas as bibliotecas e técnicas que experimentei não encontrei nenhuma que me agradasse. Como não sou programador pedi ajuda ao meu amigo @pauloricca (http://twitter.com/pauloricca), e ele deu-me uma solução muito simples de implementar e fácil de entender, todos os créditos da parte da comunicação serial vão para ele.
Para melhor exemplificar este exemplo usei um LED RGB, e liguei-o directamente aos pins do Arduino (NUNCA FAÇAM ISTO a não ser que queiram matar os vossos leds rapidamente). A maneira correcta é usar uma resistência em série nos pins dos leds, mas sobre esta matéria existem imensos tutoriais disponíveis e eu quero-me focalizar apenas na parte do envio de dados para o arduino.
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Ffarm5.static.flickr.com%2F4100%2F4817616861_21733b09cc_z.jpg&hash=0a2c9f282a9b7d0678d738eebdaa61f581d278b1)
Ainda no lado do Arduino foram definidos 3 pins de OUTPUT 9, 10, e 11, estes pins vão enviar PWM para cada um dos leds. O pin 8 é definido também como OUTPUT e vai servir como pin de GROUND. Dentro da função loop() usa-se a função switch() que detecta qual é o caracter 'R', 'G', ou 'B' que foi enviado do processing. Este caracter é meramente de sincronização e serve para nos dizer qual é o valor que vem a seguir, veremos isso melhor no lado do Processing. Depois a função GetFromSerial() é chamada sempre que quizermos ver que informação é que vem a caminho.
void setup()
{
// declare the serial comm at 9600 baud rate
Serial.begin(9600);
// output pins
pinMode(9, OUTPUT); // red
pinMode(10, OUTPUT); // green
pinMode(11, OUTPUT); // blue
// another output pin to be used as GROUND
pinMode(8, OUTPUT); // ground
digitalWrite(8, LOW);
}
void loop()
{
// call the returned value from GetFromSerial() function
switch(GetFromSerial())
{
case 'R':
analogWrite(9, GetFromSerial());
break;
case 'G':
analogWrite(11, GetFromSerial());
break;
case 'B':
analogWrite(10, GetFromSerial());
break;
}
}
// read the serial port
int GetFromSerial()
{
while (Serial.available()<=0) {
}
return Serial.read();
}
No lado do Processing, estou a usar uma classe para o slider adaptada de uma classe existente do anthonymatox.com (http://www.anthonymattox.com/serial-communication-sending-variables-to-the-arduino). São criadas 3 instâncias desta classe (vou assumir que entendem o conceito de classe e seus derivados). Notem também que é importada a biblioteca Serial e a criação de uma instância chamada "port".
Na funcção setup() estou a ver qual é a porta de comunicação disponível, no meu caso e porque estou a usar mac é a 0, para quem usa pc há-de ser COM1, ou COM2, com COM# onde # é sempre um número.
Finalmente faço o envio de valores de cada slider através do comando port.write(valor). Notem que antes de enviar cada valor do slider envio sempre um caracter de sincronização 'R', 'G', ou 'B'.
import processing.serial.*;
Serial port;
sliderV sV1, sV2, sV3;
color cor;
void setup() {
size(500, 500);
println("Available serial ports:");
println(Serial.list());
// check on the output monitor wich port is available on your machine
port = new Serial(this, Serial.list()[0], 9600);
// create 3 instances of the sliderV class
sV1 = new sliderV(100, 100, 90, 255, #FF0000);
sV2 = new sliderV(200, 100, 90, 255, #03FF00);
sV3 = new sliderV(300, 100, 90, 255, #009BFF);
}
void draw() {
background(0);
sV1.render();
sV2.render();
sV3.render();
// send sync character
// send the desired value
port.write('R');
port.write(sV1.p);
port.write('G');
port.write(sV2.p);
port.write('B');
port.write(sV3.p);
}
/*
Slider Class - [url=http://www.guilhermemartins.net]www.guilhermemartins.net[/url]
based on [url=http://www.anthonymattox.com]www.anthonymattox.com[/url] slider class
*/
class sliderV {
int x, y, w, h, p;
color cor;
boolean slide;
sliderV (int _x, int _y, int _w, int _h, color _cor) {
x = _x;
y = _y;
w = _w;
h = _h;
p = 90;
cor = _cor;
slide = true;
}
void render() {
fill(cor);
rect(x-1, y-4, w, h+10);
noStroke();
fill(0);
rect(x, h-p+y-5, w-2, 13);
fill(255);
text(p, x+2, h-p+y+6);
if (slide==true && mousePressed==true && mouseX<x+w && mouseX>x){
if ((mouseY<=y+h+150) && (mouseY>=y-150)) {
p = h-(mouseY-y);
if (p<0) {
p=0;
}
else if (p>h) {
p=h;
}
}
}
}
}
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Ffarm5.static.flickr.com%2F4098%2F4818168052_f55c606080.jpg&hash=521616d37e978df446a9227478722667e45bd499)
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Ffarm5.static.flickr.com%2F4117%2F4818167676_4183b9bfd0.jpg&hash=03593734131d8f44966b455e1e60c40099afa025)
(https://lusorobotica.com/proxy.php?request=http%3A%2F%2Ffarm5.static.flickr.com%2F4093%2F4818167282_48a675ef3c.jpg&hash=13dd03b301ef094c2b5ed81e052874a53d1c2c07)