SpeedGun (SR3600)で遊んでみた話


ボールや車などの速度を図ることのできるSpeedGunを触る機会があり、
面白そうだったのでPCに接続してUnityでデータを取得できるようにしてみた時のメモ。

## SpeedGun選定

いろいろ種類はあったけど、外部出力機能としてRJ45(RS232-C変換付き)を搭載した
[SR3600](https://sokutei-cube.com/products/shosai/2566)というモデルがあったのでこれを使うことにした。

## 接続テスト

シリアル通信で拾えるか試してみる。
RS232-Cの仕様通りに接続したがデータは拾えなかったので、
RJ45のピンアサインを元にArduinoと接続したところ、
文字化けはしているが何かしらのデータは流れてきた。

<img width="500" alt="serialTest.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45348/f9031115-6f61-9f82-9548-98439944597b.png">

ちなみに結線は以下の通り。


<img width="500" alt="connection.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45348/e2655a1a-416b-70de-33cb-ad3c7b1269ef.jpeg">


流れてきたデータを見ると経験上、バイナリデータだと思われるのでアスキーに変換してみる。


## データ変換と解析

Arduinoの`String(bytes, HEX)`を使って16進数に変換してみたところ、
規則性のあるデータが取れた。

<img width="500" alt="hex.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45348/89050ade-228c-39a6-773f-f404d4af9557.png">

何度もボールを投げてデータを収集し、
どのデータが何を指しているのかをデータを解析する。

|	|	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でシリアル通信するスクリプト](https://github.com/Satoshi-Hirazawa/unity-serial-uart
)を書いて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;
	}
```

## デモ

出来上がったプロトタイプが[こちら](https://www.youtube.com/watch?v=SvW8g4_WlhQ&feature=youtu.be
)