นี่คือห้องสมุดสำหรับใช้ Wii Nunchuk กับ ESP32 ผ่าน I2C สามารถใช้กับ Arduino IDE หรือโค้ดโดยใช้ ESP-IDF โดยตรง หากต้องการใช้ไลบรารีในภาพร่าง Arduino IDE เพียงคัดลอกไฟล์ wii_i2c.c
และ wii_i2c.h
ไปยังไดเร็กทอรีภาพร่างของคุณ
ไลบรารีนี้ใช้ ESP-IDF I2C API เนื่องจากไลบรารี Arduino Wire ไม่ทำงานอย่างน่าเชื่อถือใน ESP32 ที่มีตัวควบคุม Wii
ไลบรารีนี้รองรับ Wii Nunchuk และ Wii Classic Controller การปรับให้ทำงานร่วมกับอุปกรณ์ I2C อื่นๆ ที่เสียบ Wiimote ได้ (เช่น Classic Controller Pro, Wii Motion Plus เป็นต้น) ไม่ใช่เรื่องยาก โดยมีข้อมูลที่มีอยู่ในโปรเจ็กต์ Wiibrew แต่ฉันไม่มีอุปกรณ์เหล่านี้เลย ดังนั้นฉันจึงไม่ทราบแน่ชัด
Arduino Wire Library สำหรับ ESP32 (จาก Wire.h
) ใช้พอร์ต I2C 0 สำหรับวัตถุ Wire
และพอร์ต 1 สำหรับวัตถุ Wire1
ดังนั้นอย่าใช้ Wire
หากใช้พอร์ต I2C 0 กับไลบรารีนี้ และอย่าใช้ Wire1
หากใช้พอร์ต I2C 1
นี่เป็นตัวอย่างง่ายๆ โดยใช้ Wii Nunchuk หากต้องการตัวอย่างที่สมบูรณ์ยิ่งขึ้นที่ตรวจจับและจัดการคอนโทรลเลอร์หลายประเภท โปรดดูที่ esp32-wii-nunchuk.ino
# include " wii_i2c.h "
// pins connected to the Nunchuk:
# define PIN_SDA 32
# define PIN_SCL 33
// ESP32 I2C port (0 or 1):
# define WII_I2C_PORT 0
void setup ()
{
Serial. begin ( 115200 );
if ( wii_i2c_init (WII_I2C_PORT, PIN_SDA, PIN_SCL) != 0 ) {
Serial. printf ( " Error initializing nunchuk :( " );
return ;
}
wii_i2c_request_state ();
}
void loop ()
{
const unsigned char *data = wii_i2c_read_state ();
wii_i2c_request_state ();
if (! data) {
Serial. printf ( " no data available :( " )
} else {
wii_i2c_nunchuk_state state;
wii_i2c_decode_nunchuk (data, &state);
Serial. printf ( " Stick position: (%d,%d) n " , state. x , state. y );
Serial. printf ( " C button is %s n " , (state. c ) ? " pressed " : " not pressed " );
Serial. printf ( " Z button is %s n " , (state. z ) ? " pressed " : " not pressed " );
}
delay ( 1000 );
}
หากคุณมีโค้ดที่ไวต่อเวลาซึ่งไม่สามารถรอให้คอนโทรลเลอร์ตอบสนองได้ ให้ใช้ฟังก์ชัน API ที่สร้างงานที่อ่านสถานะของคอนโทรลเลอร์ในคอร์อื่น ตัวอย่างเช่น:
# include " wii_i2c.h "
// pins connected to the controller:
# define PIN_SDA 32
# define PIN_SCL 33
// ESP32 I2C port (0 or 1):
# define WII_I2C_PORT 0
// CPU id where the task will run (1=the core
// where your code usually runs, 0=the other core):
# define READ_TASK_CPU 0
// delay in milliseconds between controller reads:
# define READ_DELAY 30
static unsigned int controller_type;
void setup ()
{
Serial. begin ( 115200 );
if ( wii_i2c_init (WII_I2C_PORT, PIN_SDA, PIN_SCL) != 0 ) {
Serial. printf ( " Error initializing nunchuk :( " );
return ;
}
// if you want to read the controller identity,
// do it BEFORE starting the read task:
const unsigned char *ident = wii_i2c_read_ident ();
controller_type = wii_i2c_decode_ident (ident);
// start the a task that reads the controller state in a different CPU:
if ( wii_i2c_start_read_task (READ_TASK_CPU, READ_DELAY) != 0 ) {
Serial. printf ( " Error creating task to read controller state " );
return ;
}
}
void loop ()
{
// this function always returns quickly, either
// with new data or NULL if data isn't ready:
const unsigned char *data = wii_i2c_read_data_from_task ();
if (data) {
// decode data according to controller_type:
// wii_i2c_decode_nunchuk(data, &nunchuk_state);
// wii_i2c_decode_classic(data, &classic_state);
}
// do other timing-sensitive stuff
}