ESP32からCANでGM6020を動かす

今回はESP32を使ってCAN通信でGM6020を制御する方法について説明します。ちなみにm3508（c620）なども似たような方法で制御できます。

# 開発環境
- PC
Windows11
ArduinoIDE
- USBシリアルコンバータ

https://www.amazon.co.jp/gp/product/B08H4Z735F/ref=ppx_yo_dt_b_asin_title_o02_s00?ie=UTF8&th=1

- CANトランシーバ

https://akizukidenshi.com/catalog/g/g114383/



# ファームウェアの更新とIDの変更
### RoboMaster Assistantのダウンロード
GM6020のファームウェアを更新するためにはRoboMaster Assistantというソフトウェアが必要になります。
以下のサイトからソフトウェアをダウンロードしてください。同じページに日本語ドキュメントもあるので読んでおくと良いと思います。

https://www.robomaster.com/en-US/products/components/general/gm6020

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/0da3f487-ed9b-a3c5-4d1d-2e55235d5ba8.png)

7zファイルがダウンロードされるので，適当な方法で解凍してください。

### PCとGM6020の接続
USBシリアルコンバータを用いてGM6020とPCを接続します。今回自分が利用したコンバータは6ピンのものだったので，以下の画像のように接続しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/7928f974-b2a2-1014-03df-a9b22b92d73f.png)

下側は付属品のPWM配線で，上がUSBシリアルコンバータです。
今回の場合，それぞれのピンの対応は以下の表のようになっていますが，これはコンバータの種類によって変わってくると思います。

PWM|シリアル|-
---|---|---
黒|1番|GND
灰|5番|TX
白|4番|RX

### ファームウェアの更新
GM6020に24Vを投入したら，USBシリアルコンバータをPCに接続します。
先ほど解凍したフォルダ内にある，`RoboMaster Assistant.exe`というファイルを実行してください。
上手く認識されていると，数秒で起動画面が遷移し，以下のような画面になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/460afdc2-edb2-96da-1a57-a19a9fbcb6ef.png)

画面が遷移しない場合はコンバータのRXとTXを入れ替えてみたりするといいかもしれません。
`ESC GM6020`と表示されている部分をクリックすると，以下のような画面になります。また，左下のタブから表示言語を日本語にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/09cded9b-2167-2eb2-4446-a2944aaec923.png)

ここではCANのモジュールIDを確認することができます。
ファームウェアの更新は左側の`ファームウェアの更新`タブから行うことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/1fb70558-139d-dc14-b6c9-2e948575d786.png)

`アップグレード`をクリックすると更新が始まります。
### IDの変更
IDを変更するにはモータの裏側にあるDIPスイッチを用います。詳しい内容についてはドキュメントを参照した方が良いと思いますが，簡単にここでも説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/f5b9ddc9-a1e7-94cf-8d6d-07bbd0da2ee3.png)

モータの裏側を見ると上の図のようなスイッチが見つかると思います。ここで，左三つのスイッチはモジュールIDを設定するために利用し，一番右側の4番スイッチは終端抵抗のon/offを設定するために利用します。スイッチは上がonで下がoffになります。

IDの設定方法についてですが，1~3番のスイッチがそれぞれ２進数の1の位，2の位，4の位を意味しています。なので例えばIDを4にしたい場合は以下の表のようにスイッチを変更すれば良いことになります。

1|2|3
---|---|---
off|off|on

スイッチの変更はモータの電源を入れなおすと反映されます。RoboMaster Assistantを使えば簡単にIDの変更を確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/b45eeaf1-1882-f277-5a42-92f9f3703c9f.png)


# モータの制御
### 配線
コードを書く前にESPとCANトランシーバの配線をしなければなりません。今回用いるCANトランシーバはMCP2562FDなので，以下のサイトを参考に基盤を作成しました。

https://ameblo.jp/fc2miha/entry-12833773100.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/4c018fbd-98d8-1b77-ccb6-fd652231bc7c.png)

RXをGPIO5に，TXをGPIO4に接続しました。

### ライブラリの導入
便利な制御ライブラリがあったので，それを使ってみたいと思います。

https://github.com/qingmeijiupiao/DJIMotorCtrlESP

ArduinoIDEのLibrary Managerに`DJIMotorCtrlESP`と入力すると出てくるのでインストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/6062f597-1e4f-1ae1-bfc0-f93e586f243f.png)

新規スケッチを作成し，以下のコードを貼り付けます。
```cpp
#include <DJIMotorCtrlESP.hpp>
const uint8_t RX_PIN = 5;
const uint8_t TX_PIN = 4;
//                          kp,  ki,  kd,   dead_zone, max_value
pid_param gm6020_1_speed   (10,  0,   0,    1,         16384);
pid_param gm6020_1_location(1.0, 0.1, 0.03, 5,         350);
//            can_id
GM6020 gm6020(4, gm6020_1_location, gm6020_1_speed);

void setup() {
    Serial.begin(115200);
    while(!Serial);
    can_init(RX_PIN, TX_PIN, 100);
    gm6020.setup();
}

float target_angle = 0;
bool flag = true;
void loop() {
    gm6020.set_angle(target_angle);
    if(target_angle <= 10) flag = true;
    else if(target_angle >= 350) flag = false;
    if(flag) target_angle += 1;
    else target_angle -= 1;
    delay(10);
    Serial.print(target_angle);
    Serial.print(",");
    float angle = gm6020.get_angle();
    Serial.println(angle);
}
```
上のコードではモータを位置制御して，10度から350度の間を往復させています。ライブラリの詳しい使い方についてはGitHubのReadMeを読むと良いと思います。

PCにESPを接続し，書き込んでください。
<details><summary>トラブルシューティング</summary>

---
- WindowsがESPを認識しない場合

WindowsがESPを認識しない場合はドライバを最新のものにすると良いかもしれません。
下のサイトから`CP210x Windows Drivers`をダウンロードしてください。

https://jp.silabs.com/developers/usb-to-uart-bridge-vcp-drivers?tab=downloads

zipを解凍すると，中に`CP210xVCPInstaller_x64.exe`があるので，実行するとドライバがインストールされます。
- 書き込み中にエラーが発生する場合

以下のようなエラーが発生する場合はESPのbootボタンを押しながら書き込んでください。
```
A fatal error occurred: Failed to connect to ESP32: Wrong boot mode detected (0x13)! The chip needs to be in download mode.
For troubleshooting steps visit: https://docs.espressif.com/projects/esptool/en/latest/troubleshooting.html
Failed uploading: uploading error: exit status 2
```
---
</details>

# テスト
ESPとGM6020をCANで繋いで，24Vを投入すると動き始めます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/-0iqaBXevV0?si=4wNimikm5by9df3H" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3231080/9cab1c33-7313-0afc-b855-47edaf3e82b6.png)

ArduinoIDEのシリアルプロッタで確認すると，ある程度正確に制御できている事が分かります。