Это библиотека для использования Wii Nunchuk с ESP32 через I2C. Его можно использовать как с Arduino IDE, так и с кодом, использующим напрямую ESP-IDF. Чтобы использовать библиотеку в скетче Arduino IDE, просто скопируйте файлы wii_i2c.c
и wii_i2c.h
в каталог скетча.
Эта библиотека использует API ESP-IDF I2C, поскольку библиотека Arduino Wire не работает надежно в ESP32 с контроллерами Wii.
Эта библиотека поддерживает Wii Nunchuk и Wii Classic Controller . Нетрудно адаптировать его для работы с другими устройствами I2C, которые подключают Wiimote (например, Classic Controller Pro, Wii Motion Plus и т. д.), используя информацию, доступную в проекте Wiibrew, но у меня нет ни одного из этих устройств. так что я не знаю точно.
Библиотека проводов Arduino для 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
}