January
2005, Issue 174
Light-to-Frequency
Conversion (Part 2)
Pulse
and Oxygen Content
PROJECT
Let’s
take a closer look at how you can use a TSL230R to monitor
a heart rate. The push buttons allow for manual changes
to the system so you can determine the optimum settings
even during program execution. I predefined PB1 as an
LED toggle between red and IR LEDs. PB2 was predefined
as a Sensitivity mode increment to the TSL230R. PB3
was predefined as a Divisor mode increment to the TSL230R.
I used these inputs to manually change the TSL230R’s
settings and observe the frequency output of the device
for each of the modes. Because these are all based on
the light source, it was convenient to choose between
the two sources for light, the red LED and the IR LED.
These LED colors were chosen because they’re within
the TSL230R’s bandwidth and they have different absorption
characteristics based on the amount of oxygen in the
blood. I tried choosing LED currents that would allow
the LEDs to have similar intensities based on having
no objects between the LEDs and the TSL230R sensor.
The
sensor’s frequency output is connected to the external
interrupt input on a microprocessor. The frequency’s
period is measured by counting timer ticks between any
two consecutive rising edges (interrupts) of the input
signal. Last month I showed you that the best mode to
use would be that which produced the highest count without
overflowing the 16-bit (1 µs/count) counter.
The
maximum count of Timer1 is set at 31.25 ms (or 1/32
s) by reloading with a constant each overflow, and it
becomes the sampling rate. However, if the tick count
exceeds half that value, there is a good chance a count
during a successive sample period will overflow because
the count period of the sensor and the sample times
are asynchronous. So you can trap any count over this
value and assign the 16-bit count an 0xFFFF value, which
indicates a count that’s over the maximum limit (or
a timer overflow, which would also be over that limit).
Just
as the count for a low-frequency output can be too long,
a count can be too short for a high-frequency output.
A short count is limited by how fast the count recovery
routine (interrupt) can be serviced. For obvious reasons,
counts never will be less than this value, but they
could be illegal for counts up to twice this value.
With
the establishment of maximum and minimum count limits,
a sample can be taken while the TSL230R cycles through
each mode to automatically determine the best one to
use (while the sensor is connected to a patient). Mode
selection must be done separately for each LED because
there is no guarantee the LEDs will provide acceptable
counts using the same mode for each.
A
sample output similar to Figure 1 can be recorded at
this point. To help identify the maximum and minimum
sample counts, positive and negative peak detectors
are implemented in code according to certain rules (see
Figure 2). Like a hardware peak detector in which a
voltage passes through a diode to charge a capacitor,
anytime a sample is greater than the last saved maximum
or less than the last saved minimum, it’s saved as the
new maximum or minimum peak (see Figure 3).
|

(Click
here to enlarge)
|
Figure
2—Maximum and minimum samples are held for use when
determining both the number of samples between maximum
peaks (beats per minute) and the ratio of the AC
count and the DC count. |
|

(Click
here to enalrge)
|
Figure
3—Code algorithms in this project act like a hardware
peak detector. The diode allows the capacitor to
charge and hold the highest voltage applied to VIN.
The resister can be sized to slowly leak off the
capacitor’s charge (VCAP). |
To
prevent cases in which there’s a shift downward (or
upward in the case of minimums) because of a change
in DC level or a change in the absorption constant,
and a new maximum peak can’t occur, you must leak off
some charge or allow the maximum to work its way down
(like a resistor discharging the capacitor). To determine
the rate of leakage, find the mean between the maximum
and minimum peaks and then reduce the former (or increase
the latter) by some factor of it.
I
temporarily programmed PB4 to manually cycle this value
by a factor of two each time (1, 2, 4, … 64, 128, 1,
2, etc.). This leakage adjustment recalculates the maximum
and minimum peaks each sample time, except when a new
peak is detected and held until the slope changes state.
I ultimately let the program automatically select the
leakage factor by looking at sample data. Too little
leakage can cause a maximum or minimum peak to be missed
(if the DC level shifts), while too much leakage can
cause the recognition of false peaks.
Referring
to Figure 1, notice how a rising slope changes state
when a sample falls below the leaking minimum value.
The opposite is true for a falling slope: it changes
state when a sample exceeds the leaking maximum value.
Not only is the slope affected by this action, but a
change-of-state (COS) flag is recorded for both a positive
slope [SLOPE=1 (COS_SLOPE1)] and a negative slope [SLOPE=0
(COS_SLOPE0)]. As you can see in Figure 2, special events
occur during the execution of the sampling loop. This
is when the number of beats per minute (bpm) and O2
can be displayed.
The
DoSomething flag is set each time the slope equals one
and the COS_SLOPE0 equals one, which means the slope
has just changed to one. A fortune telling circuit would
be handy because there’s no way of knowing that any
particular peak sample will be the maximum before the
wave’s slope changes. Wait until some point when you
can be sure that this has happened. When a sample value
falls lower than the leaking minimum peak (a slope change),
you can be sure you have the last maximum peak. The
CNT (number of samples since the last determined peak)
is adjusted to reflect the real CNT where the new maximum
peak has occurred, such that it will reference that
new maximum peak the next time the CNT is saved during
a new maximum detection.
The
new maximum peak value is saved. A ratio is calculated
using this new value along with the last minimum peak
value. The ratio is a number that represents the AC
value (the difference between maximum and minimum peak
samples) divided by the DC value (the mean sample).
The ratio is calculated and stored separately during
red and IR LED operations. Because this is the point
in time when a positive peak has indeed occurred, enabling
the piezo beeper will give an audible indication of
such an event. By simply enabling Timer0, background
interrupts from this timer overflowing will allow the
interrupt routine to toggle the piezo output once each
overflow a number of times before disabling itself,
self-completing a short beep. Although some calculations
are performed in this portion of the code, most display
routines are handled at the end of the loop. All display
routines are serial datastreams. Although this project
requires connecting to a PC running HyperTerminal to
see the data, it very easily could be formatted for
a small LCD.