Magnetic sensor MT6701 I2C integration

Dear folks,

Could not find any resource online, neither in this forum regarding with MT6701 i2c integration, so I have modified MagneticSensorI2C.cpp as below, and everything works like a charm. will make a MR on github sometime whne I have time. Enjoy!

Simply add snippet below at line 19,then you can do the following declaration in main program.

MagneticSensorI2C sensor = MagneticSensorI2C(MT6701_I2C);

#include “MagneticSensorI2C.h”

/** Typical configuration for the 12bit MT6701 magnetic sensor over I2C interface */
MagneticSensorI2CConfig_s MT6701_I2C = {
.chip_address = 0x06,
.bit_resolution = 14,
.angle_register = 0x03,
.data_start_bit = 15
};

Full file:

/** Typical configuration for the 12bit AMS AS5048 magnetic sensor over I2C interface */
MagneticSensorI2CConfig_s AS5048_I2C = {
.chip_address = 0x40, // highly configurable. if A1 and A2 are held low, this is probable value
.bit_resolution = 14,
.angle_register = 0xFE,
.data_start_bit = 15
};

/** Typical configuration for the 12bit MT6701 magnetic sensor over I2C interface */
MagneticSensorI2CConfig_s MT6701_I2C = {
.chip_address = 0x06,
.bit_resolution = 14,
.angle_register = 0x03,
.data_start_bit = 15
};

// MagneticSensorI2C(uint8_t _chip_address, float _cpr, uint8_t _angle_register_msb)
// @param _chip_address I2C chip address
// @param _bit_resolution bit resolution of the sensor
// @param _angle_register_msb angle read register
// @param _bits_used_msb number of used bits in msb
MagneticSensorI2C::MagneticSensorI2C(uint8_t _chip_address, int _bit_resolution, uint8_t _angle_register_msb, int _bits_used_msb){
// chip I2C address
chip_address = _chip_address;
// angle read register of the magnetic sensor
angle_register_msb = _angle_register_msb;
// register maximum value (counts per revolution)
cpr = _powtwo(_bit_resolution);

// depending on the sensor architecture there are different combinations of
// LSB and MSB register used bits
// AS5600 uses 0…7 LSB and 8…11 MSB
// AS5048 uses 0…5 LSB and 6…13 MSB
// MT6701 uses 0…5 LSB and 6…13 MSB
// used bits in LSB
lsb_used = _bit_resolution - _bits_used_msb;
// extraction masks
lsb_mask = (uint8_t)( (2 << lsb_used) - 1 );
msb_mask = (uint8_t)( (2 << _bits_used_msb) - 1 );
wire = &Wire;
}

MagneticSensorI2C::MagneticSensorI2C(MagneticSensorI2CConfig_s config){
chip_address = config.chip_address;

// angle read register of the magnetic sensor
angle_register_msb = config.angle_register;
// register maximum value (counts per revolution)
cpr = _powtwo(config.bit_resolution);

int bits_used_msb = config.data_start_bit - 7;
lsb_used = config.bit_resolution - bits_used_msb;
// extraction masks
lsb_mask = (uint8_t)( (2 << lsb_used) - 1 );
msb_mask = (uint8_t)( (2 << bits_used_msb) - 1 );
wire = &Wire;
}

MagneticSensorI2C MagneticSensorI2C::AS5600() {
return {AS5600_I2C};
}

void MagneticSensorI2C::init(TwoWire* _wire){

wire = _wire;

// I2C communication begin
wire->begin();

this->Sensor::init(); // call base class init
}

// Shaft angle calculation
// angle is in radians [rad]
float MagneticSensorI2C::getSensorAngle(){
// (number of full rotations)*2PI + current sensor angle
return ( getRawCount() / (float)cpr) * _2PI ;
}

// function reading the raw counter of the magnetic sensor
int MagneticSensorI2C::getRawCount(){
return (int)MagneticSensorI2C::read(angle_register_msb);
}

// I2C functions
/*

  • Read a register from the sensor

  • Takes the address of the register as a uint8_t

  • Returns the value of the register
    */
    int MagneticSensorI2C::read(uint8_t angle_reg_msb) {
    // read the angle register first MSB then LSB
    byte readArray[2];
    uint16_t readValue = 0;
    // notify the device that is aboout to be read
    wire->beginTransmission(chip_address);
    wire->write(angle_reg_msb);
    currWireError = wire->endTransmission(false);

    // read the data msb and lsb
    wire->requestFrom(chip_address, (uint8_t)2);
    for (byte i=0; i < 2; i++) {
    readArray[i] = wire->read();
    }

    // depending on the sensor architecture there are different combinations of
    // LSB and MSB register used bits
    // AS5600 uses 0…7 LSB and 8…11 MSB
    // AS5048 uses 0…5 LSB and 6…13 MSB
    // MT6701 uses 0…5 LSB and 6…13 MSB
    readValue = ( readArray[1] & lsb_mask );
    readValue += ( ( readArray[0] & msb_mask ) << lsb_used );
    return readValue;
    }

/*

  • Checks whether other devices have locked the bus. Can clear SDA locks.

  • This should be called before sensor.init() on devices that suffer i2c slaves locking sda

  • e.g some stm32 boards with AS5600 chips

  • Takes the sda_pin and scl_pin

  • Returns 0 for OK, 1 for other master and 2 for unfixable sda locked LOW
    */
    int MagneticSensorI2C::checkBus(byte sda_pin, byte scl_pin) {

    pinMode(scl_pin, INPUT_PULLUP);
    pinMode(sda_pin, INPUT_PULLUP);
    delay(250);

    if (digitalRead(scl_pin) == LOW) {
    // Someone else has claimed master!");
    return 1;
    }

    if(digitalRead(sda_pin) == LOW) {
    // slave is communicating and awaiting clocks, we are blocked
    pinMode(scl_pin, OUTPUT);
    for (byte i = 0; i < 16; i++) {
    // toggle clock for 2 bytes of data
    digitalWrite(scl_pin, LOW);
    delayMicroseconds(20);
    digitalWrite(scl_pin, HIGH);
    delayMicroseconds(20);
    }
    pinMode(sda_pin, INPUT);
    delayMicroseconds(20);
    if (digitalRead(sda_pin) == LOW) {
    // SDA still blocked
    return 2;
    }
    _delay(1000);
    }
    // SDA is clear (HIGH)
    pinMode(sda_pin, INPUT);
    pinMode(scl_pin, INPUT);

    return 0;
    }

motor that I coupled it with:
https://nl.mouser.com/ProductDetail/SparkFun/ROB-20441?qs=1Kr7Jg1SGW9zbyRI9In86Q%3D%3D&mgh=1&utm_id=20333412842&gad_source=1&gclid=CjwKCAjwrvyxBhAbEiwAEg_Kgvi7ptAtE5Rgdw87GJZpCB4Hixt1Yirz6DBIkKL3UqeddUc_MV7O1RoCKwsQAvD_BwE

My setup:

3 Likes

Thank you for the contribution.

Hopefully (@Antun_Skuric , @runger ?) it will get integrated into the next release if possible.

Cheers,
Valentine

`no worries, thank you guys for maintaining such useful open source project. Here is the MR:

Btw, do you think it would be useful to add an example ?

Hi, thank you.

Yes, an example would be awesome!

Cheers,
Valentine