2023年12月30日土曜日

MT6701のI2C版をArduinoで使ってみた。

 モータの回転制御をやってみるのに磁気式エンコーダを購入してみた。Arduinoで使うならAS5600がお手軽で良さそうだったんだけど、MT6701というやつが14bitでいろんなインターフェースに対応しているようだったので購入してみた。

MT6701

小さい磁石も付属していた。

MT6701

今回はI2C版が安かったのでSPI使いたかったら後で改造すればいいかということでI2C版にしてみた。
MT6701のインターフェースとしてはI2C、SSI、アナログ、PWM、ABZに対応してる。アナログとPWMの切り替えはI2Cでレジスタの書き込みを行わないといけないみたい。今回のモジュールはPWM/アナログとI2Cに対応するような配線になっていた。

とりあえずBluepillを使ってI2Cで動作確認してみた。I2CのスレーブIDは0x06。

#include <Wire.h>

#define MT6701_ADDR 0x06  // MT6701のI2Cアドレス

void setup() {
  Serial.begin(115200);
  Wire.begin();  //SDA=PB7, SCL=PB6
  Serial.println("MT6701 Angle Reader Start");
}

void loop() {
  Wire.beginTransmission(MT6701_ADDR);
  Wire.write(0x03);  //MT6701の角度データ上位バイト
  if (Wire.endTransmission(false) != 0) {
    Serial.println("I2C Write Error");
  } else {
    Wire.requestFrom(MT6701_ADDR, 2);  //2バイト読み込み
    if (Wire.available() >= 2) {
      uint8_t high = Wire.read();
      uint8_t low = Wire.read();
      uint16_t angle = ((high & 0x3F) << 8) | low;  //14bit角度データ
      float degrees = (angle / 16384.0) * 360.0;    //degに変換
      uint8_t mg = (high >> 4) & 0x0F; //ステータス
      Serial.print("Raw: ");
      Serial.print(angle);
      Serial.print(", Degrees: ");
      Serial.print(degrees, 2);
      Serial.print(", Status: ");
      Serial.println(mg,BIN);
    } else {
      Serial.println("I2C Read Error");
    }
  }
  delay(200);
}

これでI2CでPB7(SDA)とPB6(SCL)にセンサーを接続すると値が出る用になった。
Statusにはマグネットが近すぎるかとか遠すぎるの他に、プッシュボタン機能や検知できないエラー情報とかも含まれている。
先頭の2bitは磁力の状態。(0→ノーマル、1→近すぎる、10→遠すぎる)

例えば0010だったらプッシュボタンが押されたとか、1だったら磁石が強すぎるとか。詳しくはデータシートのmgの所を参照するといいかも。

SSIモードはSPIライクな受信オンリーモードみたいなのでマイコンのSPIポートを使用して高速に使えるみたい。高回転なモータとかだとSSIモードのほうが良いかもしれないので次回は基板を改造してマイコンのSPIポートで試してみようかと思う。

この基板は8番PinがVCCに直結されてしまっているのでこれをCSとして取り出せば行けそうな感じ。SPIはActive Lowなのでうまく作られている気はする。ちなみに8番PinはプルアップされているのでCSに何も繋がなければI2Cとして動かせそう。6Pinだしてそういう基板にしておいてほしかったな。

データシートによると6VのTVSを電源ラインに追加しておくと良いみたいだけど、こういったモジュールにこそ追加しておかないとな…

0 件のコメント:

コメントを投稿