Fix AK09918 init: correct WIA2 expected value and broken retry loop
AK09918 WIA2 device ID is 0x0C (not 0x09 which belongs to AK09916). Previous check falsely reported init failure for a working sensor. The retry loop was resetting the sensor on every attempt, which clears CNTL2 back to power-down before the sensor can produce a measurement. At 100 Hz the first sample takes ~10 ms; checking isDataReady immediately after switchMode always returned NOT_RDY, triggering another reset. New approach: switch to continuous mode once, then poll with 15 ms delay (one sample period + margin) up to 20 times without resetting. Only re-apply the mode if an actual I2C read failure occurs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
2180415f5c
commit
12b025367c
@@ -315,42 +315,41 @@ void imuInit()
|
|||||||
if (qmi8658_.begin() == 0)
|
if (qmi8658_.begin() == 0)
|
||||||
Serial.println("qmi8658_init fail");
|
Serial.println("qmi8658_init fail");
|
||||||
|
|
||||||
// Verify AK09918 is present on I2C before trying to configure it.
|
// Verify AK09918 is present on I2C.
|
||||||
// WIA2 register (0x01) must return 0x09 on a real AK09918.
|
// WIA1=0x48 (AKM company ID), WIA2=0x0C (AK09918 device ID).
|
||||||
{
|
{
|
||||||
const uint16_t devId = magnetometer_.getDeviceID();
|
const uint16_t devId = magnetometer_.getDeviceID();
|
||||||
|
const uint8_t wia1 = (uint8_t)(devId >> 8);
|
||||||
const uint8_t wia2 = (uint8_t)(devId & 0xFF);
|
const uint8_t wia2 = (uint8_t)(devId & 0xFF);
|
||||||
if (wia2 != 0x09) {
|
if (wia1 != 0x48 || wia2 != 0x0C) {
|
||||||
Serial.printf("AK09918_init fail: WIA2=0x%02X (expected 0x09). "
|
Serial.printf("AK09918 warning: WIA1=0x%02X WIA2=0x%02X (expected 0x48/0x0C). "
|
||||||
"Check I2C wiring on SDA/SCL (GPIO32/33), "
|
"Check I2C on SDA=GPIO32 SCL=GPIO33, address 0x0C.\n", wia1, wia2);
|
||||||
"address 0x0C, and power supply.\n", wia2);
|
|
||||||
} else {
|
} else {
|
||||||
Serial.println("AK09918 found on I2C.");
|
Serial.println("AK09918 found (WIA OK).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize to power-down first so the subsequent switchMode goes through
|
// Put sensor in a known state before switching to continuous mode.
|
||||||
// a defined state (unlike AK09918_NORMAL which skips I2C entirely).
|
|
||||||
magnetometer_.initialize(AK09918_POWER_DOWN);
|
magnetometer_.initialize(AK09918_POWER_DOWN);
|
||||||
delay(1);
|
delay(10); // datasheet: >=100µs after power-down; 10ms is safe
|
||||||
magnetometer_.switchMode(AK09918_CONTINUOUS_100HZ);
|
magnetometer_.switchMode(AK09918_CONTINUOUS_100HZ);
|
||||||
|
|
||||||
|
// At 100 Hz the first sample takes ~10 ms. Poll ST1 with a delay
|
||||||
|
// instead of resetting on every attempt (reset clears the mode setting).
|
||||||
|
err = AK09918_ERR_NOT_RDY;
|
||||||
|
for (int retry_times = 0; retry_times < 20 && err != AK09918_ERR_OK; retry_times++) {
|
||||||
|
delay(15); // wait one sample period (100Hz = 10ms) plus margin
|
||||||
err = magnetometer_.isDataReady();
|
err = magnetometer_.isDataReady();
|
||||||
int retry_times = 0;
|
if (err == AK09918_ERR_READ_FAILED) {
|
||||||
while (err != AK09918_ERR_OK) {
|
// I2C error – mode may have been lost, try re-applying it once.
|
||||||
Serial.printf("AK09918 not ready (err=%d), retry %d/10...\n", err, retry_times + 1);
|
Serial.printf("AK09918 I2C read failed on retry %d, re-applying mode...\n", retry_times + 1);
|
||||||
delay(100);
|
|
||||||
magnetometer_.reset();
|
|
||||||
delay(100);
|
|
||||||
magnetometer_.switchMode(AK09918_CONTINUOUS_100HZ);
|
magnetometer_.switchMode(AK09918_CONTINUOUS_100HZ);
|
||||||
err = magnetometer_.isDataReady();
|
|
||||||
retry_times ++;
|
|
||||||
if (retry_times > 10) {
|
|
||||||
Serial.println("AK09918 init timed out. Magnetometer will be unavailable.");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (err == AK09918_ERR_OK) {
|
if (err == AK09918_ERR_OK) {
|
||||||
Serial.println("AK09918 ready.");
|
Serial.println("AK09918 ready.");
|
||||||
|
} else {
|
||||||
|
Serial.printf("AK09918 init timed out (last err=%d). Magnetometer will be unavailable.\n", err);
|
||||||
}
|
}
|
||||||
// Serial.println("Start figure-8 calibration after 1 seconds.");
|
// Serial.println("Start figure-8 calibration after 1 seconds.");
|
||||||
// delay(1000);
|
// delay(1000);
|
||||||
|
|||||||
Reference in New Issue
Block a user