I’m using a LSM303 and Baby Orangutan in a battery powered digital compass project, and would like to use the “intertial interrupt” feature to avoid needing a power switch.
It seems I should be able to do this by:
- configuring the LSM303 sleep-to-wakeup (to wake the sensor) and inertial interrupts (to wake the uC)
- sending the the LSM303 and then the uC to sleep after some idle period
I’m having trouble discerning exactly how to set this up from the LSM303 datasheet, is there any tutorial or library that handles this part of the LSM303?
My notes thus far, with q’s aplenty:
Waking the sensor
The LSM303 inertial and magnetic sensors are separate, and section 4.3 only mentions sensing acceleration when sleeping, so I presume it’ll not wake on magnetic field change (which is fine for my application)
The accel. sensor power modes include: power-down, “normal”, and a number of low-power modes (slower update rates); I’m unclear as to what mode the device should be put to enable the wake-from-sleep aka sleep-to-wake feature. The process below is what I extracted from the datasheet’s 9.1.1 CTRL_REG1_A and 9.1.5 CTRL_REG5_A, and 9.1.12 INT1_CFG_A:
So seems like when setting up and entering sleep, I need to:
a) turn off the mag sensor: set MR_REG_M:MD0 and/or MD1 (mode select) to 1
b) configure the acceleration sensor: with say a “normal” update (Output Data Rate) of 50 Hz (CTRL_REG1_A: PM=001; DR=00), I’d just have to set TurnOn bits of CTRL_REG5_A to 11 to go into sleep mode?
(an alternate reading suggests I’d set CTRL_REG1_A:PM=010 to go into a low-power mode, and then do CTRL_REG5_A:TurnOn ?)
I’d also need to configure INT1_* registers to select the interrupt events and thresholds: the INT1_CFG_A register has AOI and D6 bits that together are described as “6-direction movement recognition” and “6-direction position recognition”; what’s the difference? (what does “Position detection” mean on this component, anyhow? does it doubly-integrate acceleration over time to give some displacement measure? The datasheet says zip on this.)
Waking the uC
If the INT1 pin were level shifted, it would be straightforward to connect to any pin on the uC and set a wake interrupt on that; however…
The INT1 pin is not level shifted by the Pololu carrier board, at 1.8V will be too low to register on the uC (which is running from 5V; atmega328p datasheet says V_IH = 0.6Vcc; or 3V); I’ve considered:
a) connecting INT1 to the uC analog comparator and setting an interrupt on that (ACSR / ANALOG_COMP_vect)
b) level shifting the INT1 output via a MOSFET
c) configure INT1 on the sensor to be active low, configure a uC PCINTx input with a pull-up to the uC Vcc (5V) - I believe I’ll need a ~20k resistor from the uC input to GND to limit the voltage on INT1 to under (VDD+0.1)=3.1 V
but:
a) requires the comparator be left on and thus will use more power (how much?) than a simple pin level interrupt
b) I don’t otherwise need any external components (currently: baby orangutan, lsm303 and a 5v regulator) so introducing a single mosfet is a little awkward
c) still has an additional component, but a resistor can probably be piggy-backed on the orangutan; can I get away without this?
I also considered observing if the sensor toggles i2c state in any way when waking and trigger the uC on that - but from what I’ve read of i2c so far, the i2c master must kick off every exchange. i.e. the sensor will be mute via i2c until instructed by the uC (right?).
Ben