takashiskiのブログ

覚書の殴り書き

磁気エンコーダー MT6701 を使う

とりあえず情報整理。

  • MT6701はMagnTekの磁気エンコーダーセンサー。データシートはこれ
  • 「AS5600の置き換えに」と記載されていることが多い。
  • ブレイクアウトボードとして YYC-MT6701がある
  • 径方向着磁の磁石が必要

YYC-MT6701は商品説明欄によると

  • 初期状態ではABZ出力が有効でI2Cは無効になっている
  • I2Cを使いたい場合は、IICと書かれているジャンパを繋げる
    • SPIを使いたい場合もIICジャンパをつなぐらしい(レビューより)

データシートによると、基本的なエンコーダーとしては以下の4ピンだけ接続すれば動作すると考えられます。

  • VCC
  • GND
  • A
  • B

接続しないピンの用途は以下

  • Zは一周のタイミングで立ち上がるピン
  • Pushは磁石の距離が変わった時に押し込まれた判定を出力するピン
  • OUTはPWMかアナログのどちらかのよう。どっちかはわからなかった。

I2Cモード?での動作確認

ABZモードでの動作が、解像度が高すぎて限界を感じたので、I2C出力を試みました。 めちゃくちゃ解像度が高いので、ちょっとどっちかに触れるだけでめちゃくちゃ立ち上がります。

結論から言うとI2Cでは動作せず、SSI(SPI MODE2)で動作確認がとれました。

SSIモードでは14ビット16384段階で角度が出力されることになっています。 しかし、最上位ビットが常に1だったので、実質13ビット8192段階と考えるのがよさそうです。

データシートでは角度変換には14ビットの値に360をかけて16384で割ればよいと記載されていましたが、前述の理由により180-360の範囲で1周を表現することになってしまっています。 14ビットの値から8192をひいて360をかけて8192で割ることで0-360で表現されます。

ABZに対するSPIのピン対応は以下の通りです。

ABZ SPI
A DO(MISO)
B SCK/CLK
Z CS

動作確認したコードは以下の通りです。 以下の三つは各々の使ったマイコンボードのピンに置き換える必要があります。

  • SPI_SCK
  • SPI_MISO
  • SPI_CS
#include <SPI.h>
#define OCB(c) (c&1)|(c&2)<<2|(c&4)<<4|(c&8)<<6|(c&16)<<8|\
(c&32)<<10|(c&64)<<12|(c&128)<<14


#define SPI_SCK PA5
#define SPI_MISO PA6
#define SPI_CS PB6

int angle=0;

void setup() {
  pinMode(SPI_CS,OUTPUT);
  digitalWrite(SPI_CS,1);
  SPI.begin();
  Serial.begin(19200);
}

void loop() {
  angle=0;
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE2));
  digitalWrite(SPI_CS,0);
  char data1 = SPI.transfer(0);
  char data2 = SPI.transfer(0);
  char data3 = SPI.transfer(0);
  digitalWrite(SPI_CS,1);

  SPI.endTransaction();
  angle += (int)data1<<6; //top 8 bits of 14bits
  angle += (int)data2>>2; //bottom 6 bits of 14 bits
  Serial.print(angle);
  Serial.print(", ");
  Serial.print((angle-8192)*360/8192);
  Serial.print(", ");
  Serial.printf("%08o %08o %08o",OCB(data1), OCB(data2), OCB(data3)); //各バイト2進数表示
  Serial.println();
}

参考資料