SDVX筐体のコンパネからコントローラーを作る(2)
※この記事は Life is Tech!School秋葉原のメンバー・メンターが執筆する akihabara-school Advent Calendar 2024 17日目の記事になります。
はじめに
こんにちは!SDVX筐体のコンパネからコントローラーを作る記事の続きです!
今回は、前回で製作途中だったコンパネボルテコンのボディを作り、実際に動作できるようにします。
前回まで
✅ コンパネを入手する
✅ 大まかな仕様を決める
✅ 基板を設計する ←いまここ
4. 必要な部品を購入する
5. 筐体と基板を組み立てる
6. Pro Microにスケッチを書き込む
7. 完成!
3-ex.回路修正
部品を購入して組み立て...をしようとしたところで、もっといい回路があったので回路図を修正します。
変更点
- 基板を二枚に分けるメリットがないので一体化
- 浮きピン対策でボタンのピンを内部プルアップしたときに抵抗値が10MΩぐらいになってLEDが点かないので分離
- エンコーダの読み取りに割り込みを使えたら便利なのでピンを変更
他のところの回路はほとんど変更ありません。再度基盤を設計して発注します。今回もJLCPCBに発注しました。
4.必要な部品を購入する
組み立てに必要な部品を説明します。
4-1.基板
基板組み立てに必要なものは以下の通りです。前回で一部説明したので表のみ載せます。
部品名 | 個数 | 用途 | リンク |
---|---|---|---|
基板(自作) | 1枚 | 部品の接続 | JLCPCB |
ProMicro(互換機) | 1枚 | メイン基板 | 遊舎工房 |
B34B-XADSS-N | 1ヶ | ハーネスの接続 | JST |
B02B-XASK-1 | 1ヶ | エンコーダの電源 | JST |
68Ω1/4W抵抗器 | 7本 | LED電流制限 | 秋月電子 |
BZX55C5V1 | 7本 | LED保護 | 秋月電子 |
ピンソケット | 1set | ProMicroの接続 | 秋月電子 |
貼り付けスペーサー | 1set | 基板の取り付け | 秋月電子 |
4-2.つまみユニット
今回使うコンパネにはつまみの部品がついていないので自作します。ロータリエンコーダを取り付けるためのブラケットを自作します。
コンパネのつまみ部分には取り付け用のボルトがあるので、これに合わせて作ります。
ロータリーエンコーダを直付けしても良いのですが、横向きの力がかかったときに壊れそうだったので間に軸受けを入れて直接力がかからないようにします。
ロータリエンコーダの取り付け金具は、千石電商にタカチ製の良さそうなものを見つけたのでこれを使います。穴径が大きいのでワッシャを間に噛ませます。
軸受けとシャフトも千石電商で購入します。エンコーダの軸径は6mmなので軸受けとシャフトもφ6にします。
これらを取り付けるプレートが必要ですが、ぴったりな部品が無いので自作します。
部品のネジ穴の位置を参考に、3Dデータを作成します。今回はFreeCadを使いました。
3Dプリンターを所有していれば印刷できますが、無いのでJLCPCBに発注します。基板と同時に発注できます。
組み立てに必要な部品は以下の通りです。
部品名 | 個数 | 用途 | リンク |
---|---|---|---|
取付プレート(自作) | 2枚 | 部品の取り付け | JLC3DP |
RES20D-50-201-1 | 2ヶ | ロータリエンコーダ | RSコンポーネンツ |
SH-12-2B | 2ヶ | エンコーダ取り付け | 千石電商 |
φ6ワッシャ | 2ヶ | エンコーダ取り付け | 千石電商 |
φ6延長シャフト50mm | 2ヶ | シャフト延長 | 千石電商 |
φ6軸受け金具 | 2ヶ | シャフト支持 | 千石電商 |
SVK30 | 2ヶ | ノブ | BTOS |
M4皿ボルト15mm | 4本 | 金具取付 | モノタロウ |
M4ナット | 16ヶ | 取付 | モノタロウ |
XAP-04V-1 | 2ヶ | エンコーダのハーネス | JST |
4-3.接続ケーブル
ボタンやつまみの接続のためのケーブルは前回から変更がないので部品一覧だけ載せます。
(SXAとSXAMはエンコーダ側コネクタ用も含む)
部品名 | 個数 | 用途 | リンク |
---|---|---|---|
0.3sq線 | 10mぐらい | ケーブル | モノタロウ |
B34B-XADSS-N | 1ヶ | コネクタ | JST |
B02B-XASK-1 | 1ヶ | コネクタ | JST |
XADRP-34V | 2ヶ | コネクタ | JST |
XAP-02 | 1ヶ | コネクタ | JST |
XARR-04V | 2ヶ | コネクタ | JST |
SXA-01T-P0.6 | 100~150ヶぐらい | コネクタ | JST |
SXAM-01T-P0.6 | 20~50ヶぐらい | コネクタ | JST |
4-4.ケース
基板やケーブルをしまうケース(コントローラー筐体)を作ります。今回は安価で使いやすいアルミフレームを用います。
コンパネの取り付けネジの穴の位置は次の通りです。M6ボタンボルトが適合します。
製作中にいろいろ考えていたときの図なので雑ですが参考にどうぞ。
NICオートテックがオーダーカットに対応していたのでこれを使います。ネジ穴に対応するように長さを指定します。うち2本は端部にねじ止めするのでタップ付きを選びます。
フレームを組み立てるためにブラケットが必要です。ケースにするための表面パネルを取り付けるのでネジ穴付きのを選びます。24個中4つはコンパネにつくのでネジ穴不要です。
重量が結構あるので机等の傷つき防止のためにゴム足をつけます。M6ネジ対応にしておくとナットが他と共通になるので便利です。6ヶぐらいがちょうどよさそうです。
コンパネやゴム足をつけたりブラケットを固定するためにはナットが必要です。ナットは今回すべてM6なのでまとめて注文します。このうちブラケットに必要な分はブラケットとセット販売しているので、残りの分を注文します。
必要なネジもブラケットの分はセットなので、残りの分を注文します。パネル取り付け用にトラスボルトを、コンパネ・ゴム足取り付け用に六角穴付きボタンボルトを用います。
パネルは強度が重要でなく、中身が見えなければ十分なので、ダイソーのスチレンボードを使います。
まとめると以下の通りです
部品名 | 個数 | 用途 | リンク |
---|---|---|---|
AFS-3030F-6-520 | 4本 | フレーム | NICダイレクト |
AFS-3030F-6-245 | 4本 | フレーム | NICダイレクト |
AFS-3030F-6-140 | 2本 | フレーム | NICダイレクト |
AFS-3030F-6-140-T | 2本 | タップ付フレーム | NICダイレクト |
ABLD-30-6-N-BNH | 4set | ブラケットセット | NICダイレクト |
ABLD-30-6-N-T-BNH | 20set | タップ付ブラケットセット | NICダイレクト |
NHG-06 | 15set | ナットセット | NICダイレクト |
TSB-06-12 | 20本 | トラスボルト | NICダイレクト |
TM-TK-3617 | 6ヶ | ゴム足 | モノタロウ |
M6x20六角穴付ボタンボルト | 2本 | ボタンボルト | モノタロウ |
カラーボード | 1枚 | パネル | ダイソー |
4-5.その他
必要な工具など
品名 | 用途 |
---|---|
六角レンチセット | ボルト締め |
ドライバーセット | ネジ締め |
はんだごて | 部品のはんだ付け |
はんだ | 部品のはんだ付け |
端子に適合する圧着ペンチ | 端子圧着 |
ワイヤーストリッパ | 被覆剥き |
カッターナイフ | パネル切断 |
デジタルマルチメータ | 測定/導通チェック |
5.筐体と基板を組み立てる
いろいろ発注したのものが届いたら、組み立てていきます。
5-1.基板
基板を組み立てます。部品を配置し、はんだ付けしていきます。コネクタとダイオードは向きに注意
はんだ付けしたらテスターを用いて導通とショートをチェックしてください。
5-2.つまみ
エンコーダに端子を圧着します。線が本来適合する線より細いので千切らないように注意
つまみを組み立てます。プレートに軸受けを取り付けます。
エンコーダをスイッチボックスに取り付けます。付属のナットとワッシャで固定します。次に軸に延長シャフトをねじ止めし、プレートの軸受けにシャフトを通し、ボックスを固定します。
コンパネに取り付けたら完了です。
5-3.接続ケーブル
ビニル線にコネクタを圧着します。線の長さは割と適当で問題ないです。100ヶ所ぐらいあるのでつけ間違いに注意してください。
基板やエンコーダなどに繋いで完了です。
5-4.ケース
NICオートテックの説明を参考に組み立てていきます。
必要なナットをあらかじめ入れておきます。ゴム足やコンパネとつなぐナットを入れ忘れないようにしましょう。
ブラケットの向きと140mmタップ付きのフレームの位置に注意しながら組み立てます。
組み立てたフレームをコンパネに取り付けます。コンパネのMDF部分をM6ボタンボルトでねじ止めします。その後、コンパネの残りの部品を取り付けます。
ダイソーのカラーボードをフレームの内側に合わせて切り、ブラケットのネジ穴の位置にφ6の穴をあけネジ止めします。
取り付け部品を使い、基板をねじ止めします。
最後に、ゴム足をねじ止めして完了です。
6.ProMicroにスケッチを書き込む
ProMicroにスケッチを書き込み、実際に使用できるようにします。
まずは全体から
#include <Joystick.h>
#include <Encoder.h>
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD, 7, 0, true, true, false, false, false, false, false, false, false, false, false);
const int Abtn = 4;
const int Bbtn = 5;
const int Cbtn = 6;
const int Dbtn = 7;
const int Lbtn = 8;
const int Rbtn = 9;
const int Sbtn = 10;
const int Aled = 20;
const int Bled = 19;
const int Cled = 18;
const int Dled = 15;
const int Lled = 14;
const int Rled = 16;
const int Sled = 21;
Encoder LeftEncoder(2, 3);
Encoder RightEncoder(0, 1);
void setup(){
pinMode(Abtn, INPUT_PULLUP);
pinMode(Bbtn, INPUT_PULLUP);
pinMode(Cbtn, INPUT_PULLUP);
pinMode(Dbtn, INPUT_PULLUP);
pinMode(Lbtn, INPUT_PULLUP);
pinMode(Rbtn, INPUT_PULLUP);
pinMode(Sbtn, INPUT_PULLUP);
pinMode(Aled, OUTPUT);
pinMode(Bled, OUTPUT);
pinMode(Cled, OUTPUT);
pinMode(Dled, OUTPUT);
pinMode(Lled, OUTPUT);
pinMode(Rled, OUTPUT);
pinMode(Sled, OUTPUT);
Joystick.begin();
Joystick.setButton(1, 0);
Joystick.setButton(2, 0);
Joystick.setButton(3, 0);
Joystick.setButton(4, 0);
Joystick.setButton(5, 0);
Joystick.setButton(6, 0);
Joystick.setButton(0, 0);
Joystick.setXAxisRange(0,1023);
Joystick.setYAxisRange(0,1023);
}
long LeftPos = 0;
long RightPos = 0;
int deltaLeft = 0;
int deltaRight = 0;
int XAxisValue = 0;
int YAxisValue = 0;
void loop(){
long newLeft, newRight;
newLeft = LeftEncoder.read();
newRight = RightEncoder.read();
if (newLeft != LeftPos || newRight != RightPos) {
deltaLeft = (int)(newLeft - LeftPos);
deltaRight = (int)(newRight - RightPos);
if (deltaLeft != 0) {
XAxisValue += deltaLeft;
}
if(deltaRight != 0) {
YAxisValue += deltaRight;
}
LeftPos = newLeft;
RightPos = newRight;
if (XAxisValue < 0){
XAxisValue += 1024;
}
else if (XAxisValue > 1023) {
XAxisValue -= 1024;
}
if (YAxisValue < 0){
YAxisValue += 1024;
}
else if (YAxisValue > 1023) {
YAxisValue -= 1024;
}
Joystick.setXAxis(XAxisValue);
Joystick.setYAxis(YAxisValue);
}
if (digitalRead(Abtn) == LOW) {
Joystick.pressButton(1);
digitalWrite(Aled, HIGH);
}
else {
Joystick.releaseButton(1);
digitalWrite(Aled, LOW);
}
if (digitalRead(Bbtn) == LOW) {
Joystick.pressButton(2);
digitalWrite(Bled, HIGH);
}
else {
Joystick.releaseButton(2);
digitalWrite(Bled, LOW);
}
if (digitalRead(Cbtn) == LOW) {
Joystick.pressButton(3);
digitalWrite(Cled, HIGH);
}
else {
Joystick.releaseButton(3);
digitalWrite(Cled, LOW);
}
if (digitalRead(Dbtn) == LOW) {
Joystick.pressButton(4);
digitalWrite(Dled, HIGH);
}
else {
Joystick.releaseButton(4);
digitalWrite(Dled, LOW);
}
if (digitalRead(Lbtn) == LOW) {
Joystick.pressButton(5);
digitalWrite(Lled, HIGH);
}
else {
Joystick.releaseButton(5);
digitalWrite(Lled, LOW);
}
if (digitalRead(Rbtn) == LOW) {
Joystick.pressButton(6);
digitalWrite(Rled, HIGH);
}
else {
Joystick.releaseButton(6);
digitalWrite(Rled, LOW);
}
if (digitalRead(Sbtn) == LOW) {
Joystick.pressButton(0);
digitalWrite(Sled, HIGH);
}
else {
Joystick.releaseButton(0);
digitalWrite(Sled, LOW);
}
}
コードは、JoystickライブラリとEncoderライブラリを用いて、ゲームパッドとして動作させています。詳しくはそれぞれのライブラリのページを参考にしてください。
特徴的な部分は以下の通りです。ほかの部分はほとんどライブラリのexampleにあるものと同じです。
const int Abtn = 4;
const int Bbtn = 5;
const int Cbtn = 6;
const int Dbtn = 7;
const int Lbtn = 8;
const int Rbtn = 9;
const int Sbtn = 10;
const int Aled = 20;
const int Bled = 19;
const int Cled = 18;
const int Dled = 15;
const int Lled = 14;
const int Rled = 16;
const int Sled = 21;
Encoder LeftEncoder(2, 3);
Encoder RightEncoder(0, 1);
まず、使用するピンをはじめに設定します、こうすることで、ピン配置を変えても簡単に対応させることができます。
long newLeft, newRight;
newLeft = LeftEncoder.read();
newRight = RightEncoder.read();
if (newLeft != LeftPos || newRight != RightPos) {
deltaLeft = (int)(newLeft - LeftPos);
deltaRight = (int)(newRight - RightPos);
if (deltaLeft != 0) {
XAxisValue += deltaLeft;
}
if(deltaRight != 0) {
YAxisValue += deltaRight;
}
LeftPos = newLeft;
RightPos = newRight;
if (XAxisValue < 0){
XAxisValue += 1024;
}
else if (XAxisValue > 1023) {
XAxisValue -= 1024;
}
if (YAxisValue < 0){
YAxisValue += 1024;
}
else if (YAxisValue > 1023) {
YAxisValue -= 1024;
}
Joystick.setXAxis(XAxisValue);
Joystick.setYAxis(YAxisValue);
}
この部分で、ロータリエンコーダの回転を検出し、0~1023の値の変化としてゲームパッドのX,Y軸に反映させています。
if (digitalRead(Abtn) == LOW) {
Joystick.pressButton(1);
digitalWrite(Aled, HIGH);
}
else {
Joystick.releaseButton(1);
digitalWrite(Aled, LOW);
}
ボタンは、スイッチが接続されているピンの状態に応じて、対応するゲームパッドのボタンとLEDに反映させています。
これをProMicroに書き込み、動作を確認します。
動作を確認出来たら無事完成です!
7.完成
このコントローラーをSDVXコナステ版で使うために、Joy2Keyでキーボード動作に変換します。K-Shoot-MANIAではそのまま使用できます。
基板・3Dモデル・スケッチは下の場所にまとめてあります。
筐体や回路、ファームウェアなどに改善できる箇所がたくさんあると思うので、ぜひいろいろカスタマイズしてみてくだい。閲覧ありがとうございました!
Discussion