Here is what I have running so far:

UART: 23400 bps with 256 byte software ring buffer and 4 byte hardware FIFO. Interrupt based operation. No use of DMA for ease of portability from an existing platform.

ADC: Dual SAR converts odd/even channel pairs. Sequential conversions initiated by a software ‘global convert’ trigger and reasserted in the ISR of the last converted pair. Separate ISRs for each channel pair minimizes software overhead in processing if/else, indexing etc.

TIMER: delta-t “dt” (time since last execution) timer for Kalman filter and other integration tasks.

Inertial Measurement Unit (IMU): Will estimate roll and pitch angle by fusing measurements from a MEMS accelerometer and gyroscope using a Kalman filter. Why?

  • On it’s own, an accelerometer can output angle with respect to gravity – which appears to be stable – by using the arctan of two axes. Unfortunately the accelerometer is equally susceptible to non-gravitational acceleration, so the signal ends up being corrupted by noise from shock and vibration.
  • On it’s own, a gyroscope will natively output angular rate which must be integrated to provide an angle relative to a starting point. The output is smooth and disturbance-free when compared to the accelerometer estimate but unfortunately due to the nature of integration, the output will drift unless it’s possible to achieve an infinitely precise DC bias correction.
  • A Kalman filter takes the best of these two sensors and yields a much better estimate of angle at the expense of program memory and computation time. There is plenty of evidence around to show that this is not too much of a burden in modern ‘high speed’ microcontrollers performing ‘slow’ control applications.

…So far I have tested roll angle measurement ability. The good news is the accelerometer provides fantastic accuracy. The bad(ish) news is the gyro is not so great.

Without use of the Auto Zero (AZ) pin, the zero-rate bias of the z axis appears to randomly settle on typically either 1.41V or 1.37V after power-up, without mechanically disturbing the device. On one occasion I even saw it bias to 2.98V, which is well out of spec and leaves little room for useful signal swing. Grounding AZ made no difference.

After noticing that swiping a paper knife blade across some pins in the vicinity of the AZ input would often bring the zero-rate bias close to the reference level, I decided to implement AZ with a spare micro pin. It was not easy as I’d lost the printed pad under the leadless package. Fortunately though, it worked, and without too much extra effort, I came up with this comparison of angles (°) derived from the accelerometer v.s. that which derived from the gyro v.s. the Kalman estimated angle (NOTE: time scale omitted, but approximately 10 seconds of sensor data acquisition):

So practice follows theory: Gyro estimate drifts, accelerometer estimate noisy, Kalman estimate takes best of both and throws away the bones.

A zoom-in on Accelerometer angle estimate (blue) v.s. Kalman angle estimate (black), clearly shows how relying only on the accelerometer estimate alone is not a good idea when it comes to sudden changes in motion:

Think filtering the accelerometer estimate with a standard LPF will help? Well, it really depends how much rotational inertia (essentially how “massive and tall”) your balancing device will be. If it’s “massive and tall”, then you may be able to get away with using an accelerometer on it’s own since the phase shift introduced by filtering the signal will be relatively small. Additionally, the “massiveness and tallness” will help attenuate small acceleration disturbances, thus making the raw estimate itself less noisy.

So, looks like I’m still on track. Stay tuned for more!