Continuamos con la tercera entrada destinada montar una torreta servo con dos grados de libertad controlada por Arduino. Un pequeño proyecto que, combinado con sensores, cámaras, laser, o muchos otros dispositivos da lugar a un montón de proyectos divertidos.
En la primera entrada presentamos el proyecto y vimos el presupuesto. En la segunda entrada vimos el proceso de montaje y el esquema eléctrico. En esta, nos adentraremos en algunos ejemplos de código.
Doble barrido (sweep)
El primer ejemplo es un simple barrido con ambos servos, de 45 a 135º. El código es el siguiente.
#include <Servo.h>
Servo panServo;
Servo tiltServo;
const int speed = 30;
const int panServoPin = 9;
const int tiltServoPin = 10;
void setup()
{
panServo.attach(panServoPin);
tiltServo.attach(tiltServoPin);
}
void loop()
{
for (int pos = 45; pos <= 135; pos += 1)
{
panServo.write(pos);
tiltServo.write(pos);
delay(speed);
}
for (int pos = 135; pos >=45; pos -= 1)
{
panServo.write(pos);
tiltServo.write(pos);
delay(speed);
}
}
Sencillo, y no podría ser más aburrido ni queriendo. Vamos a ver si lo arreglamos en el siguiente ejemplo.
Recibir ángulos por puerto serie
Vamos a añadir la librería EasyComma para recibir los dos ángulos enviados por un array separado por comas.
#include <Servo.h>
#include "EasyCommaLib.h"
EasyComma easyComma(2);
Servo panServo;
Servo tiltServo;
const int panServoPin = 9;
const int tiltServoPin = 10;
void setup()
{
Serial.begin(9600);
panServo.attach(panServoPin);
tiltServo.attach(tiltServoPin);
}
void loop()
{
easyComma.Recieve(OnRecieve);
}
void OnRecieve()
{
auto panAngle = easyComma[0];
auto tiltAngle = easyComma[1];
panServo.write(panAngle);
tiltServo.write(tiltAngle);
}
Ahora, si en el monitor puerto serie escribís dos ángulos (por ejemplo: 90,90) veréis que la torreta se mueve inmediatamente a los ángulos indicados.
Por supuesto, en lugar de recibirlos por puerto de serie podríamos obtener los ángulos por cualquier controlador, como un joystick analógico, el mando de la ps2, el wiichuck, un potenciómetro, etc.
Puedes consultar más controladores para Arduino en la categoría controles de Arduino
Mover servos a velocidades distintas
Mover los servos a la posición indicada instantáneamente es divertido, pero normalmente demasiado brusco. En un robot real vamos a querer que el movimiento dure una cierta cantidad de milisegundos.
Para ello vamos a emplear la librería AsyncServo, que nos permite mover varios servos de forma asíncrona sin intervenir con el bucle principal.
#include <Servo.h>
#include "EasyCommaLib.h"
#include "AsyncServoLib.h"
EasyComma easyComma(3);
AsyncServo panServo;
AsyncServo tiltServo;
const int panServoPin = 9;
const int tiltServoPin = 10;
void setup()
{
Serial.begin(9600);
panServo.Attach(panServoPin);
tiltServo.Attach(tiltServoPin);
}
void loop()
{
easyComma.Recieve(OnRecieve);
panServo.Update();
tiltServo.Update();
}
void OnRecieve()
{
auto panAngle = easyComma[0];
auto tiltAngle = easyComma[1];
auto delayTime = easyComma[2];
panServo.MoveDegrees(panAngle, delayTime);
tiltServo.MoveDegrees(tiltAngle, delayTime);
}
Ahora, si en el monitor puerto serie escribimos dos ángulos y un tiempo en milisegundos (por ejemplo, 45, 90, 2000) veremos que la torreta se mueve al ángulo indicado, llegando en el tiempo indicado.
Nuevamente, los valores de consigna de posición podría obtenerse por cualquiera de los controles que hemos visto en el blog, o por cualquier sistema de comunicación.
En el futuro recuperaremos de vez en cuando este proyecto, por ejemplo, para poner un sensor de distancia en un robot, resolver la cinemática inversa para apuntar a unas coordenadas en un láser, o combinar una cámara y un acelerómetro para hacer una plataforma estabilizada.
Descarga el código
Todo el código de esta entrada está disponible para su descarga en Github.