Un regalo per tutti quelli che non hanno un radiocomando e vogliono "giocare" con l'elettronica per il multi coso, uno sketch che trasforma Arduino in un servo controller a 8 canali, o se preferite l'equivalente di una ricevente RC a otto canali.
Il controllo dei segnali PPM avviene tramite un Nunchuk, nella prossima release anche tramite porta seriale, il cui joystick aziona i primi due canali (1 e 2) e l'accelerometro gli ultimi due (7 e 8 )
Premendo il tasto C il joystick aziona i canali 3 e 4, i primi due rimangono al valore precedente la pressione del tasto, premendo il tasto Z si prende il controllo dei canali 5 e 6, premendo tutti e due i tasti l'accelerometro prende il controllo dei canali 1 e 2.
Leggete attentamente tutte le note in testa allo sketch.
Lo sketch è diviso in due file .pde il primo è quello principale.
nun_Servo.pde
/*
Servo Controller basato sul Nunchuk
(c) 2011 By MdA Project
v1.0.0, build 30.07.2011
*/
/*
Collegamenti Nunchuk
_________
| 1 2 3 |
| |
| 6 5 4 |
|_-----_|
•pin 1: verde - data (Arduino analog pin 4)
•pin 2: (not connected)
•pin 3: rosso - 3.3V
•pin 4: giallo - clock (Arduino analog pin 5)
•pin 5: (not connected)
•pin 6: bianco - GND
Il nunchuk originale Nintendo incorpora delle resistenze di pullup I2C da circa 1.8k.
Se utilizzate un Nunchuk non Nintendo verificate la presenza dei 3.3V su SDA e SCL
ed eventualmente aggiungere due resistenze di pull up, collegate al 3.3V,
con un valore compreso tra 1.5k e 3.3k
*/
/*
NOTE GENERALI
a) Non è garantito il corretto funzionamento con Nunchuk non originali.
b) In questa versione non è presente una routine per la calibrazione del Joystick
e dell'accelerometro.
Tutti i calcoli sono eseguiti sulla base dei valori medi forniti dai
sensori pertanto sia il punto centrale che i punti estremi possono differire
sensibilmente da quanto atteso e in modo diverso con diversi Nunchuk.
La calibrazione verrà aggiunta nelle future release.
c) Nella funzione "nun_read()" sono contenute delle serial.print() commentate, vanno
utlizzate, decommentandole, solo a scopo diagnostico per verificare il corretto
funzionamento del Nunchuk, visualizzano tutti i valori letti sul monitor seriale.
d) Nella prossima release verrà aggiunto il controllo tramite seriale con protocollo
dedicato e una GUI per pc (in futuro anche per Android) che permetterà di muovere
i servo tramite cursori e/o joystik collegato al pc.
*/
#include <Wire.h> // include per I2C
#include <Servo.h> // include per i Servo
// creazione degli oggetti servo
Servo servo1;
Servo servo2;
Servo servo3;
Servo servo4;
Servo servo5;
Servo servo6;
Servo servo7;
Servo servo8;
int pos = 1500; // posizione servo
char Led_stat = 0;
unsigned char nun_buf[6]; // buffer dati in arrivo dal nunchuck,
unsigned char z_but = 0;
unsigned char c_but = 0;
unsigned char joy_x_axis;
unsigned char joy_y_axis;
int accel_x_axis;
int accel_y_axis;
int accel_z_axis;
void setup()
{
pinMode(13, OUTPUT);
Serial.begin(115200); // per uso futuro della seriale
nunchuck_init(); // inizializza il nunchuck
// attaches servo ai pin 3-10
servo1.attach(3);
servo2.attach(4);
servo3.attach(5);
servo4.attach(6);
servo5.attach(7);
servo6.attach(8);
servo7.attach(9);
servo8.attach(10);
}
void loop()
{
Led_stat ^=1; // inverte il valore di Led_stat
digitalWrite(13, Led_stat); // lampeggio led
nun_get();
nun_read();
if (z_but & c_but)
{
pos = 800 + joy_x_axis * 6;
servo1.writeMicroseconds(pos);
pos = 800 + joy_y_axis * 6;
servo2.writeMicroseconds(pos);
}
if (z_but & !c_but)
{
pos = 800 + joy_x_axis * 6;
servo3.writeMicroseconds(pos);
pos = 800 + joy_y_axis * 6;
servo4.writeMicroseconds(pos);
}
if (!z_but & c_but)
{
pos = 800 + joy_x_axis * 6;
servo5.writeMicroseconds(pos);
pos = 800 + joy_y_axis * 8;
servo6.writeMicroseconds(pos);
}
if (!z_but & !c_but)
{
pos = 500 + accel_x_axis * 2 ;
servo1.writeMicroseconds(pos);
pos = 500 + accel_y_axis * 2;
servo2.writeMicroseconds(pos);
}
pos = 500 + accel_x_axis * 2 ;
servo7.writeMicroseconds(pos);
pos = 500 + accel_y_axis * 2 ;
servo8.writeMicroseconds(pos);
delay(50);
}
nun_Func.pde
void nunchuck_init()
{
Wire.begin();
Wire.beginTransmission(0x52);
Wire.send(0x40);
Wire.send(0x00);
Wire.endTransmission();
}
void nunchuck_send_request()
{
Wire.beginTransmission(0x52);
Wire.send(0x00);
Wire.endTransmission();
}
int nun_get()
{
int cnt=0;
Wire.requestFrom (0x52, 6);
while (Wire.available ())
{
nun_buf[cnt] = nun_decode(Wire.receive());
cnt++;
}
nunchuck_send_request();
if (cnt >= 5) {
return 1; //restituisce 1 se fallisce
}
return 0; //restituisce 0 se i dati sono stati ricevuti in maniera corretta
}
// decodifica valori nunchuck
char nun_decode (char x)
{
x = (x ^ 0x17) + 0x17;
return x;
}
void nun_read()
{
joy_x_axis = nun_buf[0];
joy_y_axis = nun_buf[1];
accel_x_axis = nun_buf[2] << 2;
accel_y_axis = nun_buf[3] << 2;
accel_z_axis = nun_buf[4] << 2;
z_but = 0;
c_but = 0;
if ((nun_buf[5] >> 0) & 1) z_but = 1;
if ((nun_buf[5] >> 1) & 1) c_but = 1;
if ((nun_buf[5] >> 2) & 1) accel_x_axis += 1;
if ((nun_buf[5] >> 3) & 1) accel_x_axis += 2;
if ((nun_buf[5] >> 4) & 1) accel_y_axis += 1;
if ((nun_buf[5] >> 5) & 1) accel_y_axis += 2;
if ((nun_buf[5] >> 6) & 1) accel_z_axis += 1;
if ((nun_buf[5] >> 7) & 1) accel_z_axis += 2;
// da decommentare solo per verifica corretto funzionamento Nunchuk
/*
Serial.print(accel_x_axis, DEC);
Serial.print(",");
Serial.print(accel_y_axis, DEC);
Serial.print(",");
Serial.print(accel_z_axis, DEC);
Serial.print(",");
Serial.print(joy_x_axis,DEC);
Serial.print(",");
Serial.print(joy_y_axis, DEC);
Serial.print(",");
Serial.print(z_but, DEC);
Serial.print(",");
Serial.println(c_but, DEC);
*/
}