Hi everyone,
I’ve been using the AS5600 magnetic encoder with Arduino Mega, and everything works fine. However, when I switch to Arduino Due, I run into problems. I’ve tried the following:
- Pull-up resistors: I’ve used values like 4.7k, 10k, 20k, and even up to 47k ohms, but the AS5600 still doesn’t work properly with Due.
- Power: The AS5600 is powered with 3.3V.
- Communication: I’m using I2C communication, and I’ve verified that the Due is able to scan and find the device on the bus. But when reading data, I get corrupted values or the device doesn’t respond.
The same setup works flawlessly with the Mega. What could be the issue with Due? Any suggestions would be greatly appreciated!
#include <Wire.h>
#define AS5600_ADDRESS 0x36
#define RAW_ANGLE 0x0C
#define DR_PIN 26 // Direction pin for determining rotation direction
#define PQO_PIN 27 // Pin connected to PQO pin of AS5600
uint16_t zeroOffset = 0;
bool firstReading = true;
int32_t cumulativeAngle = 0;
int16_t previousAngle = 0;
bool directionNegative = false;
void setup() {
Serial.begin(38400); // Set the baud rate to 38,400 bps
Wire.begin();
pinMode(DR_PIN, INPUT); // Set the direction pin as input
pinMode(PQO_PIN, OUTPUT); // Set the PQO pin as an output
digitalWrite(PQO_PIN, HIGH); // Keep PQO pin HIGH by default
}
void zeroAngle() {
digitalWrite(PQO_PIN, LOW); // Trigger zeroing on AS5600
delay(10); // Short delay to ensure zeroing is registered
digitalWrite(PQO_PIN, HIGH); // Return PQO pin to HIGH
cumulativeAngle = 0; // Reset the cumulative angle to zero
firstReading = true; // Reset the first reading flag to set a new zeroOffset
}
void loop() {
// Read the current angle from the AS5600
uint16_t currentAngle = readAS5600Angle();
// Zero the angle at startup
if (firstReading) {
zeroOffset = currentAngle;
previousAngle = 0; // Initialize previous angle to zero
directionNegative = digitalRead(DR_PIN) == LOW;
firstReading = false;
}
// Calculate the relative angle considering the zero offset
int16_t relativeAngle = (int16_t)(currentAngle - zeroOffset);
// Handle wrap-around from 0-360 degrees
int16_t deltaAngle = relativeAngle - previousAngle;
if (deltaAngle > 1800) {
cumulativeAngle -= 4096; // Handle wrap-around from 0 to 360 degrees
} else if (deltaAngle < -1800) {
cumulativeAngle += 4096; // Handle wrap-around from 360 to 0 degrees
}
// Apply the delta to the cumulative angle
cumulativeAngle += deltaAngle;
// Store the previous angle for the next loop iteration
previousAngle = relativeAngle;
// Apply direction (if directionNegative is true, make the angle negative)
int32_t finalAngle = directionNegative ? -cumulativeAngle : cumulativeAngle;
// Convert the cumulative angle to degrees (12-bit resolution)
float angleInDegrees = (finalAngle * 360.0) / 4096.0;
// Send the time and angle as a comma-separated string
unsigned long currentTime = millis();
Serial.print(currentTime);
Serial.print(",");
Serial.println(angleInDegrees);
// Wait 50 microseconds before the next reading
delayMicroseconds(50);
}
uint16_t readAS5600Angle() {
Wire.beginTransmission(AS5600_ADDRESS);
Wire.write(RAW_ANGLE);
Wire.endTransmission();
Wire.requestFrom(AS5600_ADDRESS, 2);
uint16_t angle = 0;
if (Wire.available() == 2) {
angle = Wire.read() << 8;
angle |= Wire.read();
}
return angle;
}