Arduino通过I2C驱动MT6701磁编码器并读取角度数据
- 📍相关篇《Arduino通过Wire库读取AS5600编码器数据》
- ✨测试了使用STM32硬件I2C扫描其地址失败。使用软件I2C可以。
📑MT6701(基于差分霍尔的磁性角度传感器芯片)芯片特性简介
- 🧨基于霍尔技术,0~360°绝对角度位置检测
-
- 🌿3.3V~5.0V工作电压,内置EEPROM(烧写时需要保证VDD>4.5V)
-
- 🌿独立输出接口: : I2C, SSI, ABZ,UVW, 模
拟电压、PWM以及Z轴按压检测
- 🌿独立输出接口: : I2C, SSI, ABZ,UVW, 模
-
- 🌿支持最高转速55,000 转/分钟
-
- 🌿角度输出的系统延时<5 us
-
- 🌿增量ABZ输出支持1~1024脉冲/圈,任意整
数分辨率客户可编程
- 🌿增量ABZ输出支持1~1024脉冲/圈,任意整
-
- 🌿增量UVW输出支持1~16对极,任意整数对
极客户可编程
- 🌿增量UVW输出支持1~16对极,任意整数对
-
- 🌿优异的抗杂散磁场干扰能力。
📙MT6701 IIC接口电路
- 🔖 第八引脚注意是直接接到VCC,而不是使用电阻上拉。(其内部是有上拉电阻到VCC的)
⛳MT6701 I2C 读取角度操作
MT6701做为I2C从机的地址是b’0000110(这一地址可以通过编程改为b’1000110 )。14位绝对角度数据(2的14次方,16384)保存在0x03和0x04寄存器中,请按照如图-20所示的读取0x03和0x04的角度数据。
注意:要先读0x03再读0x04。
- 🔖如果不知道MT6701芯片的I2C地址,先对编码器设备进行扫描检测。
📘Arduino I2C扫描程序
#include <Wire.h>void setup()
{// Wire.begin();Serial.begin(115200);while (!Serial); // Leonardo: wait for serial monitorSerial.println("\nI2C Scanner");// Wire.setSDA(8);// Wire.setSCL(9);Wire.begin();
}void loop()
{byte error, address;int nDevices;Serial.println("Scanning...");nDevices = 0;for(address = 1; address < 127; address++ ) {// The i2c_scanner uses the return value of// the Write.endTransmisstion to see if// a device did acknowledge to the address.Wire.beginTransmission(address);//从指定的地址开始向I2C从设备进行传输error = Wire.endTransmission();//停止与从机的数据传输/** error返回结果:* 0: 成功
1: 数据量超过传送缓存容纳限制
2: 传送地址时收到 NACK
3: 传送数据时收到 NACK
4: 其它错误*/if (error == 0){Serial.print("I2C device found at address 0x");if (address<16) Serial.print("0");Serial.print(address,HEX);Serial.println(" !");nDevices++;}else if (error==4) {Serial.print("Unknown error at address 0x");if (address<16) Serial.print("0");Serial.println(address,HEX);} }if (nDevices == 0)Serial.println("No I2C devices found\n");elseSerial.println("done\n");delay(5000); // wait 5 seconds for next scan
}
- 🔖检测结果:
📗读取原始值
#include <Arduino.h>
#include <Wire.h>const unsigned int RESOLUTION = 800;uint8_t readRegister(uint8_t address) {Wire.beginTransmission(6);Wire.write(address);Wire.endTransmission();Wire.requestFrom(6, 1);return Wire.read();
}void writeRegister(uint8_t address, uint8_t value) {Wire.beginTransmission(6);Wire.write(address);Wire.write(value);Wire.endTransmission();
}uint16_t readAbzRes() {uint16_t reg1 = readRegister(0x30) & 0x3;uint16_t reg2 = readRegister(0x31);return (reg2 | (reg1 << 8)) + 1;
}void programAbzRes(uint16_t resolution) {resolution -= 1;uint8_t reg30backup = readRegister(0x30) & 0xC;uint8_t bottom = resolution & 0xFF;uint8_t up = ((resolution >> 8) & 0x03) | reg30backup;writeRegister(0x30, up);writeRegister(0x31, bottom);writeRegister(0x09, 0xB3);writeRegister(0x0A, 0x05);delay(600);
}void setup() {Serial.begin(115200);Serial.println("Start");Wire.begin();//328PB A4:SDA A5:SCLSerial.print("ABZ reg1: ");Serial.println(readRegister(0x30), HEX);Serial.print("ABZ reg2: ");Serial.println(readRegister(0x31), HEX);if (readAbzRes() != RESOLUTION) {programAbzRes(RESOLUTION);Serial.println("Finished, power cycle");while (true);}
}void loop() {uint16_t reg1 = readRegister(3);uint16_t reg2 = readRegister(4);uint16_t pos = reg2 >> 2 | reg1 << 6;Serial.print("Pos: ");Serial.print(pos);Serial.print("\t");float Angle = float(pos/16384.00)*360;//*360;//换算角度Serial.print("Angle: ");Serial.println(Angle, 2);delay(200);
}
- 🔖测试打印数据:
📒使用MT6701库I2C读取
- 🌿依赖库:
MT6701-arduino
#include <Wire.h>
#include "MT6701.h"MT6701 encoder;void setup() {Serial.begin(115200);Wire.begin();//328p I2C: SDA:A4 ;SCL:A5encoder.initializeI2C();
}void loop() {float angle = encoder.angleRead();Serial.println(angle);delay(100);
}