Esta é uma biblioteca para usar o Wii Nunchuk com o ESP32 via I2C. Pode ser usado tanto com o Arduino IDE quanto com código usando o ESP-IDF diretamente. Para usar a biblioteca no sketch do Arduino IDE, basta copiar os arquivos wii_i2c.c
e wii_i2c.h
para o diretório do sketch.
Esta biblioteca usa a API ESP-IDF I2C porque a biblioteca Arduino Wire não funciona de forma confiável no ESP32 com controladores Wii.
Esta biblioteca suporta o Wii Nunchuk e o Wii Classic Controller . Não deve ser difícil adaptá-lo para funcionar com outros dispositivos I2C que conectam o Wiimote (como o Classic Controller Pro, Wii Motion Plus, etc.) com as informações disponíveis no projeto Wiibrew, mas não tenho nenhum desses dispositivos então não tenho certeza.
A Arduino Wire Library para ESP32 (de Wire.h
) usa a porta I2C 0 para o objeto Wire
e a porta 1 para o objeto Wire1
. Portanto, não use Wire
se estiver usando a porta I2C 0 com esta biblioteca, e não use Wire1
se estiver usando a porta I2C 1.
Aqui está um exemplo simples usando o Wii Nunchuk. Para um exemplo mais completo que detecta e lida com vários tipos de controlador, 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 );
}
Se você tiver um código urgente que não pode esperar a resposta do controlador, use a função de API que gera uma tarefa que lê o estado do controlador em um núcleo diferente. Por exemplo:
# 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
}