Wii ヌンチャクを I2C 経由で ESP32 で使用するためのライブラリです。 Arduino IDE または ESP-IDF を直接使用するコードの両方で使用できます。 Arduino IDE スケッチでライブラリを使用するには、ファイルwii_i2c.c
とwii_i2c.h
スケッチ ディレクトリにコピーするだけです。
Arduino Wire ライブラリは Wii コントローラを備えた ESP32 では確実に動作しないため、このライブラリは ESP-IDF I2C API を使用します。
このライブラリは、 Wii ヌンチャクとWii クラシック コントローラをサポートしています。 Wiibrew プロジェクトで入手可能な情報を使用して、Wii リモコンに接続する他の I2C デバイス (クラシック コントローラー プロ、Wii モーション プラスなど) で動作するように調整するのは難しくないはずですが、私はこれらのデバイスを持っていません。だから確かなことは分かりません。
ESP32 用の Arduino Wire Library ( Wire.h
より) は、 Wire
オブジェクトに I2C ポート 0 を使用し、 Wire1
オブジェクトにポート 1 を使用します。したがって、このライブラリで I2C ポート 0 を使用する場合はWire
使用しないでください。また、I2C ポート 1 を使用する場合はWire1
使用しないでください。
Wii ヌンチャクを使用した簡単な例を次に示します。複数のコントローラー タイプを検出して処理するより完全な例については、 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
}