Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

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