見出し画像

【SOUND VOLTEX用】ハンドメイドコントローラーについて

beatmaniaIIDX用のハンドメイドコントローラーに引き続き、SOUND VOLTEX用のハンドメイドコントローラーについてもまとめていく


1,各部品の種類、交換方法

鍵盤部分

SDVX用のボタンもAliExpressで購入した安価なものとなっている。FXボタンはIIDXコンに使用した黒鍵と同じもの
筆者が購入したのは下記のアイテム

これに純正のオムロンスイッチと三和バネを使用する。しかしデフォルトの100gスイッチ/20gバネではバネがボタンの自重に負け、高速な縦連が押しにくいとの指摘をいただいた。高難易度をやるにはバネはもう少し重くても良いかもしれない

三和ボタンとの比較。左が三和ボタン、右がAliExpressボタン
高さは違うがストロークはほぼ同じ
バネの互換性もある

ボタンの分解方法はIIDXコンの記事でまとめてあるので割愛する。スイッチやバネを交換するときは同じ手順で行う

つまみ部分

IIDXコンのターンテーブルと同じく、3Dプリンターで製作している。過去に下記の記事で作ったものをベースに、耐久性の向上や面取りで使用感を高めている

上記記事、そしてIIDXコンと同じくこちらのロータリーエンコーダーを使う。これがハマるようにつまみも設計されている

以前までは接着剤で固定する方式だった。そちらのSTLファイルは以下
STLファイルはこちら(旧バージョン)

今でははめ込み式にして分解、メンテナンスできるようにしてある。そちらのSTLファイルは以下
STLファイルはこちら(新バージョン)

今までつまみ部分が一度組み立てると不可逆だったため、ある程度は分解と調整ができるようにした
天板にはめ込む部分を半分に割り、つまみはぴったりはめ込むサイズにして取り外し可能に

組み立ててはめこむ
ロータリーエンコーダーはそのままでは重いので、足を浮かせて軽くする
はんだ等で足に配線する
つまみ部分はエンコーダーに力強く押し込むことでガッチリはまる
その際に足が浮いてしまうことがあるため、後ろからドライバーなどで押さえつけながらはめ込む
外すときはマイナスドライバーなどで外すか、強く引っ張る
裏面もフタとナットで固定

製品版ではつまみ側にメスのジャンパーワイヤー、ブレッドボードからオスのジャンパーワイヤーが伸びている。予備のつまみと交換する際は同じ色のワイヤーに差し替える
ちなみに中央の線がGND、左右の線はそれぞれ入力端子となる
10kΩの抵抗を用いてArduinoに繋ぐ。配線方法は下記リンク参照

基板

基板についてはIIDXコンの記事と同じ内容。以下引用

あまり考えられないが、何らかの原因で基板が故障するかもしれない。基板の交換方法についても説明する
製品の基板にはArduino互換機、Pro Microを使用している。当noteでの専コン制作では非常にお世話になっているものだ
Pro Microの購入方法は多々あるが、どうも値段が安定しない。種類もいくつかあるため、戸惑った場合は筆者が購入している遊舎工房で購入するといいだろう

しかしこのPro Micro、最大の問題点として端子部分が物理的に壊れやすいという欠点がある。使用する前に接着剤等で補強することを推奨。製品のPro Microは補強済み

Pro Microに繋ぐ際の各ピンの対応は製品だと

  • BT-A→2ピン

  • BT-B→3ピン

  • BT-C→4ピン

  • BT-D→5ピン

  • FX-L→6ピン

  • FX-R→7ピン

  • START→8ピン

  • 左つまみ→14、15ピン

  • 右つまみ→10、16ピン

となっている

2,配線とファームウェア

配線

製品では黒がGND、それ以外は無選別のジャンパーワイヤーを使用。ファストン端子を使用し、スイッチの交換などが容易になっている

ファームウェア

この項もIIDXコン記事からの引用多め

ファームウェアとはArduino基板に書き込む組み込みプログラムのこと。これをインストールすることで、基板がゲームパッドとして認識される
製品もファームウェア書き換え用のソフトをパソコンにインストールすれば書き換えられる。知識ある人なら好みに合わせて調整もできる。以下では手順を説明する

まず公式サイトからArduino IDEをダウンロード、インストールする

インストールしたら、ファームウェアに使うHIDライブラリなるものもダウンロードする。下記リンクから最新版をどうぞ

ロータリーエンコーダー用のライブラリもダウンロードする

IDEを起動したらメニューの「スケッチ→ライブラリをインクルード→.ZIP形式のライブラリをインストール」で上記HIDライブラリとEncoderライブラリを選択してインストールする
あとはUSB接続で基板をPCに繋ぎ、「ツール→ボード→Arduino AVR Boards→Arduino Leonard」を選択、同メニューのシリアルポート欄で基板が接続されていれば、下記のプログラムをインストールする

#include <Arduino.h>
#include "HID-Project.h"
#include <limits.h>
#include <Encoder.h>

