Sampling
Timing is important to understand. A typical heartbeat
lasts about 3/4 of a second, repeating itself every second or so.
Aiming for a minimum display of 1 complete heartbeat
on the OMP screen 233 pixels wide (while running fleXYlog), this
means capturing a minimum 233 data values per second. Once stored,
they can be played back at any speed. Storage possibilities needed analysis.
233 is close to 256, a typical internal storage capacity for some PIC chips.
But this is always an 8-bit size, where numbers only range from 0 to 255.
For this project, the sampling device needed
to be the familiar 8-pin PIC 12F675 with its internal A/D converter. The
converter is a 10-bit A/D converter, where numbers range 0 to 1023. That
means 2 bytes for each data sample, and 2 x 256 bytes = 512 bytes minimum
storage. Various ideas were considered, most failed due to access times.
233 samples per second means each sample arriving in 1 / 233 = 0.00429
= 4.29 mSecs. So if a modern serial RAM chip needs 11 mSecs to store each
sample, that's no use. Some larger PIC chips do have 512 bytes of faster
RAM, but my PIC chip development kit doesn't handle them.
Eventually the old 2k static RAM, type 6116, seemed an obvious solution. Plenty of bytes: 2048. Fast access: a few nano or micro-seconds. More importantly, I had a supply of them. And they can still be bought - in the UK, around 6 pounds each. The challenge of interfacing a modern PIC chip to an old static RAM chip was attractive.
The A/D PIC is the bottom line. It is only small, with limited code space. With 6 of its 8 pins in use, there was no option for an external timing-crystal, it had to use its internal 4-MHz oscillator. It runs in a fast loop just taking samples and sending them as fast as possible to the next PIC (PIC-A) for processing. It also sends a pulse to PIC-A to indicate a new data value is ready.
It became apparent that running code in Basic
language was too slow. Hence the routines in the PIC chips which handle
this A/D data transfer are in assembly code. In this project, speed
is notched back to permit easier debugging and checking. Sending a 2-byte
sample (at 10 bits per byte) at 19200 speed means 2 x 10 / 19200 = 0.0010416
secs = 1.04 mSecs minimum per sample. Added to this is the A/D conversion
delay, difficult to estimate from the PIC spec-sheet. Studying a 'scope
signal, the total timing delay between two A/D digital samples was measured
to be 6.65 divs x 0.2mS = 0.00133 secs = 1.33 mSecs.
Hence A/D conversion delay: 1.33 - 1.0416 = 288
microseconds. This seems rather large. Perhaps there is some other unknown
coding delay in operation.
In effect, that's a sampling rate of 1 / 0.00133 = 751 samples per second. This is well above the required 233 samples per second needed for the heartbeat.
Storage
Storing 1 data value.
The A/D PIC sends 751 samples per second to PIC-A
which has the task of processing the data.
In the default power-up state, PIC-A takes just
one
data-value (of 2 bytes), stores it, converts it to a decimal number, and
sends it out of the serial port at 1200 bps. PIC-A simply gets the next
data-value and repeats.
This real-time loop takes:
Faster Newton:
(5 bytes x 10 bits/1200 bps) + 80 mS delay per
data value + 1.33 mS wait for the next A/D PIC sample = (50/1200) + 0.08
+ 0.00133 = 0.122 seconds. 1 / 0.122 = 8.2 samples per second.
Slower Newton: (5 x 10/1200) + 300 mSec delay
per data-value + 1.33 mS A/D wait = (50/1200) + 0.3 + 0.00133 = 0.34
seconds. 1 / 0.34 = 2.9 samples per second.
Both these sample rates are much too slow to display a heartbeat in real-time - it needs 233 samples per second. This is why some form of fast storage is needed, with a slower replay.
[ Digression. For a PC instead of a Newton: (50/4800 bps) + 0.00133 A/D wait = 0.0117 seconds. 1 / 0.0117 = 85 samples per second. If a PC can handle 19200 bps on its serial port without dropping bytes: (50/19200) + 0.00133 = 0.0039. 1 / 0.0039 = 254 samples per second. So it should be possible for a PC to show the heartbeat without needing storage. ]
Storing 1024 data values.
The preferred 6116 static RAM can hold 2048 x
8-bit bytes. As 2 bytes are needed for each 10-bit data-value, it can hold
1024 data samples. PIC-A, in this first-generation design, can't quite
store the incoming samples from the A/D PIC in time. There is only a 300
microsecond window (= one bit-period at 19200 bps + A/D conversion delay)
between incoming data-values in which to store the 2-byte data-value in
the RAM chip. PIC-A seems to overrun by some microseconds. In consequence,
it skips alternate data-values.
So the 1024 data-values represent a sampling
period of 1024 x 0.00133 x 2 = 1024 x 0.00266 = 2.72 seconds.
1024 / 2.72 secs = 376. Effectively, a sampling
rate of 376 samples per second. This is still well above the required
233 samples per second needed for the design.
Replay
Although 256 data points (x 2-bytes = 512 storage
bytes) would be adequate to display a heartbeat, it makes sense to use
the full 2048-byte RAM capacity. So the next idea was to store the 1024
x 2-byte samples, and replay them with some noise-reduction signal-processing.
Take a pair of the samples and average them, replaying one averaged
data point instead of 2 raw data points. This should have a small
smoothing-effect on the data. A side-effect of this is to reduce
the sampling frequency by half: 376 / 2 = 188 samples per second.
Of all the maths calculations, this point is
the hardest for Old-Sock R&D to comprehend.
In other words: 1024 original data-values represents
a sampling period of 2.72 seconds. If 2 data-values are averaged, there
are now only 1024 / 2 = 512 data-values, but they still represent the same
time-period of 2.72 seconds. 512 / 2.72 = 188 samples per second.
This is rather less than the design-requirement of 233 samples per second,
but close enough to give useful results.
If these calculations are accurate, there should be 188 pixels per second in the Newton display, whatever model is used.
As it's almost impossible to count pixels, and
easier to measure image details in mm, a 1-second time-period across
the screen becomes:
MP2k: 188 / 427 x width in
mm = 188 / 427 x 110 mm = 48 mm.
OMP: 188 / 233 x width
in mm = 188 / 233 x 69.5 mm = 56 mm.
A useful test to confirm these details is to record
the sound made by a ticking clock.
See these example pictures: MP2k
and OMP.
One aim of these calculations is to estimate the
human pulse-rate by measuring the distance between heartbeats. If the distance
between peaks is e.g. 55 mm on the MP2k screen, the pulse-rate is calculated:
48 mm per sec x 60 secs per minute / 55 mm between
beats = 48 x 60 / 55 = 52 beats per minute.
On the OMP-size screen the same pulse would measure
64 mm: 56 x 60 / 64 = 52 bpm.
(The older-technology OMP Newton has fewer pixels
per inch.)
Some examples of measuring beats per minute on
the MP2k here: one, two.
And an MP110 acoustic heartbeat image where alternate
bytes were dropped:
three.
During the replay of 1024 data samples, the width
of the Newton screen represents a time-period:
For the MP2k:
427 pixel screen-width / 188 pixels = 2.27 seconds.
For the OMP range: 233 pixel screen-width
/ 188 = 1.23
seconds.