Grove mini I2C motor driver(DRV8830)とM5StickCでモーターを動かす

Grove mini I2C motor driverを動かそうとしてハマったので解決法を共有したいと思います。

Grove mini I2C motor driverというのはこういうものです

Grove - Mini I2C Motor Driver v1.0 - Seeed Wiki
http://wiki.seeedstudio.com/Grove-Mini_I2C_Motor_Driver_v1.0/

GROVE - I2C ミニモータードライバ - スイッチサイエンス
https://www.switch-science.com/catalog/2510/
Grove端子で接続してモーターを2つ回すことができます。

##ライブラリのインストール##
Arduino IDEのライブラリマネージャからインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/6e5e8e36-be92-1d41-a528-e254acd0d6d8.png)


が、結論から言うと **このライブラリは動かないので捨てます!**(うちの環境では)

##I2Cを使って自力で動かす##

I2CでM5StickCのGroveから操作してみることにします。
たまたまM5StickCを使いましたがGroveがついてる、
または無理矢理Groveに配線すれば普通のArduinoなどでもI2Cで使えると思います。

M5StickCのGroveはG32,G33なので

```
  Wire.begin(32, 33);
```

で初期化します。

I2Cのアドレスを設定しますので公式サイトを見に行くと**ウソを書いてあるので騙されます**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/f25a60a8-6ddc-49c6-8b82-1a85de770771.png)

公式サイトにはこのようにCH1が0xC4,CH2が0xC0と書いてありますが、
本体の基盤の裏を見ると・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/3a2043ab-f71a-6a86-c5b9-bd38dc9bd53e.png)

DEFAULT ADDR1:0xCA(W) 0xCB(R)
DEFAULT ADDR2:0xC0(W) 0xC1(R)
と書かれています。
(Ver1.1で変わった？)
が、このアドレスをそのまま指定しても動きません。

ネットで動かしてる方がいたので読んでみると・・・

[Grove I2C ミニモータードライバをNefryBTで操作する - 不動の鳥の勉強記録](http://hiyo-ac.hatenablog.com/entry/2018/05/20/141501)

>書き込みのアドレスは0xC4hとなりました。
>ただ、Arduinoの場合は1ビット右シフトするので、0x62hとなります。

**Arduinoの場合は1ビット右シフトする**

そんなの知らなかった・・・(´・ω・`)

というわけでやっとアドレスが特定できました。

```
CA 11001010
↓右シフト
65 01100101

#define ADDR 0x65 // CH1の書き込みアドレス
#define ADDR2 0x60 // CH2の書き込みアドレス
```

[Grove I2C ミニモータードライバをNefryBTで操作する - 不動の鳥の勉強記録](http://hiyo-ac.hatenablog.com/entry/2018/05/20/141501)

DRV8830データシートPDF
http://www.tij.co.jp/jp/lit/ds/symlink/drv8830.pdf

あとはまたこちらを参考にしてデータ形式を確定します

```cpp

#define ADDR 0x65 // CH1の書き込みアドレス
#define CONTRL 0x00 //レジスタのサブアドレス
#define FAULT 0x01 //レジスタのサブドレス

Wire.beginTransmission(ADDR); // CH1の書き込みアドレスに対して操作をする
Wire.write(CONTRL); // サブアドレスを指定する
Wire.write(0b10010101); //電圧設定とブリッジ制御を行う※
Wire.endTransmission();
```

※1バイトの前6桁で電圧(PDF10ページ参照)を、後ろ2桁で動作を指定する
000000 00 ←停止
111111 01 ←正転5V
100101 10 ←逆転3V
000000 11 ←ブレーキ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/dadbeed3-2bfd-808a-9a1e-b3c2e5a9c1c2.png)


##FAULTレジスタを読む

異常が発生した時基板上のFAULT LEDが点灯し、FAULTレジスタにその内容が書き込まれます。

```cpp

#define FAULT 0x01  // 00000001
#define CLEAR 0x80  // 10000000
#define ILIMIT 0x10 // 00010000
#define OTS 0x08    // 00001000
#define UVLO 0x04   // 00000100
#define OCP 0x02    // 00000010

//読み込み Falut(異常)が発生した場合エラーコードを読み込む
Wire.beginTransmission(ADDR);  //Slave Address
Wire.write(FAULT);             // Sub Address
Wire.endTransmission(); 

Wire.requestFrom(ADDR, 1);     // Slave Address
byte val = Wire.read(); // Data
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/fcb081b8-2f1f-fffb-0a85-48aa2588ea27.png)

ただしうちの環境ではFAULTが発生していなくても0x04が返ってくるのでFAULTビットが立ってない場合は無視していました

```cpp

    if (val != 0x00 && val & FAULT) {
      // レジスタの内容が0ではないがFAULTビットが立ってない場合は無視
      Serial.printf("Fault2 : %02x\n", val);
      if (val & ILIMIT) {
        M5.Lcd.println("R FAULT:ILIMIT");
      }
      if (val & OTS) {
        Serial.println("R FAULT:OTS");
      }
      if (val & UVLO) {
        Serial.println("R FAULT:UVLO");
      }
      if (val & OCP) {
        Serial.println("R FAULT:OCP");
      }
      Wire.beginTransmission(ADDR);
      Wire.write(FAULT);
      Wire.write(CLEAR); // FALUTフラグをリセットする
      Wire.endTransmission();
    }

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/b79d268a-d533-2bde-be68-dab3fc9a72bf.png)

##応用例
ESP32とBLE HIDデバイスを接続する方法(ESP32 1.0.4更新) - Qiita
https://qiita.com/coppercele/items/57354f3e5a50ec7e0573
と組み合わせるとこういう感じになります。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">いじれる時間が取れなかったので取り急ぎラジコンと繋いでモーター回す試験してみた<br><br>時間が取れたらコントローラに変更して左右を独立して動かすよ<a href="https://twitter.com/hashtag/M5StickC?src=hash&amp;ref_src=twsrc%5Etfw">#M5StickC</a> <a href="https://t.co/KGlSmMeJlO">pic.twitter.com/KGlSmMeJlO</a></p>&mdash; もけ@ムギ㌠ (@coppercele) <a href="https://twitter.com/coppercele/status/1225017697680773120?ref_src=twsrc%5Etfw">February 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

##電流を増やす
このボードはデフォルトでは1chあたり200mAしか流せませんが、
空きパターンにチップ抵抗をハンダ付けすることで増やすことができます。
測った感じ1608っぽいです。

計算式は公式Wikiにある以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/298776/762d9c46-2f8e-d8e2-441d-0a1b468a0938.png)

1Ωを追加することで400mA流せるようになります。

##最後に
結局Grove mini I2C motor driverで流せる電流が200mAということで自分が想定していた使い方では断念してしまいました。

200mA以内で大丈夫な用途では使えるかと思います。
またはDRV8830ブレイクアウトボードで使うときも同様に扱えると思います。