You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a sketch sets a custom I2C clock (e.g. Wire1.setClock(400000)) and then
brings up Modulino modules, the clock is silently reset to 100 kHz. The sensor
modules respond correctly but much more slowly, with no error or warning.
Each sensor module's begin() then re-initialises the bus through its underlying
library, which calls _wire->begin(); on the Renesas core TwoWire::begin()
unconditionally calls setClock(I2C_MASTER_RATE_STANDARD) (100 kHz). E.g. ModulinoMovement::begin() → LSM6DSOXClass::begin() → _wire->begin().
So any setClock() the user makes before the module begin() calls is undone.
How it manifests
An 8× ModulinoMovement network through a TCA9548A mux on a UNO R4 WiFi ran at
~10 Hz instead of the expected ≥30 Hz; per-sensor read latency was ~11 ms at the
unintended 100 kHz vs ~503 µs at 400 kHz (~22× slowdown). No error is reported.
Workaround (current)
Call setClock()after all module begin() calls:
Modulino.begin();
ModulinoMovement imu;
imu.begin(); // resets clock to 100 kHz
Wire1.setClock(400000); // re-apply AFTER begin()
Suggestions
Document that setClock() must be called after all module begin() calls
(this is non-obvious and easy to get wrong with multiple modules).
Consider letting users specify a target bus clock that Modulino re-applies after
each inner begin(), since the reset originates in the underlying libraries.
Summary
When a sketch sets a custom I2C clock (e.g.
Wire1.setClock(400000)) and thenbrings up Modulino modules, the clock is silently reset to 100 kHz. The sensor
modules respond correctly but much more slowly, with no error or warning.
There are two contributing layers:
ModulinoClass::begin()sets_wire->setClock(100000)itself.begin()then re-initialises the bus through its underlyinglibrary, which calls
_wire->begin(); on the Renesas coreTwoWire::begin()unconditionally calls
setClock(I2C_MASTER_RATE_STANDARD)(100 kHz). E.g.ModulinoMovement::begin()→LSM6DSOXClass::begin()→_wire->begin().So any
setClock()the user makes before the modulebegin()calls is undone.How it manifests
An 8×
ModulinoMovementnetwork through a TCA9548A mux on a UNO R4 WiFi ran at~10 Hz instead of the expected ≥30 Hz; per-sensor read latency was ~11 ms at the
unintended 100 kHz vs ~503 µs at 400 kHz (~22× slowdown). No error is reported.
Workaround (current)
Call
setClock()after all modulebegin()calls:Suggestions
setClock()must be called after all modulebegin()calls(this is non-obvious and easy to get wrong with multiple modules).
each inner
begin(), since the reset originates in the underlying libraries._wire->begin()intheir
begin(). Filed for the LSM6DSOX case at begin() calls Wire.begin(), silently resetting the I2C clock to 100 kHz on Renesas (UNO R4) Arduino_LSM6DSOX#53; the samepattern is present in
Arduino_HS300x,Arduino_LTR381RGB, andArduino_LPS22HB.Environment
arduino:renesas_uno1.6.0