車のデータで遊ぶ - ① 車と接続する

::: note warn
**[2024年4月 追記] 真似しないほうが良さそう**
この記事の内容は「自分の マツダ CX-30 で遊んでみてこうだった」という内容になっているが、CX-30 の新しめのモデルやこのあとで発売された CX-60 では **「OBD2 や USB Type-C ポートからデータを抜こうとしたら車が文鎮化した」** という報告が複数あり、マツダに限らず新しめの車で ECU にアクセスしようとする行為はかなりリスクが高くなっているといえるので、この記事の内容は迂闊に真似をしないほうがよい。
:::

「今年買ってよかったもの」といえば、間違いなく「車」になる。

- [車を買った - ほとラボ](https://blog.hotolab.net/entry/cx-30)

これまで車は移動手段としか思っていなかったけど、良い車を買ったことによって「くるま楽しい！！」と意識が変わったのがこの１年だったといえる。

## 車のデータを収集して遊びたい
データに携わる者としては「好きなもののデータを集めて遊びたい」と考えるのは自然ではなかろうか。
今年は車が楽しかったので、車の様々なデータを集めて遊びたいと思った。

というわけで、走行ログをとっていい感じに可視化すべくこんなものを作った。(未完成)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/a7f4e2de-9123-b1e9-f180-fc7dd6c059a1.png)

ぶっちゃけ走行ログを可視化したいだけなら Android アプリで ELM327 デバイスに接続してポチポチ設定するだけでできるのだけど、そこはなんかいい感じにデータを溜めてやっていきたいと思ったのでわざわざ面倒くさい構成にしている。


## 車からデータを取得する
やったこと全部書こうと思ったらめちゃくちゃ長くなりそうだたので、今回は車からデータを取得するところだけ書く。
のこりは続きで。

### 用語
色々と用語が出てきたので、ここでまとめておく。

- OBD2 / OBD-II (On-Board Diagnostics-II)
    - 車に搭載されているコネクタ規格のこと
    - 車の ECU と繋がっており、車のデータを取得して車両診断を行う目的で用いられる
    - 車を販売する際は OBD2 コネクタを搭載することが世界各国で義務付けられており、現代ではほとんどすべての車に OBD2 コネクタが搭載されていると言える
    - コネクタ形状が OBD2 で統一されているとはいえ通信プロトコルは様々あり、自動車メーカーごとに異なるらしい
- ELM327
    - ELM Electronics 社が作った OBD2 デバイス用の IC チップのこと
    - ELM327 チップを搭載した OBD2 デバイスを使うことで、車の様々なデータを取得することができる
    - ELM327 チップを搭載した OBD2 デバイスが各社から発売されており、USB / Wi-Fi / Bluetooth などさまざまな方式で接続できる
- CAN (Controller Area Network)
    - ISO 15765 で定められている、OBD2 コネクタ上で用いられる通信プロトコルの一種
    - CAN の中にも種類があるらしい
    - 日本車の多くは CAN による通信に対応しているらしい

**「OBD2 ポートに ELM327 デバイスを接続して CAN 通信する」** みたいなイメージで多分あっていると思う！！！ (自信はない)

### 環境
- Raspberry Pi 3B
- Raspbian Buster
- [M-OBD-V01A](https://www.amazon.co.jp/gp/product/B08LPM8MSD?&linkCode=ll1&tag=hotogoma-22&linkId=e3e92f83bd3ccd07eabaa9452c2551f6&language=ja_JP&ref_=as_li_ss_tl) (Bluetooth OBD アダプタ)
    - OBD アダプタは様々な種類があり、良し悪しがあるらしいので慎重に選んだほうが良さそう
    - USB 接続できるやつとか Wi-Fi 飛ばすやつとかあるけど、今回は Bluetooth 接続するやつにした
    - オンオフスイッチがないやつだと車に挿しっぱなしにしたときに給電され続けてバッテリが上がってしまうかもしれない (？) のでオンオフスイッチがあるやつが良いと思う

### ハードウェア構成
- RasPi を AP にして PC から SSH ログイン
    - そんなややこしいことしなくても有線で繋ぐのが一番簡単ではある
    - 無線 AP 化しておくと車の中で作業しやすくて便利


### 手順1: Bloetooth デバイスの MAC アドレスを調べる
hcitool コマンドを使うと Bluetooth デバイスのスキャンを行うことができる。

今回用いた Raspbian Buster では何もインストールしなくても hcitool を使うことが出来た。

``` console
$ sudo hcitool lescan
LE Scan ...
66:1E:11:XX:XX:XX M-OBD-V01A
(以下略)
```

今回はデバイスの MAC アドレスがわかればいいのでこれだけで事足りるが、デバイスの詳細を見たい場合は info サブコマンドで調べられる。

``` console
$ sudo hcitool info 66:1E:11:XX:XX:XX
Requesting information ...
        BD Address:  66:1E:11:XX:XX:XX
        Device Name: M-OBD-V01A
        LMP Version: 2.1 (0x4) LMP Subversion: 0x12e9
        Manufacturer: Cambridge Silicon Radio (10)
(以下略)
```

### 手順2: RFCOMM を使って仮想シリアルポートとして認識させる
実際の通信相手は Bluetooth デバイスなんだけど、あたかもシリアルポートで通信しているかのように簡単に扱えるようにする、というやつらしい。

``` console
$ sudo rfcomm bind 0 66:1E:11:XX:XX:XX
```

``` console
$ sudo rfcomm listen 0 1 &
```

### OBD2 にアクセスする
Python でデータを扱いたいので、[python-OBD](https://python-obd.readthedocs.io/en/latest/) を使用する。

``` console
$ sudo apt install -y python3-pip
$ sudo pip3 install ipython obd
```

※ ipython は入れなくてもいいけど、あるとデバッグしやすいので。

``` python:ipython
In [1]: import obd

In [2]: connection = obd.OBD()

In [3]: connection.status()
Out[3]: 'Car Connected'

In [4]: connection.query(obd.commands.SPEED).value
Out[4]: <Quantity(0.0, 'kph')>
```

`Car Connected` となり、車の速度を取得できた！
コマンドを変更すると他の様々なデータも取得できる。

めでたしめでたし

## 次回
<del>位置情報の取得に苦しめられた話をします。</del> 結局書けていない

## 参考
- [RaspberryPi + OBD2 で取得した車両情報を解析してみる - Qiita](https://qiita.com/nomunomu0504/items/8876f34fb33d8bf24fcb)
- [Raspberry Pi で無線ルータを自作する - Qiita](https://qiita.com/hoto17296/items/2e638fa28597b18505cd)
- [OBD-IIおよびELM327の説明](https://ganchi.rdy.jp/AppObdInfoSan/OBD.html)
- [OBD Info-san! 動作確認済み車両](https://ganchi.rdy.jp/AppObdInfoSan/car.html)