Skip to content

Commit

Permalink
Added basic segment support
Browse files Browse the repository at this point in the history
Updated Espalexa
  • Loading branch information
Aircoookie committed Jun 20, 2019
1 parent b224a67 commit 117dc52
Show file tree
Hide file tree
Showing 10 changed files with 247 additions and 132 deletions.
4 changes: 2 additions & 2 deletions wled00/NpbWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#define NpbWrapper_h

//PIN CONFIGURATION
#define LEDPIN 5 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
#define LEDPIN 2 //strip pin. Any for ESP32, gpio2 or 3 is recommended for ESP8266 (gpio2/3 are labeled D4/RX on NodeMCU and Wemos)
//#define USE_APA102 // Uncomment for using APA102 LEDs.
#define BTNPIN 0 //button pin. Needs to have pullup (gpio0 recommended)
#define IR_PIN 4 //infrared pin (-1 to disable)
#define IR_PIN -1 //infrared pin (-1 to disable)
#define RLYPIN 12 //pin for relay, will be set HIGH if LEDs are on (-1 to disable). Also usable for standby leds, triggers,...
#define AUXPIN -1 //debug auxiliary output pin (-1 to disable)

Expand Down
34 changes: 19 additions & 15 deletions wled00/WS2812FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,13 @@

/* each segment uses 37 bytes of SRAM memory, so if you're application fails because of
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
#define MAX_NUM_SEGMENTS 8
#define MAX_NUM_SEGMENTS 10
#define NUM_COLORS 3 /* number of colors per segment */
#define SEGMENT _segments[_segment_index]
#define SEGCOLOR(x) gamma32(_segments[_segment_index].colors[x])
#define SEGENV _segment_runtimes[_segment_index]
#define SEGLEN SEGMENT.length()
#define SEGACT SEGMENT.stop
#define SPEED_FORMULA_L 5 + (50*(255 - SEGMENT.speed))/SEGLEN
#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes))

