はじめに
ジョイスティックの検出について記載します。
ジョイスティック - HW-504
ジョイスティックは、HW-504を使用します。
HW-504は以下のことができます。
- x軸, y軸の検出
- analogRead()を使用して、読み込みます
- スイッチのON/OFFの読み取り
- 今回は使用しません
ESP32のピンアサイン
ESP32のピンアサインは、下記のようになっています。(DataSheetより抜粋)
Name | No. | Type | Function | 備考 |
---|---|---|---|---|
ND | 1 | P | Ground | - |
3V3 | 2 | P | Power supply | - |
EN | 3 | I | Module-enable signal. Active high. | - |
SENSOR_VP | 4 | I | GPIO36, ADC1_CH0, RTC_GPIO0 | - |
SENSOR_VN | 5 | I | GPIO39, ADC1_CH3, RTC_GPIO3 | - |
IO34 | 6 | I | GPIO34, ADC1_CH6, RTC_GPIO4 | - |
IO35 | 7 | I | GPIO35, ADC1_CH7, RTC_GPIO5 | - |
IO32 | 8 | I/O | GPIO32, XTAL_32K_P (32.768kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 | - |
IO33 | 9 | I/O | GPIO33, XTAL_32K_N (32.768kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 | - |
IO25 | 10 | I/O | GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 | y軸取得 |
IO26 | 11 | I/O | GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 | x軸取得 |
IO27 | 12 | I/O | GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV | - |
IO14 | 13 | I/O | GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 | - |
IO12 | 14 | I/O | GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 | - |
GND | 15 | P | Ground | - |
IO13 | 16 | I/O | GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER | - |
SHD/SD2* | 17 | I/O | GPIO9, SD_DATA2, SPIHD, HS1_DATA2, U1RXD | - |
SWP/SD3* | 18 | I/O | GPIO10, SD_DATA3, SPIWP, HS1_DATA3, U1TXD | - |
SCS/CMD* | 19 | I/O | GPIO11, SD_CMD, SPICS0, HS1_CMD, U1RTS | - |
SCK/CLK* | 20 | I/O | GPIO6, SD_CLK, SPICLK, HS1_CLK, U1CTS | - |
SDO/SD0* | 21 | I/O | GPIO7, SD_DATA0, SPIQ, HS1_DATA0, U2RTS | - |
SDI/SD1* | 22 | I/O | GPIO8, SD_DATA1, SPID, HS1_DATA1, U2CTS | - |
IO15 | 23 | I/O | GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 | - |
IO2 | 24 | I/O | GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 | - |
IO0 | 25 | I/O | GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK | - |
IO4 | 26 | I/O | GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER | - |
IO16 | 27 | I/O | GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT | - |
IO17 | 28 | I/O | GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 | - |
IO5 | 29 | I/O | GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK | - |
IO18 | 30 | I/O | GPIO18, VSPICLK, HS1_DATA7 | - |
IO19 | 31 | I/O | GPIO19, VSPIQ, U0CTS, EMAC_TXD0 | - |
NC | 32 | - | - | - |
IO21 | 33 | I/O | GPIO21, VSPIHD, EMAC_TX_EN | - |
RXD0 | 34 | I/O | GPIO3, U0RXD, CLK_OUT2 | - |
TXD0 | 35 | I/O | GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 | - |
IO22 | 36 | I/O | GPIO22, VSPIWP, U0RTS, EMAC_TXD1 | - |
IO23 | 37 | I/O | GPIO23, VSPID, HS1_STROBE | - |
GND | 38 | P | Ground | - |
GND | 39 | P | Ground | - |
analogRead()を使用するため、ADC*_CH*のピンを選択する必要があります。
- IO26
- ADC2_CH9
- x軸の読み出し
- IO25
- ADC2_CH8
- y軸の読み出し
開発環境
以下が確認した環境となります。
- windows10 64bit
- Arduino IDE 1.8.10
- Esplora Built-In by Arduino 1.0.4
- FreeRTOS by Richard Barry 10.2.0-3
- vscode 1.41.1
- PlatformIO - Home 3.0.1, Core 4.1.0
※Arduino IDEでも動くことは確認しましたが、
Arduino IDEで動かす場合は、main.cppを.inoファイルに置き換える必要があります。
機材
※型名が購入先のリンクになっています。
項目 | 型名 | 備考 |
---|---|---|
ESP32-WROOM-32 開発ボード | NodeMCU-32S ESP32-WROOM-32 | - |
ジョイスティック | ジョイスティック ブレークアウト シールドモジュール ジョイスティック ゲーム コントローラ モジュール PS2 | - |
ブレッドボード | 指定なし | |
ジャンパーケーブル | 指定なし |
接続図
※今回、スイッチ(SW)は使用しないので、未接続になっています。
シーケンス図
作成するプログラムのシーケンス図は、以下となります。
コードの配置場所
コードは、下記に配置してあります。
esp32Samples - SampleJs
シーケンスとコードとの紐づけ
シーケンスとコードの関連箇所を抜粋して記載します。
初期化処理
JoyStickのPIN設定
- 使用するPINの定義
Sytem_Js.h
#define JS_ASGN_AXIS_X (26)
#define JS_ASGN_AXIS_Y (25)
- PINの設定
ApiJs.cpp
pinMode(JS_ASGN_AXIS_X, INPUT);
pinMode(JS_ASGN_AXIS_Y, INPUT);
ジョイスティック用タイマーの生成
ApiJs.cpp
#define JS_CHECK_TIME (50) //JoyStickチェック間隔:50msec
...
static TimerHandle_t s_xTimerJs = NULL;
...
ErType_t xInitJs(void)
{
...
s_xTimerJs = xTimerCreate
( cName, //text name
JS_CHECK_TIME, //timer period
pdTRUE, //auto-reload
( void * ) 0, //number of times
vTimerCallbackJs //callback
);
xTimerReset( s_xTimerJs, JS_CHECK_TIME)
- auto-reload : pdTRUE
- 50msec毎に定期的にコールするために指定
ジョイスティックの状態の検出
ジョイスティック状態の取得
System_Js.h
/**
* @enum JsCode_t
* @brief JoyStick識別子
* @note -
*/
typedef enum
{
JS_CODE_CENTER = (0),
JS_CODE_UP ,
JS_CODE_DOWN ,
JS_CODE_RIGHT ,
JS_CODE_LEFT ,
JS_CODE_ILL = (0xFF),
} JsCode_t;
ジョイスティックの識別子の定義
ApiJs.cpp
/**
* @brief JoyStickのタイマーコールバック関数
*/
static void vTimerCallbackJs( TimerHandle_t xTimer)
{
int32_t x = analogRead(JS_ASGN_AXIS_X);
int32_t y = analogRead(JS_ASGN_AXIS_Y);
JsCode_t xJsCode;
if( x < 500 )
{
xJsCode = JS_CODE_LEFT;
}
else if( x > 3600 )
{
xJsCode = JS_CODE_RIGHT;
}
else
{
if( y < 500 )
{
xJsCode = JS_CODE_DOWN;
}
else if( y > 3600 )
{
xJsCode = JS_CODE_UP;
}
else
{
xJsCode = JS_CODE_CENTER;
}
}
// 状態の判定
if( s_xBakJsCrd.xJsCode != xJsCode )
{
vDebugJsMsg(__func__, xJsCode, x, y);
s_xBakJsCrd.xJsCode = xJsCode;
}
x, yには、0-4095の値で取得されます。
今回の接続だと以下のような値が取得されます。
ジョイスティック状態 | x値 | y値 |
---|---|---|
Idle | 2048付近 | 2048付近 |
左[←] | 0付近 | 2048付近 |
右[→] | 4095付近 | 2048付近 |
上[↑] | 2048付近 | 4095付近 |
下[↓] | 2048付近 | 0付近 |
前回の判定と異なったら、vDebugJsMsg()にて、シリアル通信で通知します。
実行結果例
- 左 → 上 → 右 → 下の順に操作する
- ログフォーマット:
- vTimerCallbackJs - [判定した方向] - ([x値], [y値])
vTimerCallbackJs - CENTER - (1915, 1872)
vTimerCallbackJs - LEFT - (0, 1280)
vTimerCallbackJs - CENTER - (1808, 1766)
vTimerCallbackJs - UP - (1919, 4095)
vTimerCallbackJs - CENTER - (2063, 1957)
vTimerCallbackJs - RIGHT - (4095, 1871)
vTimerCallbackJs - CENTER - (2907, 1933)
vTimerCallbackJs - DOWN - (1894, 0)
vTimerCallbackJs - CENTER - (1909, 1869)