先日、社内のミーティングルームでミーティング開始の準備をしていたところ、窓の外から何やら音が聞こえてきたので、28階の窓の外で一体何が…と目を遣ると…
![]()
なんと隼でした!
直ぐに飛び去ってしまうかなと思いましたが、至近距離でじっくり撮影させてくれました。
できるだけ音を立てないように注意しながらテンションが上がっていたシラッチです。
さて、大阪開発では今、ダーツが熱いです。
家庭用のダーツボード(ダーツの的)を持ってきてくださった方が居て、昼休憩等にみんなでプレーしていたりするのですが、私も去年末あたりからハマってマイダーツを購入、早く出社した時は朝練をしています。笑
アミューズメント施設やダーツバーに設置されているダーツ台でもプレーしているのですが、点数の自動計算やカッコイイ演出を見ていると、だんだんと社内にもこの環境があったら良いなぁ…むしろゲームを開発している会社だし、自分たちで開発できる環境が欲しいなぁ…(しかもできるだけ安価に…)
…つくるか。
というわけで、開発に着手し始めました。
全体の構成は以下の図のようにイメージしました。
![]()
家庭用ダーツボードはBluetoothでタブレットやスマートフォンと連携するものと、本体にセグ液晶やスピーカーが搭載されているタイプのものがあるようで、安価な後者を購入しました。
ダーツボードとBluetoothキーボードを接続して、タブレットやスマートフォン上で連携できるアプリを開発すれば良いのでは…という構想です。
まずはBluetoothキーボードの入力を受け付けるアプリを用意しました。
![]()
いいかんじです。^^
(アプリ名は社名から一部拝借して DartsDrive(仮)にしています。笑)
市販のダーツボードからセグ液晶とスピーカーを取り外して…
![]()
さあ次はBluetoothキーボードと接続を…と思っていたのですが…
![]()
キーボードの配線が細かい…ッ!!><
写真ではわかりにくいですが、目測でもピンとピンの間は1mm以下…ハンダ職人の技術があれば可能かもしれませんがコレは泣く泣く断念しました。
絶望しかけたところ同僚から「Arduinoで作った方がいいのでは?」と教えてもらい&Arduinoをお借りして、Arduinoって何でしょうか…??というレベルから手探りでシステムを作り始めました(汗)
Arduino – Home https://www.arduino.cc/
Arduino – ウィキペディア https://ja.wikipedia.org/wiki/Arduino
ダーツボードの背面にある2枚のシートから伸びる配線(それぞれ10本と7本)の接触を検出したいので、まずは1vs1の配線の接触が検出できるように以下のように回路を組みました。![]()
プログラムは次の通りです。
// darts.ino
void setup() {
// デジタルピン2を出力モードに、アナログピン0を入力モードに設定
pinMode(2, OUTPUT);
pinMode(A0, INPUT);
// PC上で結果を確認するためにシリアルポート9600番を解放
Serial.begin(9600);
}
void loop() {
// デジタルピン2にHIGH信号を流す
digitalWrite(2, HIGH);
// アナログピン0に信号が来ていれば接触検出
if( digitalRead(A0) ) {
Serial.println("Hello Arduino!");
}
// 接触検出が終わったのでLOWに設定
digitalWrite(2, LOW);
}
確認したところ検出が行えたので、こちらの回路とプログラムを、さらに2vs2の配線の接触が検出できるように拡張します。
回路:
![]()
プログラム:
// darts.ino
// ダーツボードの2枚のシートとArduinoのピン番号の対応を表す配列
static const int S1PIN[] = {2, 3};
static const int S2PIN[] = {A0, A1};
static const int S1PIN_LEN = sizeof(S1PIN) / sizeof(S1PIN[0]);
static const int S2PIN_LEN = sizeof(S2PIN) / sizeof(S2PIN[0]);
void setup() {
// ピンの入出力モードを設定
for(int i = 0; i < S1PIN_LEN; i++) {
pinMode(S1PIN[i], OUTPUT);
}
for(int i = 0; i < S2PIN_LEN; i++) {
pinMode(S2PIN[i], INPUT);
}
// PC上で結果を確認するためにシリアルポート9600番を解放
Serial.begin(9600);
}
void loop() {
for(int i = 0; i < S1PIN_LEN; i++) {
digitalWrite(S1PIN[i], HIGH);
for(int j = 0; j < S2PIN_LEN; j++) {
// 2枚のシートの接触を検出したらそれぞれ何番目のピンが接触しているかを出力
if( digitalRead(S2PIN[j]) ) {
Serial.print("Sheet1 pin =");
Serial.print(i);
Serial.print(", Sheet2 pin =");
Serial.println(j);
break;
}
}
digitalWrite(S1PIN[i], LOW);
}
}
プログラムを実行して確認してみると、どうやらうまく検出できているようです♪
![]()
まだまだ先は長そうですが、少し光が見えてきました。
スキマ時間に少しずつ進めているので、進捗が遅いですが、次回ブログターンが回ってくるまでに完成した状態をお披露目できるように…できる…かな…がんばります(笑)
おまけ
ダーツボードのイラストを簡単に作れたら良いなぁと思ってPythonでスクリプトを書いてみました。
※実行にはPython3.x, numpy, matplotlib が必要です。
# -*- coding: utf-8 -*-
# ダーツボードイメージを出力するスクリプト
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as patches
ax = plt.axes()
# 余白は不要なのでナシに設定
mpl.rcParams['axes.xmargin'] = 0
mpl.rcParams['axes.ymargin'] = 0
# 出力画像サイズを 2000x2000 に設定
plt.figure(figsize=(20, 20))
# 目盛り類を非表示に設定
plt.tick_params(labelbottom=False, labelleft=False, labelright=False, labeltop=False)
# 色定義
C_SEG1 = '#E18E96'
C_SEG2 = '#A9ABDC'
C_SEG3 = '#E0DBDF'
C_BULL = '#A9F5A9'
C_INBULL = '#A9F5A9'
C_EDGE = '#939393'
# 20等分の円グラフを作成するためのデータ
x = np.ones((20))
# Double領域
colors = [C_SEG1, C_SEG2]
plt.pie(x, startangle=9, radius=100, colors=colors, wedgeprops={'linewidth': 3, 'edgecolor':C_EDGE})
# Single(外側)領域
colors = [C_SEG3]
plt.pie(x, startangle=9, radius=90, colors=colors, wedgeprops={'linewidth': 3, 'edgecolor':C_EDGE})
# Triple領域
colors = [C_SEG1, C_SEG2]
plt.pie(x, startangle=9, radius=60, colors=colors, wedgeprops={'linewidth': 3, 'edgecolor':C_EDGE})
# Single(内側)領域
colors = [C_SEG3]
plt.pie(x, startangle=9, radius=50, colors=colors, wedgeprops={'linewidth': 3, 'edgecolor':C_EDGE})
# Bull
centre_circle = plt.Circle((0,0), 13, color=C_BULL, fc=C_BULL, ec=C_EDGE, linewidth=3)
fig = plt.gcf()
fig.gca().add_artist(centre_circle)
# In Bull
centre_circle = plt.Circle((0,0), 6, color=C_INBULL, fc=C_INBULL, ec=C_EDGE, linewidth=3)
fig = plt.gcf()
fig.gca().add_artist(centre_circle)
# 真円になるように設定
plt.axis('image')
ax.set_aspect('equal')
plt.savefig('dartsboard.png')
実行すると以下のような画像が出力されます。
![]()
ではまた~