ESP32でジョイスティックを使ってみよう

ESP32とジョイスティック
ESP32とジョイスティック

この記事では、ゲームコントローラーなどでおなじみのジョイスティックをArduino(ESP32)で使う方法を解説します。本記事ではESP32を使いましたが、M5Stackや他のArduino、Arduino互換機でも動作しますので、ぜひご参考になさってみてください。

ジョイスティックについて

ジョイスティックの中身
ジョイスティックの中身

Amazonなどでよく売られている格安のジョイスティックはGND、+5V(基準電圧)、VRX、VRY、SWの端子になっています。ジョイスティックには2つの可変抵抗が内蔵されており、X軸方向とY軸方向の動きに応じてそれぞれの可変抵抗が回転します。また、VRXとVRYの出力は基準電圧を可変抵抗で分圧した値になるようです。

ArduinoのADコンバータを使って、VRXとVRYの出力値を読み取ればジョイスティックの操作量を知ることができます。ただし、今回使用したジョイスティックは基準電圧が+5Vと書かれていますが。ESP32を使う場合、GPIOの入力は3.3Vまでなのでジョイスティックにかける基準電圧も3.3Vとします。

また、ジョイスティックにはタクトスイッチが内蔵されています。SWがそのタクトスイッチの出力です。ジョイスティックを垂直方向に押し込むとタクトスイッチがオンとなり、SWはアースと導通した状態になります。タクトスイッチが押されてない状態では、宙に浮いているため無限大の抵抗値を示します。このままですとSW端子には電圧変化がありませんので、抵抗を介して電圧を掛ける必要があります。このことをプルアップと呼びます。プルアップ抵抗には10kΩを使用するのが一般的なようです。これでスイッチが宙に浮いてる時の出力を、基準電圧と同じにすることができます。

またArduinoによっては、プログラミングでプルアップやプルダウンに設定可能な場合があります。ESP32も一部のGPIO端子でソフトウェアプルアップが可能になっています。

ESP32とジョイスティックの配線

さて、実際にESP32を使ってジョイスティックを配線してみましょう。次のように配線を行いました。

ESP32ジョイスティック
GNDGND
3.3V+5V
G22VRX
G33VRY
G34SW

先ほどESP32でもソフトウェアプルアップが使えると説明しましたが、GPIO34以降は内部プルアップ/プルダウンが無いようです。しかしながら、手持ちのESP32ではGPIO32でプルアップを試してもなぜかうまくできませんでした。

プルアップ抵抗
プルアップ抵抗

よってプルアップ抵抗を物理的に入れることにしました。皆さんはご自分の環境に合わせて設定してみてください。

通常、ソフトウェアのプルアップ/プルダウンは gpio_set_pull_mode(32, GPIO_PULLUP_ONLY); で設定します。

プログラム

const gpio_num_t VRX_PIN = GPIO_NUM_32;
const gpio_num_t VRY_PIN = GPIO_NUM_33;
const gpio_num_t SW_PIN = GPIO_NUM_34;

void setup() {
    pinMode(VRX_PIN, INPUT);
    pinMode(VRY_PIN, INPUT);
    pinMode(SW_PIN, INPUT); // 10kΩで3V3にプルアップしておく

    Serial.begin(115200);
}



void loop() {
    int x_val = analogRead(VRX_PIN); // 0 - 4095
    int y_val = analogRead(VRY_PIN);
    int s_val = analogRead(SW_PIN);

    Serial.printf("X: %d, Y: %d, S: %d\n", x_val, y_val, s_val);

    delay(100);
}

思いの外カンタンにジョイスティックの値を取得できてしまいました。ただし、触ってなくても出力値が変動しますので、ジョイスティックを実用する際はしきい値で操作を判断させたほうが良いかもしれません。

ジョイスティックの値をシリアルモニタへ表示している様子
ジョイスティックの値をシリアルモニタへ表示している様子

ESP32の内蔵ADコンバータについて

ESP32には2つのADコンバータが内蔵されています。逐次比較型(SAR)と呼ばれるADコンバータになっています。分解能は9〜12bitで、デフォルトでは12bitに設定されています。よって、analogReadで読み取れれる値は0〜4095となります。

ADC1はGPIO32〜GPIO39までが割り当てられています。ADC2はそれ以外のピンとなります。ただし、Wi-Fiなどの無線を利用するとADC2が利用できなくなるようです。しかも一度でも無線を利用すると、再起動または内部レジスタを書き換える必要があるので注意が必要です。

さらにこれらのADコンバータには減衰器が設定されています。通常0〜1Vの間で測定されるADコンバータですが、デフォルトでは-11dBに減衰(-11dBは約1/3.6倍)させられているため、0〜3.6Vの値が測定できるようになっています。

これらのことはM5Stackシリーズを使用するときにも同じことが言えると思いますので注意しましょう。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
ESP32搭載ボード
ESP32の書籍
Arduinoで人気の周辺パーツ
関連記事