#define log_timer 100     //つまみの感度
#define tsumami_timer 20  //つまみの入力を残す時間
Encoder EncL(10, 16);
Encoder EncR(14, 15);
//ピン番号 0は欠番 10~16はロータリーエンコーダー用
int button[8] = { 0, 2, 3, 4, 5, 6, 7, 8 };
bool button_prev[8];

int input_logL[log_timer];
int prev_L;
int max_valueL;
int min_valueL;
int input_logR[log_timer];
int prev_R;
int max_valueR;
int min_valueR;
long L_timer;
long R_timer;
int i;

void setup() {
  for (i = 1; i < 8; i++) pinMode(button[i], INPUT_PULLUP);
  Gamepad.xAxis(0);
  Gamepad.yAxis(0);
  Gamepad.begin();
}

void loop() {
  //delay(1); //1ミリ秒ごとに処理
  Serial.println(digitalRead(10));
  Serial.println(digitalRead(16));
  max_valueL = INT_MIN;
  min_valueL = INT_MAX;
  //過去50ミリ秒分のロータリーエンコーダーの値を記録し最小値と最大値を調べる
  for (i = 0; i < log_timer; i++) {
    if (i == log_timer - 1) input_logL[i] = EncL.read();
    else input_logL[i] = input_logL[i + 1];
    max_valueL = max(max_valueL, input_logL[i]);
    min_valueL = min(min_valueL, input_logL[i]);
  }

  max_valueR = INT_MIN;
  min_valueR = INT_MAX;
  //過去50ミリ秒分のロータリーエンコーダーの値を記録し最小値と最大値を調べる
  for (i = 0; i < log_timer; i++) {
    if (i == log_timer - 1) input_logR[i] = EncR.read();
    else input_logR[i] = input_logR[i + 1];
    max_valueR = max(max_valueR, input_logR[i]);
    min_valueR = min(min_valueR, input_logR[i]);
  }

  // 鍵盤の処理 つまみの入力タイミングと合わせるために1ms遅延させる
  for (i = 1; i < 8; i++) {
    if (button_prev[i] == true) {
      Gamepad.press(i);
    } else {
      Gamepad.release(i);
    }
  }
  for (i = 1; i < 8; i++) {
    if (digitalRead(button[i]) == LOW) {
      button_prev[i] = true;
    } else {
      button_prev[i] = false;
    }
  }

  //台揺れなどのチャタリング防止のために2以上動いてたらつまみ判定
  //if (button_prev[7] == true) {
  //  Gamepad.xAxis(0);
  //  Gamepad.yAxis(0);
  //}
  if (max_valueL - min_valueL >= 2) {
    if (input_logL[log_timer - 1] > input_logL[log_timer - 2]) {
      Gamepad.xAxis(0x7FFF);
      L_timer = tsumami_timer;
    }
    if (input_logL[log_timer - 1] < input_logL[log_timer - 2]) {
      Gamepad.xAxis(-0x7FFF);
      L_timer = tsumami_timer;
    }
  } else if (L_timer < 0) {
    Gamepad.xAxis(0);
  }

  if (max_valueR - min_valueR >= 2) {
    if (input_logR[log_timer - 1] > input_logR[log_timer - 2]) {
      Gamepad.yAxis(0x7FFF);
      R_timer = tsumami_timer;
    }
    if (input_logR[log_timer - 1] < input_logR[log_timer - 2]) {
      Gamepad.yAxis(-0x7FFF);
      R_timer = tsumami_timer;
    }
  } else if (R_timer < 0) {
    Gamepad.yAxis(0);
  }

  L_timer--;
  R_timer--;

  Gamepad.write();
}

これをコピペして左上の「マイコンボードに書き込む」を押せば基板にインストールされ、ゲームパッドとして使用可能になる

3,外箱

製品の仕様は幅約45cm、奥行き約30cm現在は25cm、高さ約10cmである。自作する際は好みに合わせて大きさを変えるとよい
天板にはカッターナイフでも加工しやすいMDF材を使用。厚さはIIDXコンと同じく2.5ミリだが、IIDXよりボタンが大きく中心に負荷が集中するため、もう少し厚くてもよさそうだ
以下は製品の天板の寸法。FXボタンと下辺からの距離は3cm。好みに合わせて調整しよう

拡大推奨

枠組みについてはホームセンターに売っている適当なものを使う。DIYの経験があれば説明するまでもないだろう。筆者は接着剤ではなくネジで固定する派
底版を使うかはお好みで。製品には見た目重視で底版を付けたが、実のところは底版無い方がメンテしやすいので底版はいらない派

終わりに

つまみに関しては力が上に働く都合上、どうしても完全に固定せざるをえなかったが、何か良い感じの対処法があれば取り入れていきたい。積層式の3Dプリンターではイモネジの機構は細かすぎて作れなさそうというのが所見ではある
質問等はコメント欄は作者のSNSなどでどうぞ。最後にTwitterアカウントと商品ページの方を