Esta es una biblioteca para usar el Wii Nunchuk con el ESP32 vía I2C. Se puede utilizar tanto con el IDE de Arduino como con código usando el ESP-IDF directamente. Para usar la biblioteca en su boceto Arduino IDE, simplemente copie los archivos wii_i2c.c
y wii_i2c.h
a su directorio de boceto.
Esta biblioteca utiliza la API ESP-IDF I2C porque la biblioteca Arduino Wire no funciona de manera confiable en ESP32 con controladores Wii.
Esta biblioteca es compatible con Wii Nunchuk y Wii Classic Controller . No debería ser difícil adaptarlo para que funcione con otros dispositivos I2C que se conectan al Wiimote (como el Classic Controller Pro, Wii Motion Plus, etc.) con la información disponible en el proyecto Wiibrew, pero no tengo ninguno de estos dispositivos. así que no lo sé con seguridad.
La biblioteca Arduino Wire para ESP32 (de Wire.h
) utiliza el puerto I2C 0 para el objeto Wire
y el puerto 1 para el objeto Wire1
. Por lo tanto, no use Wire
si usa el puerto I2C 0 con esta biblioteca, y no use Wire1
si usa el puerto I2C 1.
Aquí hay un ejemplo simple usando el Wii Nunchuk. Para obtener un ejemplo más completo que detecta y maneja múltiples tipos de controladores, consulte 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 );
}
Si tiene un código urgente que no puede esperar a que el controlador responda, use la función API que genera una tarea que lee el estado del controlador en un núcleo diferente. Por ejemplo:
# 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
}