Indietro

Come usare MultiWii per giocare senza usare un vero apparato radio!

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 ).

Utilizzo:

  • Premendo il tasto C il joystick si azionano 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

# 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); 

}

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);
  • /

}

Indietro

Share