この記事は RECRUIT MARKETING PARTNERS Advent Calendar 2017 の投稿記事です。
こんにちは!フロントエンジニアの夛田です。
弊社アドベントカレンダーも折り返し、そろそろ年末も近くなって来ましたね。年末年始に家族や友人とやる遊びといえば、もちろんダーツですよね!
今回は年末年始のダーツライフをより楽しく過ごせるように、みなさんのご家庭にあるダーツボードをハックするTipsをご紹介します。
家庭で使えるダーツボードの種類
家庭で気軽に遊ぶことができるダーツボードは大きく2種類に分類されます。
まずはBluetoothが搭載されているモデルです。こちらに分類される機種はiPadを始めとするタブレットと連動し、家にいながらダーツバーや漫喫にある本物の筐体と変わらないクオリティのゲームを楽しむことができます。
そしてもう1つはダーツボード本体にセグ液晶やスピーカが搭載されているモデルです。ダーツボード本体にゲームシステム全てが集約されており、購入後電池を入れればすぐに遊ぶことができるのが特徴です。
どちらの機種においても既製品のままで十分に楽しめますが、やはり本格的な筐体と比べると遊べるゲームに限りがあります。1)01やクリケットという完全実力ゲーしか搭載されていないことが多く、運要素が含まれるパーティーゲーム等が搭載されていません...
そこでエンジニアリングの出番です!これらのダーツボードをハックして、自作ゲームを動かせるようにしてしまいましょう。
Bluetooth搭載ダーツボードをハックする
今回はDARTSLIVE GROUPが販売しているDARTSLIVE-200Sを使用します。こちらは専用アプリが配布されており、お店で遊ぶものと遜色ないハイクオリティなゲームを楽しむことができます。
さて、タブレット端末にBluetoothで接続して遊ぶことが前提のこのダーツボードですが、実は接続側からはただの無線キーボードとして認識されています。それぞれの得点エリアにユニークな文字が割り当てられており、ダーツが刺さった際にそれに対応する文字が接続先に送信されます。
つまりこのダーツボードのどの数字にダーツが刺さったかという情報は、キーボード入力を監視するだけで把握することが出来てしまうのです!
ダーツボード上のどの部分がどの文字に対応しているかは以下の表の通りです。2)認識側のPCでこのダーツボードをどのようなキーボードとして扱うかによって各入力文字に変化があるようです。表に示したのはmacにてjisキーボードとして認識した場合の例となります。
※Singleに対応する文字が2つ存在するのはセグメントが2つあるためです。外側→内側の順で記載しています。
Single | Double | Triple | |
---|---|---|---|
20 | 'Z', 'U' | '1' | 'Q' |
19 | '=', "'" | 'G' | 's' |
18 | 'H', 'n' | 'C' | 'F' |
17 | '.', '+' | 'R' | '~' |
16 | 'g', 'P' | 'V' | '*' |
15 | 'e', '2' | '7' | '"' |
14 | ')', ';' | 'M' | 'l' |
13 | 'L', 'B' | 'K' | '6' |
12 | 'X', '^' | 'm' | 'I' |
11 | '[', '>' | '/' | '>' |
10 | '3', 'h' | '5' | 'p' |
9 | 'a', '%' | 'c' | '(' |
8 | 'j', 'b' | 'T' | 'J' |
7 | 'O', 'Y' | '0' | '!' |
6 | '@', 'W' | 't' | '<' |
5 | '$', '-' | 'E' | '&' |
4 | '8', 'N' | '?' | 'S' |
3 | 'A', 'o' | 'D' | 'q' |
2 | '9', ',' | 'i' | '#' |
1 | ']', '4' | 'k' | 'f' |
Bull | 'd' | 'r' |
この通り様々な言語においてkeyboardイベントとして扱うことができるため、非常に簡単に自作のゲームを作ることができます。ハードウェア的な手を加えることもないため、高いデバイスを万が一にも壊してしまう心配もなく安心です。
試しに適当なオリジナルカウントアップゲームを動かしている様子を以下の動画からご覧ください。
セグ液晶型のダーツボードをハックする
先ほどのBluetoothモデルのダーツボードでは非常に簡単にオリジナルのゲームを作ることができました。しかし、ダーツボード本体が高価で手が出にくい側面もありますし、何より弄りがいがなくて面白くありません。
そこで次は3000円程度で手に入るセグ液晶型のダーツボードをハックする方法をご紹介します。今回はドンキで適当に入手してきた以下のボードを使用することにします。
こちらのダーツボードはBluetooth搭載型のものとは異なり、ダーツボード本体にゲームの進行を表示するセグ液晶や、各種操作を行うボタン等が搭載されています。気軽に楽しむ分にはこのままでも良さそうですが、やはり液晶にゲーム画面を出力してお店の筐体のようにダイナミックに遊びたいですよね。
こちらの安価なボードをDARTSLIVE-200Sと同様にPCと接続し、自作のゲームが作れるところまでをゴールとして定め、早速手を加えてみましょう!
電子ダーツボードの仕組みを理解する
改造を行う前に、まずはこの手の電子ダーツボードの仕組みを理解しなければなりません。先ほどのBluetooth版のダーツボード含め、これらの製品はいったいどのような仕組みでダーツの刺さった位置を高精度で検出しているのでしょうか?
答えを見つけるためにまずは分解してみましょう。
一番目につく蜘蛛の巣状のシートをめくってみると、複数の層に分かれいることが確認できました。[シート---黒色の絶縁体---シート---ダーツボードのセグメント]という構図になっています。
シート周りをもう少し詳しく見てみると、ダーツボードの各セグメントに突起が付いており、その位置に対応する形でシート上に丸の印刷が複数あるのが分かります。このシートの印刷部分は導電性ペースト(銀とカーボン)であり、導電性部分が触れ合うことでスイッチの役割を果たすようになっています。
ダーツボードにダーツが刺さると、突起部分が少し押し込まれ、1枚目のシートの導電性ペーストと2枚目の導電性ペーストが接触し、2枚のシートを通して回路が完成します。
真ん中の黒色の絶縁シートは突起が押し込まれていない際に2枚のシートが不用意に接触しないようにするためのクッションになっているわけですね。このような仕組みはメンブレンスイッチと呼ばれています。身近なところですと、安価なキーボード等にこの仕組みが使われています。気になった方は是非調べてみてください。3)パネルやリモコンなどの入力端末に使われていることが多いです。
ここまでの分解で、ダーツボードにおけるダーツの接触位置判定が実は只のスイッチ群であるということが分かりました。つまり、このスイッチ群の入力を取得することができれば、どこにダーツが刺さったかということをソフトウェア的に把握することができそうです。
導電シートを取り出す
それでは早速スイッチ部分を取り出してみましょう。中にある基板を見てみると、2枚の導電性のシートの入力はピンヘッダに集約されていることが分かります。
それではこのピンヘッダを取り出してやりましょう。
これでダーツボードにぴったりはまるシートの形をしたスイッチ部品が手に入りました!
残りの基板や回路は今回不要なので外してしまいましょう。更にこのピンヘッダのそれぞれの入力を扱いやすくするために、別の基板にワイヤ線とともに半田付けしてモジュール化してしまいましょう!
シートの組み合わせと検出位置把握の仕組み
さて、ダーツボードには通常1から20までの数字と、それぞれの数字にシングル/ダブル/トリプルの3種類のセグメントが存在します。また中央のBullは外側のoutBullと内側のinBullの2種類のセグメントによって構成されています。それぞれを合計すると、20 * 3 + 2
で62箇所のユニークな点があり、これを全て精査することによってはじめてダーツボードのセンシングを制覇したと言えます。しかしながら、62箇所それぞれを独立したスイッチで監視するのは効率的とは言えません。ダーツはルール上、同じタイミングに複数本投げられることがないため、もう少しセンシングを効率化できそうです。
今回扱ったダーツボードの場合は1枚目のシートからは10本のピン、2枚目のシートからは7本のピンが出ています。実はこの2枚のシート、それぞれ役割が違います。10本のピンを持つシートは「数字を検出」するために使われ、7本のピンを持つシートは「場所(シングル / ダブル / トリプル / ブル)を検出」するために使われています。
つまり、ダーツが刺さることに起因して2枚のシートが接触することにより、「数字」と「場所」の組み合わせが導き出されるわけです。蜘蛛の巣状の回路を目で追い、それぞれのピンがどの役割を担っているかをまとめたものが以下の表になります。
ピン番号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
数字 | 9 | 12 | 5 | 20 | 10 | 6 | 13 | 4 | 18 | 1 |
14 | 11 | 8 | 16 | 15 | 2 | 7 | 3 | 19 | 7 | |
inBull | outBull |
ピン番号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
場所 | Triple | Double | Single | Bull | Single | Double | Triple |
これを見ると、10ピン/7ピンの組み合わせにも合点がいきますね。数字を検出するシートは2つの数字を1組にすることによって20までの数字を10ピンに集約して担当し、場所を検出するシートは(トリプル/ダブル/シングル)*2とBullの7ピンを担当しています。
トリプル/ダブル/シングルの検出を行うものがそれぞれ2つずつ用意されている理由は、表1の数字の上部分と下部分をそれぞれ分けて担当するためです。(表3の1-3ピンは表1の数字上部分, 表3の5-7ピンは表2数字下部分をそれぞれ担当します)
例えば、表2の1ピンと表3の1ピンの先にある導電性部分が接触した場合は「9のトリプル」を示し、表2の1ピンと表3の5ピンの先にある導電性部分が接触した場合は「14のトリプル」を示します。
マイコンで制御する
ここまででようやく仕組みが解明できました。あとはそれぞれのピンの接触/非接触を検出する回路を組んで、ソフトウェア的に処理してやるだけです。
回路は非常にシンプルで、一般的なスイッチのON/OFFデジタル入力を調べるものが複数並んでいるだけです。10ピン側の各ピンに順番に電流を流してやり、7ピン側の各ピンに抵抗を挟んでマイコンにつなぎ、電流の流れを監視します。
10ピン側のどのピンに電流が流れたタイミングに7ピン側のどのピンまで電流が行き届いたかをそれぞれ確認することで、全ての組み合わせを網羅することができますね。今回は各ピンのへのI/O操作にArduinoを使いました。
回路とプログラムは以下の通りです。
// 2枚のシート分の入出力領域を確保します int NUM[10]; int SDT[7]; // 数字検出位置まとめの配列を作ります String positions[10][2] = {{ "09" , "14" }, { "12" , "11" }, { "05" , "08" }, { "20" , "16" }, { "10" , "15" }, { "06" , "02" }, { "13" , "17" }, { "04" , "03" }, { "18" , "19" }, { "01" , "07" } }; boolean found; int findNum, findPos; void setup(){ /* * Arduinoのピン番号と1枚目のシート(数字検出)のピン番号を対応させ、 * 出力モードに設定した後にLOW信号を流しておきます */ for ( int i = 0; i < 10; i++){ NUM[i] = i + 2; pinMode(NUM[i], OUTPUT); digitalWrite(NUM[i], LOW); } /* * Arduinoのピン番号と2枚目のシート(場所検出)のピン番号を対応させ、 * 入力モードに設定しておきます */ for ( int i = 0; i < 7; i++){ SDT[i] = i + 12; pinMode(SDT[i], INPUT); } // 結果をPCに出力するためにシリアルポート9600番を解放しておきます Serial.begin(9600); } void loop(){ for ( int i = 0; i < 10; i++){ // 全ての数字ピンに対して順番にHIGH信号を流してやります digitalWrite(NUM[i], HIGH); for ( int j = 0; j < 7; j++){ /* * この時、全ての場所ピンの入力値を精査し、 * HIGHが検出された場所があればそのピン番号を覚えておきます */ if (digitalRead(SDT[j])){ findNum = i; findPos = j; found = true ; } } digitalWrite(NUM[i], LOW); } // 検出されたものがあれば、数字と場所を確定させるための条件判定を行います if (found){ showHitPosition(findNum, findPos); found = false ; } } void showHitPosition( int num, int pos){ // 場所を検出するピンのHIGHになった点と数字を組み合わせてSerial通信で結果を出力! // e.g. 数字シートピン1がHIGHの時に場所シートピン1がHIGH → 出力値: "09t" (9のTriple) switch (pos){ case 0: Serial.print(positions[num][0]); Serial.println( "t" ); break ; case 1: Serial.print(positions[num][0]); Serial.println( "d" ); break ; case 2: Serial.print(positions[num][0]); Serial.println( "s" ); break ; case 3: switch (num){ case 0: Serial.println( "ib" ); break ; case 1: Serial.println( "ob" ); break ; default : break ; } break ; case 4: Serial.print(positions[num][1]); Serial.println( "s" ); break ; case 5: Serial.print(positions[num][1]); Serial.println( "d" ); break ; case 6: Serial.print(positions[num][1]); Serial.println( "t" ); break ; default : break ; } } |
これにて完成です!
これでBluetooth搭載型のダーツボードと同じようにソフトウェアで値が取れるようになりました。
あとは好きな言語で自作のダーツアプリを書いてやるだけです。ひとまずBluetooth版のデモ動画で動いていたカウントアップアプリを今回改造したダーツボードで動かしてみました。4)デモ動画のアプリはArduino --[シリアル通信]-->node な構成でjsアプリが動いています
まとめ
いかがでしたか?3,000円ほどのダーツボードでも工夫次第でお店のものと同様な遊びが実現できることが分かりましたね。
この記事をご覧いただいた皆様はぜひ面白いオリジナルゲームを作ってみてください!パーティーなどで活用すると盛り上がること間違いなしです!
おまけ
筆者はダーツ好きが高じて学生時代に本物のDARTS LIVEを購入してしまいました5)ヤフオクで10万円くらいでしたこちらの中身も今回紹介したものと同じような構造6)導電シートの構造が少し違ってピン対応が変わったくらいでしたので、もちろん改造して楽しみました;)
本物の筐体を使ったダーツゲームハッカソンなども身内で開催して盛り上がりました。面白いゲームを作った方 / アイデアが思いついた方は是非連絡ください!
脚注
1. | ↑ | 01やクリケットという完全実力ゲーしか搭載されていないことが多く、運要素が含まれるパーティーゲーム等が搭載されていません... |
2. | ↑ | 認識側のPCでこのダーツボードをどのようなキーボードとして扱うかによって各入力文字に変化があるようです。表に示したのはmacにてjisキーボードとして認識した場合の例となります。 |
3. | ↑ | パネルやリモコンなどの入力端末に使われていることが多いです。 |
4. | ↑ | デモ動画のアプリはArduino --[シリアル通信]-->node な構成でjsアプリが動いています |
5. | ↑ | ヤフオクで10万円くらいでした |
6. | ↑ | 導電シートの構造が少し違ってピン対応が変わったくらい |