Apéndice 6. Envío a petición (toma y dame)
Cuando se envía más de un dato del Arduino a otro sistema es necesario implementar reglas de comunicación adicionales para poder distinguir a que dato corresponde cada uno de los paquetes de bytes recibidos. Una manera simple y eficiente de hacer esto es jugando al “toma y dame”. Arduino no enviará los valores de los sensores hasta que Processing no le envíe también un valor por el puerto serial y Processing, a su vez, no enviara ese valor hasta no tener los datos que espera completos.
Este sería el código para Arduino usando tres potenciómetros en los últimos tres pines analógicos del ATmega:
Codigo para cargar en la tarjeta Arduino desde el IDE Arduino
int pot1= 0; // valores de los sensores analógicos
int pot2= 0;
int pot3= 0;
int inByte = 0; // valor entrante de Processing
void setup()
{
Serial.begin(9600);
}
void loop()
{
if (Serial.available() > 0) { // sólo si algo ha llegado
inByte = Serial.read(); // lo lee
// hace la lectura de los sensores en pines 3,4y 5 (análogos)
pot1 = analogRead(3)/4;
pot2 = analogRead(4)/4;
pot3 = analogRead(5)/4;
// y los envía Serial.print(pot1, BYTE); Serial.print(pot2, BYTE); Serial.print(pot3, BYTE);
}
}
Una vez cargado este programa en la tarjeta Arduino está en disposición de enviar los datos de las lecturas de los potenciómetros cuando le sean demandados por el programa que los requiera. En nuestro ejemplo vamos a escribir un programa en el IDE Processing y será este el que se ocupe de leer los datos y con ellos modificar la posición de una bola que aparecerá en pantalla
Será processing quién empezará el “toma y dame” y deberá reconocer cada dato. Este es el código:
Código para Processing
import processing.serial.*;
Serial puerto;
int[] datosEntrantes = new int[3]; // arreglo para recibir los tres datos
int cuantosDatos = 0; // contador
int posX, posY, posZ; // posición de un objeto 3D
boolean hayDatos = false; // control de verdad
void setup() {
size(400, 400, P3D);
noStroke();
println(Serial.list());// puertos serie disponibles
puerto = new Serial(this, Serial.list()[0], 9600); // Configuración del puerto
puerto.write(65);
// Envía el primer dato para iniciar el toma y dame
}
void draw() {
background(0);
lights();
fill(30,255,20);
translate(width/2 + posX, height/2 + posY, posZ); sphere(40);
if (hayDatos == false) { //si no hay datos envía uno
puerto.write(65);
}
}
// esta función corre cada vez que llega un dato serial
void serialEvent(Serial puerto) {
if (hayDatos == false) {
hayDatos = true; // de ahora en adelante el dato de envío se dará por el toma y dame
}
// Lee el dato y lo añade al arreglo en su última casilla
datosEntrantes[cuantosDatos] = puerto.read();
cuantosDatos++;
if (cuantosDatos > 2 ) { // Si ya hay tres datos en el arreglo
posX = datosEntrantes[0];
posY = datosEntrantes[1];
posZ = datosEntrantes[2];
println("Valores de los potenciometros: " + posX + "," + posY + "," + posZ);
puerto.write(65); // y envía para pedir más
cuantosDatos = 0; // y todo empieza de nuevo
}
}
Aspecto del IDE Processing cuando esta en funcionamiento el programa de captura de valores de los tres potenciómetros.