Mengintegrasikan Wii Nunchuk dengan Arduino: Panduan Langkah demi Langkah
Komponen dan Perlengkapan
Nintendo Nunchuk × 1
SparkFun Level Shifter × 1
Arduino UNO × 1
Tentang Proyek Ini
Pendahuluan
Aslinya, postingan ini diterbitkan pada www.xarg.org.
Menggunakan Wii Nunchuk dengan Arduino
Kita semua tumbuh dengan pengendali game di tangan, yang menjadikannya ideal untuk dikombinasikan dengan hampir setiap aplikasi yang mungkin. Pengemukan hebat dari Nintendo adalah Nunchuk, ekstensi murah untuk remote Wii U. Karena menggunakan I2C sebagai protokol transportasi, mudah untuk mengakses data mentah dari pengendali. Karena sangat mudah, saya pikir pasti ada solusi standar untuk itu, tapi saya tidak menemukan implementasi yang stabil, hanya banyak cuplikan kode. Itulah mengapa saya berfokus pada mengisi kesenjangan ini, dan inilah hasilnya. Dalam artikel ini, saya akan memandu Anda melalui detailnya dan mengimplementasikannya untuk Arduino.
Hardware
Nunchuk memiliki dua tombol membran, disebut tombol C dan tombol Z. Di atas perangkat ada joystick dua sumbu analog dan seluruh perangkat sensitif terhadap gerakan, karena akselerometer mengukur gaya yang bekerja pada ketiga dimensi. Direkomendasikan untuk mengoperasikan Nunchuk dengan 3v3 dan Anda sebaiknya menggunakan level shifter jika Anda tidak dapat menyediakan tegangan itu untuk meningkatkan umur panjangnya. Sebagai minimum, Anda akan membutuhkan bagian berikut untuk pengaturan ini:
Bagian
Nintendo Nunchuk (atau replika)
Arduino
Level Shifter (opsional)
Nunchuk Adapter (opsional)
Nunchuk Asli atau Replika
Pertanyaan besar adalah, apakah Anda harus membeli Nintendo Nunchuk asli atau replika China? Untuk menguji driver Nunchuk saya, saya membeli keduanya — asli dan replika murah. Keduanya jauh dari mahal, tetapi selisihnya sekitar 10-15€. Yang dapat saya katakan adalah, kabel kabel pada kabel Nunchuk asli dilindungi, yang membuatnya lebih tahan terhadap gangguan. Joystick pada asli memiliki kualitas yang lebih tinggi, dapat menyelesaikan semua gerakan dalam rentang nilai penuh, sementara replika tidak bereaksi terhadap gerakan minimal. Juga kualitas akselerometer pada asli lebih baik. Namun, saya menerapkan Kalman Filter, yang menyamarkan perbedaan ini. Jadi, jika Anda ingin pengendali yang awet, saya akan memilih asli, jika Anda hanya membutuhkan perangkat input murah, Anda mungkin beruntung dengan salinan Nunchuk.
Konektor Nunchuk
Nintendo menghubungkan semua periferal dengan soket miliknya. Karena saya tidak memiliki Wii dan tidak akan menggunakan pengendali untuk sesuatu yang berkaitan dengan game, saya merobek konektor. Anda dapat mendapatkan adapter Nunchuk untuk beberapa dolar, jika Anda tidak ingin melakukan langkah drastis ini, tetapi dengan keterampilan solder, Anda seharusnya dapat memperbaiki soketnya. Saya merekomendasikan membuka soket, karena Anda dapat melihat bagaimana kabel terhubung ke pin. Ini sangat penting untuk replika Nunchuk, karena kabel dapat terhubung secara acak. Hal aneh lainnya adalah, pengendali asli memiliki 4 kabel dan replika memiliki 5, sementara soket sebenarnya memiliki 6 pin. Baiklah, mari kita bekerja dan buka soketnya:
Dan potong kabelnya:
Saat melihat depan soket, Anda akan melihat pin ini:
Untuk Nunchuk asli, berikut adalah warna dan tata letak pin soket:
Hijau → SDA
nc
Merah → 3v3
Putih → GND
nc
Kuning → SCL
Untuk klon Nunchuk yang saya dapatkan, berikut adalah warna dan tata letak pin soket:
Kuning → SDA
Hitam → nc
Hijau → 3v3
Merah → GND
nc
Putih → SCL
Seperti yang saya katakan, Anda sebaiknya melihat bagaimana kabel disusun dan tidak menghubungkan apa pun berdasarkan warnanya. Singkatan yang digunakan adalah: nc untuk tidak terhubung, SDA - garis data (harus terhubung dengan A4 pada papan Arduino) dan SCL - jam (terhubung dengan A5). Arduino memiliki regulator tegangan, yang memungkinkan kita untuk menggunakan 3v3 langsung. Jika Anda ingin menggunakan WiiChuck atau adapter Nunchuk serupa, hubungkan 3v3 dengan A2 dan GND dengan A1 - nantinya Anda perlu memanggil nunchuk_init_power() untuk menginisialisasi konektor suplai daya ini. Sketsa Fritzing berikut menunjukkan koneksi:
Software
Saya menulis perpustakaan header kecil yang mengimplementasikan komunikasi dengan Nunchuk. Faktanya, Anda tidak perlu khawatir tentang apa yang terjadi di balik layar, itu seharusnya bekerja langsung dari kotak. Jika Anda tertarik dengan detailnya, saya akan menjelaskannya dalam sebentar.
Unduh Perpustakaan Nunchuk
Komunikasi dengan Nunchuk dilakukan melalui bus TWI, yang merupakan nama lain untuk I2C (baik, beberapa detail berbeda, yang tidak penting untuk tujuan kami). Kecepatan bus I2C diatur ke Fast Mode (400kHz) secara default. Untuk menggunakan Nunchuk dengan Arduino Anda, hanya yang berikut ini yang diperlukan:
#include <Wire.h> #include "nunchuk.h" void setup() { Serial.begin(9600); Wire.begin(); // nunchuk_init_power(); // A1 and A2 is power supply nunchuk_init(); } void loop() { if (nunchuk_read()) { // Work with nunchuk_data nunchuk_print(); } delay(10); }
Saat memulai file Processing yang dikirim bersama perpustakaan, Anda dapat menyeimbangkan kerucut ini dengan Nunchuk Anda:
Alih-alih nunchuk_print() banyak fungsi dapat digunakan untuk mengakses data aktual:
Fungsi Nunchuk
nunchuk_buttonZ(): 1 atau 0, apakah tombol Z ditekan atau tidak
nunchuk_buttonC(): 1 atau 0, apakah tombol C ditekan atau tidak
nunchuk_joystickX_raw() / nunchuk_joystickX() nunchuk_joystickY_raw() / nunchuk_joystickY(): Nilai x- atau y-joystick. Versi mentah untuk setiap fungsi memberikan akses ke data tanpa kalibrasi.
nunchuk_joystick_angle():Menghitung sudut joystick dalam radian.
nunchuk_accelX_raw() / nunchuk_accelX() nunchuk_accelY_raw() / nunchuk_accelY() nunchuk_accelZ_raw() / nunchuk_accelZ(): Nilai x-, y- atau z-akselerometer. Versi mentah untuk setiap fungsi memberikan akses ke data tanpa kalibrasi.
nunchuk_pitch(): Menghitung sudut pitch pengendali dalam radian.
nunchuk_roll(): Menghitung sudut roll pengendali dalam radian.
Catatan: Tidak ada fungsi nunchuk_yaw(), karena akselerometer hanya dapat mengukur gaya arah dan tidak ada kecepatan rotasi. Hal ini juga membatasi pitch hanya hingga 180° dan memaksa sudut roll menjadi salah ketika pitch lebih besar dari 180°.
Perhitungan sudut pitch dan roll juga bekerja dengan asumsi menyederhanakan, bahwa satu-satunya kecepatan yang bekerja pada pengendali adalah gravitasi. Ini bekerja karena Nunchuk dipegang diam atau mengalami kecepatan konstan dari gaya eksternal.
Kalibrasi
Seperti yang dijelaskan dalam ringkasan fungsi, setiap fungsi joystick dan akselerometer hadir dengan versi terkalibrasi dan mentah. Di awal file perpustakaan, beberapa konstanta menentukan posisi nol. Hal terbaik adalah membaca ukuran mentah pengendali Anda saat Anda memegangnya dalam posisi netral dan menyesuaikan konstanta sesuai dengan itu.
Protokol I2C
Bagian terakhir di sini membahas protokol I2C aktual. Jika Anda hanya ingin menggunakan pengendali, informasi ini tidak diperlukan, tapi jika Anda ingin memahami protokol, saya harap dapat menghemat waktu Anda.
Saya mulai mengembangkan dengan memindai alamat aktual Nunchuk dengan scanner I2C saya, yaitu 0x52. Membaca parameter dari memori Nunchuk melalui bus I2K cukup mirip dengan komunikasi dengan EEPROM I2K normal. Sebelum data dari Nunchuk dapat dibaca, perlu mengirimkan urutan inisialisasi.
Untuk membaca data dari Nunchuk, perlu mengirim alamat yang akan dibaca, karena pengendali Nunchuk meningkatkan alamat setiap kali dibaca. Data yang kita inginkan sebenarnya terletak di alamat 0x00 dan berukuran 6 byte. Di alamat 0x20 dan 0x30 (tampaknya salinan tepat dari byte di 0x20), 16 byte data kalibrasi disimpan. Di alamat 0xFA Anda dapat menemukan nomor identifikasi perangkat, yaitu 0xA4200000 untuk Nunchuck, 0xA4200101 untuk Classic Controller, 0xA4200402 untuk Balance dan seterusnya.
Ketika data perlu ditulis ke Nunchuk, formatnya mirip dengan perintah baca. Byte pertama adalah alamat, diikuti oleh data aktual.
Mari kita telusuri urutan byte aktual dari Nunchuk untuk fitur yang dijelaskan:
1. Inisialisasi Nunchuk:
START, 0x40, 0x00, STOP
Urutan ini adalah urutan inisialisasi normal, yang mengatur algoritma enkripsi ke default. Setiap byte yang dibaca dari Nunchuk harus kemudian dienkripsi dengan (x ^ 0x17) + 0x17. Cara yang lebih baik adalah menonaktifkan enkripsi dengan urutan ini:
2. Inisialisasi Nunchuk tanpa enkripsi:
START, 0xF0, 0x55, STOPSTART, 0xFB, 0x00, STOP
Ini memiliki manfaat bahwa data aktual dapat digunakan tanpa rumus dekripsi dan akan bekerja dengan klon Nunchuk juga.
3. Baca identifikasi perangkat dari register ekstensi:
START, 0xFA, STOPREAD 6 byte
Data adalah identifikasi, yang sudah saya sebutkan, jika perangkat yang terhubung adalah Nunchuk atau Classic controller dan seterusnya.
4. Baca pengukuran dari perangkat:
START, 0x00, STOPREAD 6 byte
Yang Anda peroleh kembali dijelaskan dalam ringkasan ini:
Bit Byte 7 6 5 4 3 2 1 0
1 Joystick X-Axis [7:0]
2 Joystick Y-Axis [7:0]
3 Accelerometer X-Axis [9:2]
4 Accelerometer Y-Axis [9:2]
5 Accelerometer Z-Axis [9:2]
6 Az [1:0] Ay [1:0] Ax [1:0] ¬Bc ¬Bz
Jadi, nilai tombol terbalik, dan bit LSB akselerometer terkandung dalam byte 6. Dalam perpustakaan, saya menggabungkan bit LSB dengan sisanya. Saya telah melihat orang-orang menggunakan nilai tanpa bit LSB, yang merupakan cara terlalu sederhana untuk membuat sinyal lebih stabil. Bagi saya, saya lebih suka sinyal berisik dari ADC, yang dapat difilter dengan Filter Komplementer atau Kalman alih-alih memotong angka dengan pembulatan - di mana Anda kehilangan banyak informasi.
5. Baca data kalibrasi aktual dari perangkat:
START, 0x20, STOP READ 16byte
Yang Anda peroleh kembali dijelaskan dalam ringkasan ini:
Byte
Deskripsi
1 Nilai 0G sumbu X [9:2]
2 Nilai 0G sumbu Y [9:2]
3 Nilai 0G sumbu Z [9:2]
4 LSB Nilai Nol sumbu X,Y,Z
5 Nilai 1G sumbu X [9:2]
6 Nilai 1G sumbu Y [9:2]
7 Nilai 1G sumbu Z [9:2]
8 LSB Nilai 1G sumbu X,Y,Z
9 Maksimum sumbu X joystick
10 Minimum sumbu X joystick
11 Titik tengah sumbu X joystick
12 Maksimum sumbu Y joystick
13 Minimum sumbu Y joystick
14 Titik tengah sumbu Y joystick
15 Checksum
16 Checksum
Byte 0-3 menyimpan nilai nol sumbu X, Y dan Z, sementara byte 4-7 menyimpan nilai pada 1G (gravitasi bumi). Data kalibrasi belum digunakan dalam implementasi perangkat lunak.
Kode
Cuplikan kode #1
Cuplikan kode #1Plain text
#include <Wire.h> #include "nunchuk.h" void setup() { Serial.begin(9600); Wire.begin(); // nunchuk_init_power(); // A1 and A2 is power supply nunchuk_init(); } void loop() { if (nunchuk_read()) { // Work with nunchuk_data nunchuk_print(); } delay(10); }