Wielu miało tę zabawkę w dzieciństwie; kontrolowaliśmy ją za pomocą dwóch pokręteł. Nawet wtedy można było podłączyć do niego dwa silniki prądu stałego z zębatką i sterować nimi za pomocą przycisków. A teraz można w tym celu dostosować joysticki. Tak właśnie zrobił autor Instructables pod pseudonimem millerman4487.
Ale musiały zostać wydrukowane dwie identyczne części - są to adaptery do łączenia narzędzi z uchwytami Magic Screen. Wygląda jak dowolny z adapterów:
I tak łączy się ze skrzynią biegów (być może będzie to wymagać nieco rozgrzania adaptera suszarką do włosów):
Plik STL.
Jest tylko jeden niezrozumiały element - układ L293D. Zawiera dwa tak zwane mostki H, z których każdy może odwrócić podłączony do niego silnik. Poniżej planszy pokazano, jakie wnioski
Podłącz który ze styków złącza joysticka Wii Nunchuck. Poniższy szkic może zostać przepisany do pracy z innymi rodzajami joysticków, w jego obecnej formie będzie wymagany.
#include
#if (ARDUINO> 100)
#include
#else
#include
// # zdefiniuj Wire.write (x) Wire.send (x)
// # zdefiniuj Wire.read () Wire.receive ()
#endif
static uint8_t nunchuck_buf [6]; // tablica do przechowywania danych nunchuck,
// Wykorzystuje styki portu C (wejście analogowe) jako zasilanie i uziemienie dla Nunchuck
static void nunchuck_setpowerpins () {
# zdefiniować pwrpin PORTC3
# zdefiniować port PORTC2
DDRC | = _BV (pwrpin) | _BV (gndpin);
PORTC & = ~ _BV (gndpin);
PORTC | = _BV (pwrpin);
opóźnienie (100); // czekaj na ustabilizowanie się rzeczy
}
// zainicjuj system I2C, dołącz do magistrali I2C,
// powiedz nunchuckowi, że z nim rozmawiamy
static void nunchuck_init () {
Wire.begin (); // dołącz do magistrali i2c jako master
Wire.beginTransmission (0x52); // przesyłanie do urządzenia 0x52
#if (ARDUINO> 100)
Wire.write ((uint8_t) 0x40); // wysyła adres pamięci
Wire.write ((uint8_t) 0x00); // wysyła zero.
#else
Wire.send ((uint8_t) 0x40); // wysyła adres pamięci
Wire.send ((uint8_t) 0x00); // wysyła zero.
#endif
Wire.endTransmission (); // zatrzymaj transmisję
}
// Wyślij zapytanie o dane do nunchucka
// było „send_zero ()”
static void nunchuck_send_request () {
Wire.beginTransmission (0x52); // przesyłanie do urządzenia 0x52
#if (ARDUINO> 100)
Wire.write ((uint8_t) 0x00); // wysyła jeden bajt
#else
Wire.send ((uint8_t) 0x00); // wysyła jeden bajt
#endif
Wire.endTransmission (); // zatrzymaj transmisję
}
// Zakoduj dane, aby sformatować je z wyjątkiem większości sterowników wiimote
// potrzebne tylko, jeśli używasz jednego ze zwykłych sterowników wiimote
static char nunchuk_decode_byte (char x) {
x = (x ^ 0x17) + 0x17;
zwraca x;
}
// Odbierz dane z nunchucka,
// zwraca 1 po pomyślnym odczycie. zwraca 0 w przypadku niepowodzenia
static int nunchuck_get_data () {
int cnt = 0;
Wire.requestFrom (0x52, 6); // żądanie danych od nunchuck
while (Wire.available ()) {
// otrzymaj bajt jako liczbę całkowitą
#if (ARDUINO> 100)
nunchuck_buf [cnt] = nunchuk_decode_byte (Wire.read ());
#else
nunchuck_buf [cnt] = nunchuk_decode_byte (Wire.receive ());
#endif
cnt ++;
}
nunchuck_send_request (); // wyślij żądanie następnego ładunku danych
// Jeśli otrzymaliśmy 6 bajtów, to wydrukuj je
jeśli (cnt>> = 5) {
zwraca 1; // sukces
}
zwraca 0; // awaria
}
// Wydrukuj otrzymane dane wejściowe
// dane accel mają długość 10 bitów
// więc czytamy 8 bitów, a następnie musimy dodać
// na ostatnich 2 bitach. Dlatego ja
// pomnóż je przez 2 * 2
static void nunchuck_print_data () {
statyczny int i = 0;
int joy_x_axis = nunchuck_buf [0];
int joy_y_axis = nunchuck_buf [1];
int accel_x_axis = nunchuck_buf [2]; // * 2 * 2;
int accel_y_axis = nunchuck_buf [3]; // * 2 * 2;
int accel_z_axis = nunchuck_buf [4]; // * 2 * 2;
int z_button = 0;
int c_button = 0;
// bajt nunchuck_buf [5] zawiera bity dla przycisków z i c
// zawiera również najmniej znaczące bity dla danych akcelerometru
// więc musimy sprawdzić każdy bit bajtu outbuf [5]
if ((nunchuck_buf [5] & gt; & gt; 0) & 1)
przycisk z_ = 1;
if ((nunchuck_buf [5] & gt; & gt; 1) & 1)
przycisk c_ = 1;
if ((nunchuck_buf [5] & gt; & gt; 2) & 1)
accel_x_axis + = 1;
if ((nunchuck_buf [5] & gt; & gt; 3) & 1)
accel_x_axis + = 2;
if ((nunchuck_buf [5] & gt; & gt; 4) & 1)
accel_y_axis + = 1;
if ((nunchuck_buf [5] & gt; & gt; 5) & 1)
accel_y_axis + = 2;
if ((nunchuck_buf [5] & gt; & gt; 6) & 1)
accel_z_axis + = 1;
if ((nunchuck_buf [5] & gt; & gt; 7) & 1)
accel_z_axis + = 2;
Numer seryjny (i, DEC);
Serial.print („\ t”);
Serial.print („joy:”);
Serial.print (joy_x_axis, DEC);
Serial.print (",");
Serial.print (joy_y_axis, DEC);
Serial.print („\ t”);
Serial.print („acc:”);
Serial.print (accel_x_axis, DEC);
Serial.print (",");
Serial.print (accel_y_axis, DEC);
Serial.print (",");
Serial.print (accel_z_axis, DEC);
Serial.print („\ t”);
Serial.print („but:”);
Serial.print (z_button, DEC);
Serial.print (",");
Serial.print (c_button, DEC);
Serial.print ("\ r \ n"); // nowa linia
i ++;
}
// zwraca stan zbutton: 1 = wciśnięty, 0 = nie wciśnięty
static int nunchuck_zbutton () {
return ((nunchuck_buf [5] & gt; & gt; 0) & 1)? 0–1 // voodoo
}
// zwraca stan zbutton: 1 = wciśnięty, 0 = nie wciśnięty
static int nunchuck_cbutton () {
return ((nunchuck_buf [5] & gt; & gt; 1) & 1)? 0–1 // voodoo
}
// zwraca wartość joysticka w osi X.
static int nunchuck_joyx () {
return nunchuck_buf [0];
}
// zwraca wartość joysticka w osi y
static int nunchuck_joyy () {
return nunchuck_buf [1];
}
// zwraca wartość akcelerometru osi x
static int nunchuck_accelx () {
return nunchuck_buf [2]; // FIXME: pomija 2 bity danych
}
// zwraca wartość akcelerometru na osi y
static int nunchuck_accely () {
return nunchuck_buf [3]; // FIXME: pomija 2 bity danych
}
// zwraca wartość akcelerometru osi Z.
static int nunchuck_accelz () {
return nunchuck_buf [4]; // FIXME: pomija 2 bity danych
}
int loop_cnt = 0;
bajt joyx, joyy, zbut, cbut, accx, accy, accz;
void _print () {
Serial.print („\ tX Joy:”);
Numer seryjny (mapa (joyx, 15, 221, 0, 255));
Serial.print („\ tY Radość:”);
Serial.println (mapa (joyy, 29, 229, 0, 255));
}
int joyx1 = 129; // 15 - 221
int joyy1 = 124; // 29–229
void setup () {
Serial.begin (9600);
nunchuck_setpowerpins ();
nunchuck_init (); // wyślij uzgadnianie inicjujące
Serial.println („Wii Nunchuck Ready”);
pinMode (3, WYJŚCIE);
pinMode (5, WYJŚCIE);
pinMode (6, WYJŚCIE);
pinMode (9, WYJŚCIE);
// type ();
}
void loop () {
if (loop_cnt & gt; 10) {// co 100 ms otrzymuje nowe dane
loop_cnt = 0;
nunchuck_get_data ();
zbut = nunchuck_zbutton ();
joyx = nunchuck_joyx (); // 15 - 221
joyy = nunchuck_joyy (); // 29–229
_print ();
}
loop_cnt ++;
if (zbut == 1) {
type ();
zbut = 0;
}
jeszcze {
if (joyx & gt; (joyx1 + 20)) {
int speed1 = mapa (joyx - joyx1, 0, 80, 40, 255);
prędkość1 = ograniczenie (prędkość1, 0, 255);
analogWrite (6, 0);
analogWrite (9, prędkość1);
}
else if (joyx & lt; (joyx1 - 20)) {
int speed2 = mapa (joyx1 - joyx, 0, 90, 40, 255);
prędkość2 = ograniczenie (prędkość2, 0, 255);
analogWrite (6, prędkość2);
analogWrite (9, 0);
}
jeszcze {
analogWrite (6, 0);
analogWrite (9, 0);
}
if (joyy & gt; (joyy1 + 20)) {
int speed3 = mapa (joyy - joyy1, 0, 80, 40, 255);
prędkość3 = ograniczenie (prędkość3, 0, 255);
analogWrite (3, 0);
analogWrite (5, prędkość3);
}
else if (joyy & lt; (joyy1 - 20)) {
int speed4 = mapa (joyy1 - joyy, 0, 90, 40, 255);
speed4 = ograniczenie (speed4, 0, 255);
analogWrite (3, prędkość4);
analogWrite (5, 0);
}
jeszcze {
analogWrite (3, 0);
analogWrite (5, 0);
}
}
opóźnienie (1);
}
void type () {
int rltime = 200;
// digitalWrite (6, 1); // origin
// digitalWrite (9, 0);
// digitalWrite (3, 1);
// digitalWrite (5, 0);
// opóźnienie (1000);
// H ===============
// digitalWrite (3, 0); // czekaj
// digitalWrite (5, 0);
// digitalWrite (6, 0);
// digitalWrite (9, 0);
// opóźnienie (250);
// digitalWrite (3, 0); // w górę
digitalWrite (5, 1);
opóźnienie (500);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (3, 1); // dół
// digitalWrite (5, 0);
opóźnienie (250);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
// digitalWrite (6, 0); // prawo
digitalWrite (9, 1);
opóźnienie (rltime);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
// digitalWrite (3, 0); // w górę
digitalWrite (5, 1);
opóźnienie (250);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (3, 1); // dół
// digitalWrite (5, 0);
opóźnienie (500);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
// digitalWrite (6, 0); // prawo
digitalWrite (9, 1);
opóźnienie (rltime);
// I ==========================
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (3, 0); // w górę
digitalWrite (5, 1);
opóźnienie (500);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (6, 0); // prawo
digitalWrite (9, 1);
opóźnienie (100);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (6, 1); // left
digitalWrite (9, 0);
opóźnienie (rltime);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (6, 0); // prawo
digitalWrite (9, 1);
opóźnienie (100);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (3, 1); // dół
digitalWrite (5, 0);
opóźnienie (500);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (6, 0); // prawo
digitalWrite (9, 1);
opóźnienie (100);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
digitalWrite (6, 1); // left
digitalWrite (9, 0);
opóźnienie (rltime);
digitalWrite (3, 0); // czekaj
digitalWrite (5, 0);
digitalWrite (6, 0);
digitalWrite (9, 0);
opóźnienie (250);
}
Po włączeniu prawidłowo zmontowane urządzenie natychmiast zaczyna działać. Nunchuck to analogowy joystick, więc możesz kontrolować nie tylko kierunek, ale także prędkość ruchu. Arduino przejmuje kontrolę prędkości PWM. Jeśli ruch wzdłuż którejkolwiek z osi występuje w przeciwnym kierunku, odpowiedni silnik musi zostać odwrócony. Umieszczając kursor w przybliżeniu na środku ekranu i naciskając przycisk Z, można ustawić automatyczne wpisywanie słowa HI przez urządzenie.