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, il cui joystick aziona i primi due canali (1 e 2) e l'accelerometro gli ultimi due (7 e 8 ).
Leggete attentamente tutte le note in testa allo sketch.
Lo sketch è diviso in due file .pde il primo è quello principale.
/* 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
# Non è garantito il corretto funzionamento con Nunchuk non originali.
# 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.
# 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.
# 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);
}
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);
}