Expand Down Expand Up @@ -190,7 +191,15 @@ class WS2812FX {
{
return ((options >> n) & 0x01);
}
inline uint16_t length()
bool isSelected()
{
return getOption(0);
}
bool isActive()
{
return stop > start;
}
uint16_t length()
{
return stop - start;
}
Expand Down Expand Up @@ -289,19 +298,14 @@ class WS2812FX {
_mode[FX_MODE_RIPPLE] = &WS2812FX::mode_ripple;

_brightness = DEFAULT_BRIGHTNESS;
_num_segments = 1;
_segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR;
_segments[0].start = 0;
_segments[0].speed = DEFAULT_SPEED;
currentPalette = CRGBPalette16(CRGB::Black);
targetPalette = CloudColors_p;
ablMilliampsMax = 850;
currentMilliamps = 0;
_locked = nullptr;
_modeUsesLock = false;
bus = new NeoPixelWrapper();
RESET_RUNTIME;
resetSegments();
}

void
Expand All @@ -310,13 +314,12 @@ class WS2812FX {
blur(uint8_t),
fade_out(uint8_t r),
setMode(uint8_t m),
setMode(uint8_t segid, uint8_t m),
setSpeed(uint8_t s),
setIntensity(uint8_t i),
setPalette(uint8_t p),
setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
setColor(uint32_t c),
setSecondaryColor(uint32_t c),
setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
setColor(uint8_t slot, uint32_t c),
setBrightness(uint8_t b),
driverModeCronixie(bool b),
setCronixieDigits(byte* d),
Expand All @@ -337,22 +340,24 @@ class WS2812FX {
show(void);

bool
reverseMode = true,
reverseMode = false,
gammaCorrectBri = false,
gammaCorrectCol = true,
setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p);

uint8_t
returnedSegment = 0,
paletteFade = 0,
paletteBlend = 0,
colorOrder = 0,
getBrightness(void),
getMode(void),
getSpeed(void),
getNumSegments(void),
getModeCount(void),
getPaletteCount(void),
getMaxSegments(void),
getFirstSelectedSegment(void),
getReturnedSegmentId(void),
gamma8(uint8_t),
get_random_wheel_index(uint8_t);

Expand Down Expand Up @@ -506,7 +511,6 @@ class WS2812FX {

uint8_t _segment_index = 0;
uint8_t _segment_index_palette_last = 99;
uint8_t _num_segments = 1;
segment _segments[MAX_NUM_SEGMENTS] = { // SRAM footprint: 21 bytes per element
// start, stop, speed, intensity, palette, mode, options, color[]
{ 0, 7, DEFAULT_SPEED, 128, 0, DEFAULT_MODE, NO_OPTIONS, {DEFAULT_COLOR}}
Expand Down
162 changes: 112 additions & 50 deletions wled00/WS2812FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,19 @@ void WS2812FX::service() {
unsigned long now = millis(); // Be aware, millis() rolls over every 49 days
if (now - _lastShow < MIN_SHOW_DELAY) return;
bool doShow = false;
for(uint8_t i=0; i < _num_segments; i++)
for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
{
_segment_index = i;
if(now > SEGENV.next_time || _triggered)
if (SEGMENT.isActive())
{
doShow = true;
handle_palette();
uint16_t delay = (this->*_mode[SEGMENT.mode])();
SEGENV.next_time = now + max(delay, MIN_SHOW_DELAY);
SEGENV.call++;
if(now > SEGENV.next_time || _triggered || (doShow && SEGMENT.mode == 0)) //last is temporary
{
doShow = true;
handle_palette();
uint16_t delay = (this->*_mode[SEGMENT.mode])();
SEGENV.next_time = now + delay;
SEGENV.call++;
}
}
}
if(doShow) {
Expand Down Expand Up @@ -249,14 +252,24 @@ void WS2812FX::trigger() {
_triggered = true;
}

void WS2812FX::setMode(uint8_t m) {
RESET_RUNTIME;
bool ua = modeUsesLock(_segments[0].mode) && !modeUsesLock(m);
if (m > MODE_COUNT - 1) m = MODE_COUNT - 1;
_segments[0].mode = m;
if (ua) unlockAll();
_modeUsesLock = modeUsesLock(_segments[0].mode);
setBrightness(_brightness);
void WS2812FX::setMode(uint8_t segid, uint8_t m) {
if (segid >= MAX_NUM_SEGMENTS) return;

bool anyUsedLock = _modeUsesLock, anyUseLock = false;
if (m >= MODE_COUNT) m = MODE_COUNT - 1;

if (_segments[segid].mode != m)
{
_segment_runtimes[segid].reset();
_segments[segid].mode = m;
}

for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (modeUsesLock(_segments[i].mode)) anyUseLock = true;
}
if (anyUsedLock && !anyUseLock) unlockAll();
_modeUsesLock = anyUseLock;
}

uint8_t WS2812FX::getModeCount()
Expand All @@ -271,42 +284,64 @@ uint8_t WS2812FX::getPaletteCount()

//TODO transitions

void WS2812FX::setMode(uint8_t m) {
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) setMode(i, m);
}
}

void WS2812FX::setSpeed(uint8_t s) {
_segments[0].speed = s;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) _segments[i].speed = s;
}
}

void WS2812FX::setIntensity(uint8_t in) {
_segments[0].intensity = in;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) _segments[i].intensity = in;
}
}

void WS2812FX::setPalette(uint8_t p) {
_segments[0].palette = p;
}

bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t i, uint8_t p) {
bool changed = false;
m = constrain(m, 0, MODE_COUNT - 1);
if (m != _segments[0].mode) { setMode(m); changed = true; }
if (s != _segments[0].speed) { setSpeed(s); changed = true; }
if (i != _segments[0].intensity) { setIntensity(i); changed = true; }
if (p != _segments[0].palette) { setPalette(p); changed = true; }
return changed;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) _segments[i].palette = p;
}
}

