Hey folks - i'm looking for a function to gives me a heartbeat effect.

Hey folks - i’m looking for a function to gives me a heartbeat effect.
I can probably hack this together from something that’s already out there in a demo, but wondering if someone had something already done?

Like as below:
(showing a new line for each successive time, with the showing as brightness along the length of a strip)
_ t=0
<i> t=50ms…
/___100ms
/_

_/___200ms
/</i>/<i>

__/_/_300ms
/<i>/_

/_/________400ms
/_/__________etc…

That’s an interesting waveform to replicate. When I started to think about it I overlaid a spreadsheet grid with an EKG waveform image and roughly moved them around until some stuff sort of lined up. Then placed green dots at the waveform/grid intersections. If these values were put into an array it could then be cycled through to represent height (or pulse brightness, etc). But this doesn’t help with timing at all.

I ran across a matlab discussion that had a wave form modeled out, but a quick peek at the .mat script and it looked like a huge mess of code so I moved on.

Then ran across this:
http://www.intmath.com/blog/mathematics/math-of-ecgs-fourier-series-4281
Which made think that if the EKG wave was simplified and broken into two time based pulse equations, then the second one could be time offset from the first and you might get a pretty good EKG representation.

This is an interesting topic.

Matlab coding from this site:
http://www.m-hikari.com/ams/ams-2013/ams-53-56-2013/aidooAMS53-56-2013.pdf

This function is able to generate synthetic electrocardiograms for 10 seconds. We just input heart rate (per minute) value and the desired peak voltage in millivolts.

Here’s how I think about that function:
There’s an ever-repeating cycle that comes around (say) once per second (60BPM, a typical heartrate).

The output waveform is the sum of two single-pulse waveforms with offset timing.

So let’s define what a single-pulse wave looks like, and then we can add two of them. Here’s one way to do that:

For the first X/2 milliseconds, the otuput value of the function rises from zero to some maximum, let’s say 255.

From X/2 ms to X ms, the output value falls from 255 back to 0.

In all other cases, the output value is zero.

SO, something like this pseudocode:

uint8_t pulsewave8( uint32_t ms, uint16_t cyclelength, uint16_t pulselength)
{
uint16_t T = ms % cyclelength;

if( T > pulselength) return 0;

uint16_t halfpulse = pulselength / 2;
if( T <= halfpulse ) {
// first half = going up
return (T * 255) / halfpulse;
} else {
//second half = coming down
return ((pulselength - T) * 255) / halfpulse;
}
}

So if you call it like this:
Y = pulsewave8( millis(), 1000, 100);
you’ll get one 100ms long pulse every 1000ms.

And if you do this:
Y = pulsewave8( millis() + 200, 1000, 100);
you’ll get one 100ms long pulse every 1000ms, but offset 200ms from the first one.

So then you can:
Y1 = pulsewave8( millis(), 1000, 100);
Y2 = pulsewave8( millis() + 200, 1000, 100);
Y = qadd8( Y1, Y2); // add without overflow.

Something like that should work, more or less. None of this has been compiled or tested or run, but it’s a conceptual start.

Marc and Gilligan thanks for the responses I had a good read of the articles you listed.

Mark - Just put yours into into a compiler and it looks good!
I’ve added a time shift thing so that the “history” of the beat turns into a time plot along the length of the LED strip emanating from a middle point . I’m currently not in front of an LED strip, but hopefully this’ll give me something to fix with when I get home.
Thanks a bunch mate! ~ Chris from Melbourne.
I’ll put a video up if I can get this work this arvo :slight_smile:

Here’s a link to the working file if anyone wants to have a crack at it! (sorry no pastebin)
https://drive.google.com/file/d/0B7cesji3QhJ2SUliNEtEVXVrRlE/view?usp=sharing

Working - thanks Mark!

I’ve made it red with a little bit of red in the background and updated the file in the previous link

I just tried it out on a 32 pixel strip. That’s cool. :slight_smile:

A while back I started trying to do something similar, and came up with this simple approach: https://github.com/evilgeniuslabs/plasma/blob/gh-pages/plasma.ino#L430-L440

Looking forward to trying your approach, Mark!