taiki3's engineering note

プログラミング、電子工作、アクアリウムなど色々. 当面は自作キーボードのこと. 本業はデータサイエンティスト見習い(?)

Black pill でジョイスティックを使ったHIDデバイス

キーボードのキットを複数作ってきて、物足りないのは親指の使い方。 多くの分離型キーボードで、親指キーが全体的に押しにくい気がする。 もちろん、自分の指の位置に合わせてキー位置ずらしたキーボードを設計してもいいんだけど、 それよりもジョイスティックにしてしまえば親指一本で4キーから上手くいけば8キー+押し込みで9キーくらい担当できるかも。

ぱっと考えると同時押しの制約がありそうなんだけど後述の方法で大分何とかなりそう。

準備したもの

Black pill Amazonで買ったジョイスティックhttps://www.amazon.co.jp/dp/B00M0F21KU PC

ProMicroのおうちがあったので使うつもりだったが、Black pillも一度使ってみたかったのでとりあえず。

やったこと

下記のスケッチになった。

#include <USBComposite.h>
#include <USBHID.h>


int xPin = PA2;   // Select the input pin for the potentiometer
int yPin = PA3;
int sensorValue = 0; // Variable to store the value coming from the sensor
int delayTime = 10; //loop delay
int prec = 4096; //Analog input precision
float THRESHOLD = 0.7; // Key input threshold

const int keyNum = 4;
const byte keyMap[keyNum]  = { 0x61, 0x62, 0x63, 0x64 };
USBHID HID; // create instance of USBHID plugin
HIDKeyboard Keyboard(HID); // create a profile
  
void setup() {
  //setup input
  pinMode(xPin, INPUT_ANALOG);
  pinMode(yPin, INPUT_ANALOG);
  //setup HID
  HID.begin(HID_KEYBOARD);
  Keyboard.begin();
}

void loop() {
  // Read the value from the joystick:
  int x_raw = 2 * analogRead(xPin) - prec;
  int y_raw  = 2 * analogRead(yPin) - prec;
  //convert value:
  float x_val = (float)x_raw / prec;
  float y_val = (float)y_raw / prec;

  if (x_val > THRESHOLD) {
    //right
    Keyboard.press(KEY_DELETE);
  } else if (x_val < -THRESHOLD) {
    //left
    Keyboard.press(KEY_LEFT_CTRL);
  } else if (y_val > THRESHOLD) {
    //up
    Keyboard.press(KEY_BACKSPACE);
  } else if (y_val < -THRESHOLD) {
    //down
    Keyboard.press(KEY_LEFT_ALT);
  } else {
    Keyboard.releaseAll();
  }
  delay(delayTime);
}

既知の不具合?

うちの環境で上記を書き込むと、Black pillのCOMポートが死ぬ。 シリアルでデバッグしながらと思ってたらちょっと困った。 HIDデバイスになるっていうのはそういうことなのかもしれない。

動作しているところ

このぐるっと回してショートカットキー入力、個人的には革命なんだけどどうだろうか。