プレイ動画
— △Natua♪▽ (@natua_tcmm) 2024年10月17日
たまにスライドが逆に入ることがあるんだけど、どうやらゲーム側の問題らしい https://t.co/NVmoWs8wED pic.twitter.com/UO22axQvw6
タイトル通り、初音ミク ProjectDIVA Arcadeの中古コントロールパネルとArduino互換機を使って、PC版DIVA(MEGA39's+)で使えるアーケードスタイルコントローラーに改造したという記事です。
コンパネ購入

ヤフオクで30,000円

スイッチは本来OBSA-LHSXF-LN(光学式無接点スイッチ)が使用されており、ハーネスもそれ対応のものが付いていますが、使用していた店舗さんがOBSA-LHS1F-LN/OBSA-LHSDF-LN(普通のスイッチ)用ハーネスも追加で取り付けていたようで、どちらでも使えるようになっていました。
ただ私はOBSA-LHS7F2-LEDを使用するので、ケーブルぶった切り大会を実施することとなりました。
スライダーはCHUNITHMのものと内部的には同じです。

ハードウェア
使用したマイコン
Seeed XIAO RP2040を使用しました。
PC通信用とスライダー通信用に2つ以上のハードウェアシリアルが搭載されている必要があり、かつHID対応(PCに接続してキーボードやマウスとして認識させられる)のマイコンボードを選ぶ必要があります。
(以前はこれを実現するためにArduinoを2枚使っていましたねw)
ちなみに理想としてはUARTが5V入出力のボードがいいです。スライダーは5Vしか受け付けていません。ですがこちらのボードは3.3Vなので、レベル変換回路が必要です(後述)
Seeed Studio XIAO RP2040 — スイッチサイエンス
回路設計

Fusion360で回路図制作・基板設計しました。昔のEagleです。
最初はTinkercadの回路設計ツールでテストしており、それを回路図として書き出してみたのですが、ありえないくらいぐっちゃぐちゃの図になってしまいめちゃくちゃめんどくさかったです。Tinkercadの回路図書き出しは使わないほうが良いです!!!(改善されてたらごめん)
この回路図は頑張ってキレイにしたものです(それでも少し汚いかも)

電源はマイコンからの出力(3.3V/5V)と12V電源(スライダー電源・LED)の2つを使用していますが、フォトリレーを2つ用いて両方接続されるまでスライダーに信号がいかないようにしています。
Seeed XIAO RP2040の出力は3.3Vなので、レベル変換回路を用いて5Vにしてあげる必要があります。
以前にも書きましたが、スライダーの通信は極性反転が必要です。Arduino側で反転させるオプションはないので、インバーターが必須となります。
通常のUART通信は「待機状態は常時HIGH・立ち下がりエッジを検出して通信を始める」って仕様です。このスライダーは逆で、「待機状態は常時LOW・立ち上がりエッジを検出して通信を始める」となっています。
マイコンからの3.3V信号でLEDの12Vを操るためにNch-MOSFETを使用しています。存在は知っていましたが初めて使いました。
ゲート抵抗やゲートソース間抵抗の値はこちらのサイトを参考に決めました。合ってる自信はないですが動いているのでOK。10Hz以上でスイッチングすることないですし適当でもだいたい大丈夫だと思います()
基盤制作・その他
JLCPCBに発注しました。


あとはケーブルにコネクタを付けたり、スイッチ用のハーネスを買ったりしました。
スライダーのピンの配置についてはこのサイトを見てください。
GND-TX-RXと12V-GNDを挿せばOKです。プログラミングポートは当然使いません。
ソフトウェア
Arduinoと同じ感じで動きます。
ちなみに、制作メモに「処理順を逆にするとうまくいった」とありましたが、どれとどれを逆にしたかすっかり忘れてしまいました。困ったら処理順を変更してみてください(雑)
スライダー制御
こちらのサイトで分析されているプロトコルを参考にいい感じに作ればOKです。
通信速度は115200です。ソフトウェアシリアルだと動作が遅くて上手く動きません。
「接続確認」と「スキャン開始指示」と「LED発光指示」だけ実装すれば動きます。他の通信は何やってるか誰も知りません。
スキャン開始指示を出すと約16.67ms間隔でタッチ状態の情報が来ます。こちらから何も情報を送らない期間が一定時間続くと勝手にリセットされるので、何かしらを適当な間隔で送っておきましょう。
ちなみにArduinoでは極性反転の設定はできません。なので先述の通りインバーターが必須です。
PCへのデータ送信
TinyUSBを使用してPCにゲームコントローラーとして認識させています。(Adafruit TinyUSB Library 3.3.4)
- Tools > USB Stack を Adafruit TinyUSBにしてください。
- 頭に#include <Adafruit_TinyUSB.h>を書いてください。
- setup()にSerial.begin(115200);を書いてください。
1つでも忘れるとArduino IDEがボードを全く認識しなくなります(たぶん)。
その時はここからterminal_rp2040_v1.0.0.uf2をダウンロードして、ボードの「B」ボタンを押しながらPCに接続(ブートローダーモード)→認識されたドライブにダウンロードしたファイルをドラッグ&ドロップすると、データは全部消えますが再使用できるようになります。
MEGA39's+で使用可能にする
MEGA39's+でアーケードコントローラーとして認識させるには、デバイス名やベンダーID・製品IDを偽装する必要があります。
- TinyUSBDevice.setID( 0x0f0d, 0x013c );
- TinyUSBDevice.setManufacturerDescriptor("HORI HATSUNE MIKU 39S CONTROLLER");
- TinyUSBDevice.setProductDescriptor("HORI HATSUNE MIKU 39S CONTROLLER");
これらを書いておけばHORIのSwitch用DIVAコンに偽装できます。なお、PS4用DIVA FTコンに偽装しても大丈夫らしいです。
参考
また、スライダーの状態はジョイスティックのデータに乗せて送る必要があります。詳しくはこちらのサイトを見ていただければと思います。
簡単に言うと、2つのスティックのXY(8bit×2方向×2個=32bit)の1bitずつにセンサーのON/OFFを割り当てています。賢い。
変数名がわかりにくいですが、gp.xとgp.yがLXとLY、gp.zとgp.rzがRXとRYです。
どこかで最上位ビットを反転させる必要があるとか聞いた気がするのですが、特に何もせずそのまま乗せるだけで大丈夫でした。
ちなみに上のサイトにも書かれていますが、スライドが逆方向に入るのはおそらくゲーム側の問題です。
やってないけどやったほうがいいこと
静音化しましょう。打鍵音80〜90dBくらいあります。