昔PS2で使っていた虹コンをbeatmania IIDX INFINITASで使えるようにPro micro仕込んで改造しようのコーナー。備忘録的にざっくりと残しておく。

必要なもの
やっていく
ボード定義の編集
ボード定義を書き換えて、USB接続時にコナミ製専コンとして認識させる。商標権の侵害にあたる可能性があるため、この方法で書き込んだマイコンボードを譲渡・販売する際には十分に注意すること。
%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.4\boards.txtを次の通り書き換える。
leonardo.build.vid=0x2341 leonardo.build.pid=0x8036 leonardo.build.usb_product="Arduino Leonardo"
leonardo.build.vid=0x1CCF leonardo.build.pid=0x8048 leonardo.build.usb_product="PRECON"

書き込み
/*
## board deffinition
%LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.4\boards.txt
---
< leonardo.build.vid=0x2341
< leonardo.build.pid=0x8036
< leonardo.build.usb_product="Arduino Leonardo"
> leonardo.build.vid=0x1CCF
> leonardo.build.pid=0x8048
> leonardo.build.usb_product="PRECON"
---
## requires
- https://github.com/NicoHood/HID
- https://github.com/brianlow/Rotary
*/
#include <Rotary.h>
#define KEY1 1
#define KEY2 2
#define KEY3 3
#define KEY4 4
#define KEY5 5
#define KEY6 6
#define KEY7 7
#define E1 9
#define E2 10
#define E3 11
#define E4 12
#define PIN_KEY1 2
#define PIN_KEY3 3
#define PIN_KEY2 4
#define PIN_KEY4 5
#define PIN_KEY5 6
#define PIN_KEY6 7
#define PIN_KEY7 10
#define PIN_E1 A0
#define PIN_E2 A1
#define PIN_E3 A2
#define PIN_E4 A3
#define PIN_ENC0 8
#define PIN_ENC1 9
#include "HID-Project.h"
int16_t axis = 0;
Rotary r = Rotary(PIN_ENC1,PIN_ENC0);
ISR(PCINT0_vect) {
unsigned char result = r.process();
if (result == DIR_NONE) {
// do nothing
}
else if (result == DIR_CW) {
axis+=500; // 皿の反応をみて増やしたり減らしたりしてみる
}
else if (result == DIR_CCW) {
axis-=500;
}
}
void setup() {
pinMode(PIN_KEY1, INPUT_PULLUP);
pinMode(PIN_KEY2, INPUT_PULLUP);
pinMode(PIN_KEY3, INPUT_PULLUP);
pinMode(PIN_KEY4, INPUT_PULLUP);
pinMode(PIN_KEY5, INPUT_PULLUP);
pinMode(PIN_KEY6, INPUT_PULLUP);
pinMode(PIN_KEY7, INPUT_PULLUP);
pinMode(PIN_E1, INPUT_PULLUP);
pinMode(PIN_E2, INPUT_PULLUP);
pinMode(PIN_E3, INPUT_PULLUP);
pinMode(PIN_E4, INPUT_PULLUP);
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT4) | (1 << PCINT5);
sei();
Gamepad.begin();
}
void loop() {
Gamepad.xAxis(axis);
if (!digitalRead(PIN_KEY1))Gamepad.press(KEY1); else Gamepad.release(KEY1);
if (!digitalRead(PIN_KEY2))Gamepad.press(KEY2); else Gamepad.release(KEY2);
if (!digitalRead(PIN_KEY3))Gamepad.press(KEY3); else Gamepad.release(KEY3);
if (!digitalRead(PIN_KEY4))Gamepad.press(KEY4); else Gamepad.release(KEY4);
if (!digitalRead(PIN_KEY5))Gamepad.press(KEY5); else Gamepad.release(KEY5);
if (!digitalRead(PIN_KEY6))Gamepad.press(KEY6); else Gamepad.release(KEY6);
if (!digitalRead(PIN_KEY7))Gamepad.press(KEY7); else Gamepad.release(KEY7);
if (!digitalRead(PIN_E1))Gamepad.press(E1); else Gamepad.release(E1);
if (!digitalRead(PIN_E2))Gamepad.press(E2); else Gamepad.release(E2);
if (!digitalRead(PIN_E3))Gamepad.press(E3); else Gamepad.release(E3);
if (!digitalRead(PIN_E4))Gamepad.press(E4); else Gamepad.release(E4);
Gamepad.write();
}
結線
#define PIN_KEY1 2などを見ながら鍵盤を結線する。もとからある基板のGNDや皿基板の電源もマイコンボードと接続する。
皿基板の2つあるフォトインタラプタの受光側をそれぞれ8と9に結線。

さいごに
低遅延かつ皿の操作性の良い令和最新版虹コンになった。
おまけ
PS2用の専コンを無改造で接続する用のやつ
#include "HID-Project.h"
#include <Psx.h>
#define dataPin 7
#define cmndPin 6
#define attPin 5
#define clockPin 4
#define KEY1 (uint8_t)1
#define KEY2 (uint8_t)2
#define KEY3 (uint8_t)3
#define KEY4 (uint8_t)4
#define KEY5 (uint8_t)5
#define KEY6 (uint8_t)6
#define KEY7 (uint8_t)7
// 9がE2 10がE3
#define ST 9
#define SEL 10
Psx Psx;
unsigned int data;
int16_t axis =0;
void setup() {
Psx.setupPins(dataPin, cmndPin, attPin, clockPin, 10);
Gamepad.begin();
}
void loop() {
data = Psx.read();
if(data&psxDown){
axis+=50;
Gamepad.xAxis(axis);
}
if(data&psxUp){
axis-=50;
Gamepad.xAxis(axis);
}
if(data&psxSqu)Gamepad.press(KEY1);else Gamepad.release(KEY1);
if(data&psxL1)Gamepad.press(KEY2);else Gamepad.release(KEY2);
if(data&psxX)Gamepad.press(KEY3);else Gamepad.release(KEY3);
if(data&psxR1)Gamepad.press(KEY4);else Gamepad.release(KEY4);
if(data&psxO)Gamepad.press(KEY5);else Gamepad.release(KEY5);
if(data&psxL2)Gamepad.press(KEY6);else Gamepad.release(KEY6);
if(data&psxLeft)Gamepad.press(KEY7);else Gamepad.release(KEY7);
if(data&psxStrt)Gamepad.press(ST);else Gamepad.release(ST);
if(data&psxSlct)Gamepad.press(SEL);else Gamepad.release(SEL);
//delay(10);
Gamepad.write();
}