void WS2812FX::setColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
}
bool WS2812FX::setEffectConfig(uint8_t m, uint8_t s, uint8_t in, uint8_t p) {
uint8_t retSeg = getReturnedSegmentId();
Segment& seg = _segments[retSeg];
uint8_t modePrev = seg.mode, speedPrev = seg.speed, intensityPrev = seg.intensity, palettePrev = seg.palette;

void WS2812FX::setSecondaryColor(uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setSecondaryColor(((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected())
{
_segments[i].speed = s;
_segments[i].intensity = in;
_segments[i].palette = p;
setMode(i, m);
}
}

if (seg.mode != modePrev || seg.speed != speedPrev || seg.intensity != intensityPrev || seg.palette != palettePrev) return true;
return false;
}

void WS2812FX::setColor(uint32_t c) {
_segments[0].colors[0] = c;
void WS2812FX::setColor(uint8_t slot, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
setColor(slot, ((uint32_t)w << 24) |((uint32_t)r << 16) | ((uint32_t)g << 8) | b);
}

void WS2812FX::setSecondaryColor(uint32_t c) {
_segments[0].colors[1] = c;
void WS2812FX::setColor(uint8_t slot, uint32_t c) {
if (slot >= NUM_COLORS) return;
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isSelected()) _segments[i].colors[slot] = c;
}
}

void WS2812FX::setBrightness(uint8_t b) {
Expand All @@ -316,27 +351,44 @@ void WS2812FX::setBrightness(uint8_t b) {
}

uint8_t WS2812FX::getMode(void) {
return _segments[0].mode;
return _segments[getReturnedSegmentId()].mode;
}

uint8_t WS2812FX::getSpeed(void) {
return _segments[0].speed;
return _segments[getReturnedSegmentId()].speed;
}

uint8_t WS2812FX::getBrightness(void) {
return _brightness;
}

uint8_t WS2812FX::getNumSegments(void) {
return _num_segments;
}

uint8_t WS2812FX::getMaxSegments(void) {
return MAX_NUM_SEGMENTS;
}

uint8_t WS2812FX::getFirstSelectedSegment(void)
{
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++)
{
if (_segments[i].isActive() && _segments[i].isSelected()) return i;
}
for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) //if none selected, get first active
{
if (_segments[i].isActive()) return i;
}
return 0;
}

uint8_t WS2812FX::getReturnedSegmentId(void) {
if (returnedSegment >= MAX_NUM_SEGMENTS || !_segments[returnedSegment].isActive())
{
return getFirstSelectedSegment();
}
return returnedSegment;
}

uint32_t WS2812FX::getColor(void) {
return _segments[0].colors[0];
return _segments[getReturnedSegmentId()].colors[0];
}

uint32_t WS2812FX::getPixelColor(uint16_t i)
Expand Down Expand Up @@ -392,6 +444,16 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2) {
if (n >= MAX_NUM_SEGMENTS) return;
Segment& seg = _segments[n];
if (seg.start == i1 && seg.stop == i2) return;
if (seg.isActive() && modeUsesLock(seg.mode))
{
_modeUsesLock = false;
unlockRange(seg.start, seg.stop);
_modeUsesLock = true;
}
if (i2 <= i1) //disable segment
{
seg.stop = 0; return;
}
if (i1 < _length) seg.start = i1;
seg.stop = i2;
if (i2 > _length) seg.stop = _length;
Expand All @@ -402,12 +464,12 @@ void WS2812FX::resetSegments() {
memset(_segments, 0, sizeof(_segments));
memset(_segment_runtimes, 0, sizeof(_segment_runtimes));
_segment_index = 0;
_num_segments = 1;
_segments[0].mode = DEFAULT_MODE;
_segments[0].colors[0] = DEFAULT_COLOR;
_segments[0].start = 0;
_segments[0].speed = DEFAULT_SPEED;
_segments[0].stop = _length;
_segments[0].setOption(0, 1); //select
}

void WS2812FX::setIndividual(uint16_t i, uint32_t col)
Expand All @@ -434,28 +496,28 @@ void WS2812FX::setRange(uint16_t i, uint16_t i2, uint32_t col)

void WS2812FX::lock(uint16_t i)
{
if (modeUsesLock(SEGMENT.mode)) return;
if (_modeUsesLock) return;
if (i >= 0 && i < _length) _locked[i] = true;
}

void WS2812FX::lockRange(uint16_t i, uint16_t i2)
{
if (modeUsesLock(SEGMENT.mode)) return;
if (_modeUsesLock) return;
for (uint16_t x = i; x < i2; x++)
{
if (i >= 0 && i < _length) _locked[i] = true;
if (x >= 0 && x < _length) _locked[i] = true;
}
}

void WS2812FX::unlock(uint16_t i)
{
if (modeUsesLock(SEGMENT.mode)) return;
if (_modeUsesLock) return;
if (i >= 0 && i < _length) _locked[i] = false;
}

void WS2812FX::unlockRange(uint16_t i, uint16_t i2)
{
if (modeUsesLock(SEGMENT.mode)) return;
if (_modeUsesLock) return;
for (uint16_t x = i; x < i2; x++)
{
if (x >= 0 && x < _length) _locked[x] = false;
Expand Down
Loading

0 comments on commit 117dc52

Please sign in to comment.