ボールや車などの速度を図ることのできるSpeedGunを触る機会があり、
面白そうだったのでPCに接続してUnityでデータを取得できるようにしてみた時のメモ。
SpeedGun選定
いろいろ種類はあったけど、外部出力機能としてRJ45(RS232-C変換付き)を搭載した
SR3600というモデルがあったのでこれを使うことにした。
接続テスト
シリアル通信で拾えるか試してみる。
RS232-Cの仕様通りに接続したがデータは拾えなかったので、
RJ45のピンアサインを元にArduinoと接続したところ、
文字化けはしているが何かしらのデータは流れてきた。
ちなみに結線は以下の通り。
流れてきたデータを見ると経験上、バイナリデータだと思われるのでアスキーに変換してみる。
データ変換と解析
ArduinoのString(bytes, HEX)
を使って16進数に変換してみたところ、
規則性のあるデータが取れた。
何度もボールを投げてデータを収集し、
どのデータが何を指しているのかをデータを解析する。
description | byte | |
---|---|---|
1 | startByte | 0x00 |
2 | Fixed | 0x20 |
3 | Fixed | 0x03 |
4 | Fixed | 0x06 |
5 | 100の位 | [numbers] |
6 | 10の位 | [numbers] |
7 | 1の位 | [numbers] |
8 | Fixed | 0x03 |
9 | マイル or メートル | 0x5A or 0x59 |
10 | Fixed | 0x05 |
11 | Fixed | 0x0B |
12 | Fixed | 0x03 |
13 | checksum? | 0x06 |
14 | Fixed | 0x3D |
15 | endByte | 0x79 |
Unityとの連携
ArduinoでUnityにデータを送るスクリプトを書く。
SpeedGun.ino
#define START_BYTE 0
#define END_BYTE 121
int bytes;
String str_data;
String str_array;
bool isStart = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(1200);
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available()) {
bytes = Serial.read();
if (bytes == START_BYTE) {
isStart = true;
str_array = "";
str_data = "";
}
else if (bytes == END_BYTE) {
str_array = str_array + String(END_BYTE, HEX);
Serial.println(str_array);
isStart = false;
}
if (isStart == true) {
str_data = String(bytes, HEX);
if (str_data.length() == 1) {
str_data = "0" + str_data;
}
str_array = str_array + str_data + ",";
}
}
}
//========================
// [miles or km]
// km -> 5A
// miles -> 59
//------------------------
// [numbers]
// 0 -> 0x06
// 1 -> 0x67
// 2 -> 0x33
// 3 -> 0x66
// 4 -> 0x19
// 5 -> 0x65
// 6 -> 0x32
// 7 -> 0x64
// 8 -> 0x0C
// 9 -> 0x63
//========================
Unityでシリアル通信するスクリプトを書いてArduinoから送られてきたHexを数字に変換して表示する。
toNumber.cs
void ReceivedLine(string data){
Debug.Log (data);
string[] arr = data.Split(',');
int score = int.Parse(toNumber(arr[3]) + toNumber(arr[4]) + toNumber(arr[5]));
string scoreStr = score.ToString();
unit.text = toUnit(arr[8]).ToString();
}
string toNumber(string s){
string num = "0";
switch(s){
case "63" : num = "9"; break;
case "0c" : num = "8"; break;
case "64" : num = "7"; break;
case "32" : num = "6"; break;
case "65" : num = "5"; break;
case "19" : num = "4"; break;
case "66" : num = "3"; break;
case "33" : num = "2"; break;
case "67" : num = "1"; break;
case "06" : num = "0"; break;
}
return num;
}
デモ
出来上がったプロトタイプがこちら