Skip to content

Commit

Permalink
Effect "Heartbeat" (Aircoookie#680)
Browse files Browse the repository at this point in the history
  • Loading branch information
Def3nder authored Feb 17, 2020
1 parent 61f3002 commit 5befcd2
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 1 deletion.
40 changes: 40 additions & 0 deletions wled00/FX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3119,4 +3119,44 @@ uint16_t WS2812FX::mode_percent(void) {
}

return FRAMETIME;
}

uint16_t WS2812FX::mode_heartbeat(void) {
static unsigned long lastBeat = 0;
static bool secondBeatActive = false;

uint8_t bpm = 40 + (SEGMENT.speed >> 4);
uint32_t msPerBeat = (60000 / bpm);
uint32_t secondBeat = (msPerBeat / 3);

// Get and translate the segment's size option
uint8_t size = 2 << ((SEGMENT.options >> 1) & 0x03); // 2,4,8,16

// copy pixels from the middle of the segment to the edges
uint16_t bytesPerPixelBlock = size * 4;
uint16_t centerOffset = (SEGLEN / 2) * 4;
uint16_t byteCount = centerOffset - bytesPerPixelBlock;
memmove(bus->GetPixels(), bus->GetPixels() + bytesPerPixelBlock, byteCount);
memmove(bus->GetPixels() + centerOffset + bytesPerPixelBlock, bus->GetPixels() + centerOffset, byteCount);

fade_out(255 - SEGMENT.intensity);

unsigned long beatTimer = millis() - lastBeat;
if((beatTimer > secondBeat) && !secondBeatActive) { // time for the second beat?
uint16_t startLed = (SEGLEN / 2) - size;
for (uint16_t i = startLed; i < startLed + (size * 2); i++) {
setPixelColor(i, SEGMENT.colors[0]);
}
secondBeatActive = 1;
}
if(beatTimer > msPerBeat) { // time to reset the beat timer?
uint16_t startLed = (SEGLEN / 2) - size;
for (uint16_t i = startLed; i < startLed + (size * 2); i++) {
setPixelColor(i, SEGMENT.colors[0]);
}
secondBeatActive = 0;
lastBeat = millis();
}

return FRAMETIME;
}
6 changes: 5 additions & 1 deletion wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
#define FX_MODE_PLASMA 97
#define FX_MODE_PERCENT 98
#define FX_MODE_RIPPLE_RAINBOW 99
#define FX_MODE_HEARTBEAT 100

class WS2812FX {
typedef uint16_t (WS2812FX::*mode_ptr)(void);
Expand Down Expand Up @@ -380,6 +381,7 @@ class WS2812FX {
_mode[FX_MODE_DRIP] = &WS2812FX::mode_drip;
_mode[FX_MODE_PLASMA] = &WS2812FX::mode_plasma;
_mode[FX_MODE_PERCENT] = &WS2812FX::mode_percent;
_mode[FX_MODE_HEARTBEAT] = &WS2812FX::mode_heartbeat;
_mode[FX_MODE_RIPPLE_RAINBOW] = &WS2812FX::mode_ripple_rainbow;

_brightness = DEFAULT_BRIGHTNESS;
Expand Down Expand Up @@ -565,6 +567,7 @@ class WS2812FX {
mode_drip(void),
mode_plasma(void),
mode_percent(void),
mode_heartbeat(void);
mode_ripple_rainbow(void);


Expand Down Expand Up @@ -646,7 +649,8 @@ const char JSON_mode_names[] PROGMEM = R"=====([
"Scanner Dual","Stream 2","Oscillate","Pride 2015","Juggle","Palette","Fire 2012","Colorwaves","Bpm","Fill Noise",
"Noise 1","Noise 2","Noise 3","Noise 4","Colortwinkles","Lake","Meteor","Meteor Smooth","Railway","Ripple",
"Twinklefox","Twinklecat","Halloween Eyes","Solid Pattern","Solid Pattern Tri","Spots","Spots Fade","Glitter","Candle","Fireworks Starburst",
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent", "Ripple Rainbow"
"Fireworks 1D","Bouncing Balls","Sinelon","Sinelon Dual","Sinelon Rainbow","Popcorn","Drip","Plasma","Percent","Ripple Rainbow",
"Heartbeat"
])=====";


Expand Down
9 changes: 9 additions & 0 deletions wled00/NpbWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,15 @@ class NeoPixelWrapper
return 0;
}

uint8_t* GetPixels(void)
{
switch (_type) {
case NeoPixelType_Grb: return _pGrb->Pixels(); break;
case NeoPixelType_Grbw: return _pGrbw->Pixels(); break;
}
return 0;
}


private:
NeoPixelType _type;
Expand Down

0 comments on commit 5befcd2

Please sign in to comment.