Visitando o site instructables que, diga-se de passagem, é um site muito bom, encontrei o projeto Servo Controlled Labyrinth by nivini . Decidi então, tendo como referência a ideia do autor, montar o jogo usando o arduino e o nunchunk para controlar o tabuleiro. Como não tinha o jogo tradicional montei meu próprio tabuleiro usando duas caixas em mdf e quatro pedaços de compensado 4mm além de outras pequenas peças adaptadas de matérias disponíveis em casa, o que rendeu um pouco mais de trabalho, mas nada exagerado. Se você já tiver o labirinto pode montar toda a parte física como no projeto original, o que torna as coisas mais fáceis.
O labirinto
Para a confecção do labirinto usei uma caixa em MDF de 25cm x 25cm e a tampa de outra caixa em MDF 20cm x 20cm, onde foi montado o labirinto propriamente dito com pedaços das peças de um pega varetas "gigante" (5mm de diâmetro), um brinquedo abandonado por minha filha de três anos. Quatro pedaços de compensado serviram para fazer o quadro intermediário. Neste quadro foi fixado o primeiro servo que tem seu eixo preso no centro de uma das laterais da tampa 20x20 e é responsável pelo movimento no eixo Y. O segundo servo, que é responsável pelo movimento no eixo X, é fixado à caixa maior e tem seu eixo preso em uma das laterais do quadro intermediário de modo a ficar perpendicular ao primeiro servo.
O código
O código, que pode ser visto abaixo, foi adaptado do código encontrado neste site: http://www.windmeadow.com/node/42 .
Eu substitui a parte do código que imprime os valores na tela pelo controle dos servos. Pra melhora a estabilidade o código faz uma media dos últimos 20 valores lidos, ajusta a escala e aplica os resultados aos servos. /*
* NunchuckPrint
*
* 2007 Tod E. Kurt, http://todbot.com/blog/
BRANCO------ GND
AZUL-------- SCL pino analogico 5
VERMELHO---- +3.3V
VERDE------- SDA pino analogico 4
*/
#include <Wire.h>
#include <Servo.h>
Servo servo_y; // create servo object to control a servo
Servo servo_x; // create servo object to control a servo
#define m_movel 20 // quantidade de leituras para media
int media_leit_y =0;
int media_y_aux =0;
int aux_soma_y = 0;
int aux_m_y[m_movel];
int media_leit_x =0;
int media_x_aux =0;
int aux_soma_x = 0;
int aux_m_x[m_movel];
void setup()
{
servo_x.attach(9); // attaches the servo on pin 9 to the servo object
servo_y.attach(10);
Serial.begin(19200);
nunchuck_setpowerpins(); // use analog pins 2&3 as fake gnd & pwr
nunchuck_init(); // send the initilization handshake
Serial.print ("Finished setup\n");
for(int i=0; i < m_movel; i++)
{
aux_m_y[i] =0;
aux_m_x[i] =0;
}
}
void loop()
{
nunchuck_get_data(); // lê dados
aciona_servos(); // envia-os para os servos
delay(5);
}
//
// Nunchuck functions
//
static uint8_t nunchuck_buf[6]; // array to store nunchuck data,
// Uses port C (analog in) pins as power & ground for Nunchuck
static void nunchuck_setpowerpins()
{
#define pwrpin PORTC3
#define gndpin PORTC2
DDRC |= _BV(pwrpin) | _BV(gndpin);
PORTC &=~ _BV(gndpin);
PORTC |= _BV(pwrpin);
delay(100); // wait for things to stabilize
}
// initialize the I2C system, join the I2C bus,
// and tell the nunchuck we're talking to it
void nunchuck_init()
{
Wire.begin(); // join i2c bus as master
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x40); // sends memory address
Wire.send(0x00); // sends sent a zero.
Wire.endTransmission(); // stop transmitting
}
// Send a request for data to the nunchuck
// was "send_zero()"
void nunchuck_send_request()
{
Wire.beginTransmission(0x52); // transmit to device 0x52
Wire.send(0x00); // sends one byte
Wire.endTransmission(); // stop transmitting
}
// Receive data back from the nunchuck,
int nunchuck_get_data()
{
int cnt=0;
Wire.requestFrom (0x52, 6); // request data from nunchuck
while (Wire.available ()) {
// receive byte as an integer
nunchuck_buf[cnt] = nunchuk_decode_byte(Wire.receive());
cnt++;
}
nunchuck_send_request(); // send request for next data payload
// If we recieved the 6 bytes, then go print them
if (cnt >= 5) {
return 1; // success
}
return 0; //failure
}
void aciona_servos()
{
for(int cnt = m_movel-1; cnt > 0; cnt --)
{
aux_m_y[cnt] = aux_m_y[cnt-1];
aux_soma_y = aux_soma_y + aux_m_y[cnt];
aux_m_x[cnt] = aux_m_x[cnt-1];
aux_soma_x = aux_soma_x + aux_m_x[cnt];
}
int joy_x_axis = nunchuck_buf[0];
int joy_y_axis = nunchuck_buf[1];
int z_button = nunchuck_buf[5] & 1;
int c_button = nunchuck_buf[5] >> 1 & 1;
int accel_x_axis = (nunchuck_buf[2] << 2) + ((nunchuck_buf[5] >> 2) & 0x03);
int accel_y_axis = (nunchuck_buf[3] << 2) + ((nunchuck_buf[5] >> 4) & 0x03);
int accel_z_axis = (nunchuck_buf[4] << 2) + ((nunchuck_buf[5] >> 6) & 0x03);
// media eixo Y ////
aux_m_y[0] = accel_y_axis;
aux_soma_y = aux_soma_y + aux_m_y[0];
media_y_aux = aux_soma_y /m_movel;
aux_soma_y = 0;
media_leit_y = constrain(media_y_aux, 375, 595);
media_leit_y = map(media_leit_y, 375, 595, 110, 70);
// media eixo X ////
aux_m_x[0] = accel_x_axis;
aux_soma_x = aux_soma_x + aux_m_x[0];
media_x_aux = aux_soma_x /m_movel;
aux_soma_x = 0;
media_leit_x = constrain(media_x_aux, 375, 595);
media_leit_x = map(media_leit_x, 375, 595, 70, 110);
servo_y.write(media_leit_y); // tell servo to go to position in variable 'pos'
servo_x.write(media_leit_x);
}
char nunchuk_decode_byte (char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}