robust duty cycle capturing with 2138 counter/timer module
2006-03-12 by chazeltopman
Recently, I was porting a bunch of sensor software to a new micro,
the ARM 2138, and most sensors ported smoothly but I ran into a
snag with the 2D accelerometer ADXL202. It has two digital outputs
which vary the duty cycle in relation to the acceleration in two
dimensions. The 2138 provides a timer/counter module for measuring
precisely the time between transitions, rising and falling. Given
a perfect world (granular computer architecture), reading the sensor is
a simple matter of recording the transitions and then doing the math.
The accelerometer was a tough sensor, not because of its signal
or the encoding but because sharing of the CPU sometimes meant
missed transistions. And when you try and capture timestamps for
a rising edge, falling edge and a final rising edge to calculate
duty cycle, if any are missed, the reading is glitched. The
conversion and management of a sensor by means of software can
introduce noise in the signal which is not environmental. The
timer/counter unit can trigger on either or both edges, count
internal or external clock transistions, match an internal timer
count, but it can't capture in hardware 3 sequential counts
without software assistance and that relates its sensor signal
integrity to a whole other thing: the program. With a one cpu
resource and many sensors to take care of, the chance of the
cpu being busy increases to the point that timing commitments
become tough. Granted, more mechanical resource sharing with
overheads and priorities would be one way to solve the problem,
given the right set of circumstances. The other way for the like
thinkers is GCA. One resource dedicated to the sensor and it
will have full integrity and robustness.
Not having a GCA at hand and not wanting to integrate medusa's
organizer into the fray, I tickled my brain for a better solution
which didn't depend on software being there, on-time, all the time.
I toyed with many different ideas but it all boiled down to the
pieces were too simple and they couldn't be connected together.
Instead, I hooked up each input to a second timer capture input where
one captures timestamps on the rising edge while the second one
captures timestamps on the falling edge. This runs in hardware
and generates no interrupts and the difference between the two
counts is either high or low time. A state machine is run which samples
the input by reading the two counters and subtracting second from
the first. If the number is positive, then this is the length of
the high part of the period. If it is negative, then the magnitude
of that is the length of the low part of the period. The duty cycle
of the period which is the tilt of the sensor can be calculated from
the length of the high and low.
This rethink and this algorithm benefited me in many ways:
o 240 lines of souce code reduced to 24 lines of source code
o averaging of the readings reduces jitter in the signal
o very low overhead as the hardware is employed to cache two values
o no glitches since the counts are always valid
TWE