Monday, 15 February 2016

Heartbeat to Midi, take 3

This project actually finished up sometime in 2013... but due to various forms of procrastination, it is getting written up now.  There is now a project page at http://foulab.org/en/user/strawdog/HeartBeat, complete with a link to video of the device in action. You may want to go there directly.

So in the last post, we had a heartbeat monitoring device that worked quite well, but the beats coming out of it were too irregular to be aesthetically pleasing as music.  We had some debate amongst ourselves about whether this interbeat variability was real, or an effect of the circuitry triggering at slightly different parts of the waveform on each cycle.  In the end, it does not matter.  The rhythm has to be smoothed out for the project to work as intended.

At this point, the problem really became a software one. 

Basically, the heart beat device software has a fast interrupt service routine that captures, as accurately as possible, the heartbeat pulse timing.  This is used to adjust the interbeat delay.  The main loop then emits a beat whenever this delay has expired from the last time a beat was emitted.   The actual calculations are performed in relatively idle times between these two events.

Testing showed that the main loop was nearly always taking less than a millisecond, so the Arduino's speed did not seem to be a critical factor.

My first attempts used various kinds of smoothing on the interbeat delay.  However, even with this, there was audible variability over the short term.  I also tried rejecting outlier observations and a few other nonlinear tricks, but audible problems remained (although simple outlier rejection remains in the final result to avoid "double beats").

Eventually I realized that the human ear wants stability in the pulses.  So I chose a new strategy.  The heart beat rate must fall on one of a set of stable rates, and, it must not change back and forth between these rates too rapidly.  Arbitrarily, I chose multiples of 5bpm.  There is also hysteresis in the changing between these rates.  To change from one rate to another, the computed interbeat delay is averaged over the last 12 beats and must move more than 80% of the way to the next bpm rate before the switch is made.

Two LED's were placed on the box - one to indicate detection of the heartbeat, and one to indicate the output of the note.  First tests were very promising - so a model two was made, using an Arduino Nano instead of a Diecimila, and a 9V instead of AA batteries conserved some space, so the whole thing fit in an Altoids tin.