RobTillaart / AS5600

Arduino library for AS5600 magnetic rotation meter
MIT License
109 stars 20 forks source link

Teensy 4.1 cannot connect to AS5600 #53

Closed SquadQuiz closed 9 months ago

SquadQuiz commented 9 months ago

I'm using this library with teensy 4.1, I have found some issue on the library version 0.5.1 and the latest version work with my board is version 0.4.1 The issue is I cannot get any data via I2C connection.

After investigation I found something in the PR no. #47 in AS5600.cpp file

bool AS5600::begin(uint8_t directionPin)
{
  _directionPin = directionPin;
  if (_directionPin != AS5600_SW_DIRECTION_PIN)
  {
    pinMode(_directionPin, OUTPUT).
  }
  setDirection(AS5600_CLOCK_WISE);

  if (! isConnected()) return false;
  return true;
}

So I try restore some code from version 0.4.1 and it's work for my teensy 4.1

bool AS5600::begin(uint8_t directionPin)
{
  _directionPin = directionPin;
  if (_directionPin != AS5600_SW_DIRECTION_PIN)
  {
    pinMode(_directionPin, OUTPUT).
  }
  setDirection(AS5600_CLOCK_WISE);

  _wire->begin();   // I restore this line..
  if (! isConnected()) return false;
  return true;
}

Sqk~ Thanks

RobTillaart commented 9 months ago

@SquadQuiz

Thanks for the issue, The removal of that line was by design. This is documented in the changelog.md and the readme.md file, including the solution how and when to call the begin()) function. See below.

0.5.0 Breaking change Version 0.5.0 introduced a breaking change. You cannot set the pins in begin() any more. This reduces the dependency of processor dependent Wire implementations. The user has to call Wire.begin() and can optionally set the Wire pins before calling begin().

Long Answer

The reason to remove the _wire->begin() is that different boards can have different sets of parameters for the begin() function. Most incompatible one is to set the pins used for the I2C bus in question by different boards (e.g. ESP, RP2040). Furthermore the begin() function might reset the internal variables e.g. clock speed, that interferes with settings made before by the user.

So I had to refactor the code of the library (and all my I2C ones) to do what is known as "dependency injection". Only pass a reference to a dependency (I2C class) , but do not handle settings of that (I2C) class that also might be dependent of the (I2C) class.

So this change makes it explicit for the user what the I2C settings are and where they are set. For me as developer it reduced the lines of code and code paths so it improved maintainability.

SquadQuiz commented 9 months ago

@RobTillaart Thanks for your kind explanation,

Let me try to use I2C begin() method of Teensy 4.1 on my Arduino sketch. Later, I will let you know the result. Furthermore, I will create a demo example sketch for this library using Teensy 4.1 if it is useful for others.

RobTillaart commented 9 months ago

@SquadQuiz A teensy specific example is definitely welcome.

SquadQuiz commented 9 months ago

@RobTillaart

I have done testing AS5600 library with specific begin() method for Teensy. Now I can run a demo sketch without any issues.

Here is snippet of code,

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);
  Serial.print("AS5600_LIB_VERSION: ");
  Serial.println(AS5600_LIB_VERSION);

  Wire.begin(); 

  as5600.begin(4);  //  set direction pin.
  as5600.setDirection(AS5600_CLOCK_WISE);  //  default, just be explicit.
  int b = as5600.isConnected();
  Serial.print("Connect: ");
  Serial.println(b);
  delay(1000);
}

It seems like Wire.begin() method in Teensy doesn't require parameter SDA and SCL pins.

Below is a snapshot. serial