Skip to content

Commit

Permalink
Merge pull request Aircoookie#2601 from Aircoookie/minseg-udp
Browse files Browse the repository at this point in the history
UDP on main segment only.
  • Loading branch information
Aircoookie authored Mar 31, 2022
2 parents 46eae41 + 958cd35 commit d2ced93
Show file tree
Hide file tree
Showing 17 changed files with 2,386 additions and 2,304 deletions.
9 changes: 7 additions & 2 deletions wled00/FX.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@
#define MAX(a,b) ((a)>(b)?(a):(b))
#endif

//color mangling macros
#ifndef RGBW32
#define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b))))
#endif

/* Not used in all effects yet */
#define WLED_FPS 42
#define FRAMETIME_FIXED (1000/WLED_FPS)
Expand Down Expand Up @@ -637,12 +642,13 @@ class WS2812FX {
resetSegments(),
makeAutoSegments(bool forceReset = false),
fixInvalidSegments(),
setPixelColor(uint16_t n, uint32_t c),
setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b, uint8_t w = 0),
show(void),
setTargetFps(uint8_t fps),
deserializeMap(uint8_t n=0);

inline void setPixelColor(uint16_t n, uint32_t c) {setPixelColor(n, byte(c>>16), byte(c>>8), byte(c), byte(c>>24));}

bool
gammaCorrectBri = false,
gammaCorrectCol = true,
Expand Down Expand Up @@ -910,7 +916,6 @@ class WS2812FX {
friend class ColorTransition;

uint16_t
realPixelIndex(uint16_t i),
transitionProgress(uint8_t tNr);

public:
Expand Down
83 changes: 43 additions & 40 deletions wled00/FX_fcn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ void WS2812FX::service() {

for(uint8_t i=0; i < MAX_NUM_SEGMENTS; i++)
{
//if (realtimeMode && useMainSegmentOnly && i == getMainSegmentId()) continue;

_segment_index = i;

// reset the segment runtime data if needed, called before isActive to ensure deleted
Expand Down Expand Up @@ -185,65 +187,60 @@ void WS2812FX::service() {
_triggered = false;
}

void IRAM_ATTR WS2812FX::setPixelColor(uint16_t n, uint32_t c) {
setPixelColor(n, R(c), G(c), B(c), W(c));
}

//used to map from segment index to physical pixel, taking into account grouping, offsets, reverse and mirroring
uint16_t IRAM_ATTR WS2812FX::realPixelIndex(uint16_t i) {
int16_t iGroup = i * SEGMENT.groupLength();

/* reverse just an individual segment */
int16_t realIndex = iGroup;
if (IS_REVERSE) {
if (IS_MIRROR) {
realIndex = (SEGMENT.length() - 1) / 2 - iGroup; //only need to index half the pixels
} else {
realIndex = (SEGMENT.length() - 1) - iGroup;
}
}

realIndex += SEGMENT.start;
return realIndex;
}

void IRAM_ATTR WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
{
if (SEGLEN) {//from segment
uint16_t realIndex = realPixelIndex(i);
uint16_t len = SEGMENT.length();
uint8_t segIdx;

if (SEGLEN) { // SEGLEN!=0 -> from segment/FX
//color_blend(getpixel, col, _bri_t); (pseudocode for future blending of segments)
if (_bri_t < 255) {
r = scale8(r, _bri_t);
g = scale8(g, _bri_t);
b = scale8(b, _bri_t);
w = scale8(w, _bri_t);
}
segIdx = _segment_index;
} else // from live/realtime
segIdx = _mainSegment;

if (SEGLEN || (realtimeMode && useMainSegmentOnly)) {
uint32_t col = RGBW32(r, g, b, w);
uint16_t len = _segments[segIdx].length();

/* Set all the pixels in the group */
for (uint16_t j = 0; j < SEGMENT.grouping; j++) {
uint16_t indexSet = realIndex + (IS_REVERSE ? -j : j);
if (indexSet >= SEGMENT.start && indexSet < SEGMENT.stop) {
if (IS_MIRROR) { //set the corresponding mirrored pixel
uint16_t indexMir = SEGMENT.stop - indexSet + SEGMENT.start - 1;
/* offset/phase */
indexMir += SEGMENT.offset;
if (indexMir >= SEGMENT.stop) indexMir -= len;
// get physical pixel address (taking into account start, grouping, spacing [and offset])
i = i * _segments[segIdx].groupLength();
if (_segments[segIdx].options & REVERSE) { // is segment reversed?
if (_segments[segIdx].options & MIRROR) { // is segment mirrored?
i = (len - 1) / 2 - i; //only need to index half the pixels
} else {
i = (len - 1) - i;
}
}
i += _segments[segIdx].start;

// set all the pixels in the group
for (uint16_t j = 0; j < _segments[segIdx].grouping; j++) {
uint16_t indexSet = i + ((_segments[segIdx].options & REVERSE) ? -j : j);
if (indexSet >= _segments[segIdx].start && indexSet < _segments[segIdx].stop) {

if (_segments[segIdx].options & MIRROR) { //set the corresponding mirrored pixel
uint16_t indexMir = _segments[segIdx].stop - indexSet + _segments[segIdx].start - 1;
indexMir += _segments[segIdx].offset; // offset/phase

if (indexMir >= _segments[segIdx].stop) indexMir -= len;
if (indexMir < customMappingSize) indexMir = customMappingTable[indexMir];

busses.setPixelColor(indexMir, col);
}
/* offset/phase */
indexSet += SEGMENT.offset;
if (indexSet >= SEGMENT.stop) indexSet -= len;
indexSet += _segments[segIdx].offset; // offset/phase

if (indexSet >= _segments[segIdx].stop) indexSet -= len;
if (indexSet < customMappingSize) indexSet = customMappingTable[indexSet];

busses.setPixelColor(indexSet, col);
}
}
} else { //live data, etc.
} else {
if (i < customMappingSize) i = customMappingTable[i];
busses.setPixelColor(i, RGBW32(r, g, b, w));
}
Expand Down Expand Up @@ -508,7 +505,13 @@ uint8_t WS2812FX::getActiveSegmentsNum(void) {

uint32_t WS2812FX::getPixelColor(uint16_t i)
{
i = realPixelIndex(i);
// get physical pixel
i = i * SEGMENT.groupLength();;
if (IS_REVERSE) {
if (IS_MIRROR) i = (SEGMENT.length() - 1) / 2 - i; //only need to index half the pixels
else i = (SEGMENT.length() - 1) - i;
}
i += SEGMENT.start;

if (SEGLEN) {
/* offset/phase */
Expand All @@ -523,7 +526,7 @@ uint32_t WS2812FX::getPixelColor(uint16_t i)
}

WS2812FX::Segment& WS2812FX::getSegment(uint8_t id) {
if (id >= MAX_NUM_SEGMENTS) return _segments[0];
if (id >= MAX_NUM_SEGMENTS) return _segments[getMainSegmentId()];
return _segments[id];
}

Expand Down
2 changes: 2 additions & 0 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {

JsonObject if_live = interfaces["live"];
CJSON(receiveDirect, if_live["en"]);
CJSON(useMainSegmentOnly, if_live[F("mso")]);
CJSON(e131Port, if_live["port"]); // 5568
if (e131Port == DDP_DEFAULT_PORT) e131Port = E131_DEFAULT_PORT; // prevent double DDP port allocation
CJSON(e131Multicast, if_live[F("mc")]);
Expand Down Expand Up @@ -704,6 +705,7 @@ void serializeConfig() {

JsonObject if_live = interfaces.createNestedObject("live");
if_live["en"] = receiveDirect;
if_live[F("mso")] = useMainSegmentOnly;
if_live["port"] = e131Port;
if_live[F("mc")] = e131Multicast;

Expand Down
13 changes: 13 additions & 0 deletions wled00/data/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -864,6 +864,19 @@ input[type=number]::-webkit-outer-spin-button {
right: 8px;
}

.frz {
left: 36px;
position: absolute;
top: 0px;
cursor: pointer;
padding: 8px;
}

/* TODO expanded does not seem to apply to .frz, what is this for? */
.expanded .frz {
display: none;
}

.check, .radio {
display: inline-block;
position: relative;
Expand Down
2 changes: 1 addition & 1 deletion wled00/data/index.htm
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
<div id="Effects" class="tabcontent">
<p class="labels">Effect speed</p>
<div class="staytop">
<i class="icons slider-icon" style="cursor: pointer;" onclick="tglFreeze()">&#xe325;</i>
<i class="icons slider-icon" style="cursor: pointer;" title="Freeze" onclick="tglFreeze()">&#xe325;</i>
<div class="sliderwrap il">
<input id="sliderSpeed" class="noslide" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
<output class="sliderbubble hidden"></output>
Expand Down
10 changes: 8 additions & 2 deletions wled00/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ function populateInfo(i)
function populateSegments(s)
{
var cn = "";
let li = lastinfo;
segCount = 0; lowestUnused = 0; lSeg = 0;

for (var y = 0; y < (s.seg||[]).length; y++)
Expand All @@ -584,6 +585,7 @@ function populateSegments(s)
<input type="checkbox" id="seg${i}sel" onchange="selSeg(${i})" ${inst.sel ? "checked":""}>
<span class="checkmark schk"></span>
</label>
<i class="icons e-icon frz" id="seg${i}frz" onclick="event.preventDefault();tglFreeze(${i});" style="display:${inst.frz?"inline":"none"}">&#x${li.live && li.liveseg==i?'e410':'e325'};</i>
<div class="segname">
<div class="segntxt" onclick="selSegEx(${i})">${inst.n ? inst.n : "Segment "+i}</div>
<i class="icons edit-icon ${expanded[i] ? "expanded":""}" id="seg${i}nedit" onclick="tglSegn(${i})">&#xe2c6;</i>
Expand Down Expand Up @@ -964,7 +966,7 @@ function updateUI()

function displayRover(i,s)
{
d.getElementById('rover').style.transform = (i.live && s.lor == 0) ? "translateY(0px)":"translateY(100%)";
d.getElementById('rover').style.transform = (i.live && s.lor == 0 && i.liveseg<0) ? "translateY(0px)":"translateY(100%)";
var sour = i.lip ? i.lip:""; if (sour.length > 2) sour = " from " + sour;
d.getElementById('lv').innerHTML = `WLED is receiving live ${i.lm} data${sour}`;
d.getElementById('roverstar').style.display = (i.live && s.lor) ? "block":"none";
Expand Down Expand Up @@ -1643,7 +1645,11 @@ function setSegBri(s){
function tglFreeze(s=null)
{
var obj = {"seg": {"frz": "t"}}; // toggle
if (s!==null) obj.id = s;
if (s!==null) {
obj.seg.id = s;
// if live segment, enter live override (which also unfreezes)
if (lastinfo && s==lastinfo.liveseg && lastinfo.live) obj = {"lor":1};
}
requestJson(obj);
}

Expand Down
3 changes: 2 additions & 1 deletion wled00/data/settings_sync.htm
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ <h3>Instance List</h3>
Enable instance list: <input type="checkbox" name="NL"><br>
Make this instance discoverable: <input type="checkbox" name="NB">
<h3>Realtime</h3>
Receive UDP realtime: <input type="checkbox" name="RD"><br><br>
Receive UDP realtime: <input type="checkbox" name="RD"><br>
Use main segment only: <input type="checkbox" name="MO"><br><br>
<i>Network DMX input</i><br>
Type:
<select name=DI onchange="SP(); adj();">
Expand Down
1 change: 1 addition & 0 deletions wled00/fcn_declare.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ bool updateVal(const String* req, const char* key, byte* val, byte minv=0, byte
void notify(byte callMode, bool followUp=false);
uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte *buffer, uint8_t bri=255, bool isRGBW=false);
void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
void exitRealtime();
void handleNotifications();
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
void refreshNodeList();
Expand Down
3 changes: 2 additions & 1 deletion wled00/html_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ Send notifications twice: <input type="checkbox" name="S2"><br><i>
Reboot required to apply changes.</i><h3>Instance List</h3>
Enable instance list: <input type="checkbox" name="NL"><br>
Make this instance discoverable: <input type="checkbox" name="NB"><h3>Realtime
</h3>Receive UDP realtime: <input type="checkbox" name="RD"><br><br><i>
</h3>Receive UDP realtime: <input type="checkbox" name="RD"><br>
Use main segment only: <input type="checkbox" name="MO"><br><br><i>
Network DMX input</i><br>Type: <select name="DI" onchange="SP(),adj()"><option
value="5568">E1.31 (sACN)</option><option value="6454">Art-Net</option><option
value="0" selected="selected">Custom port</option></select><br><div id="xp">
Expand Down
Loading

0 comments on commit d2ced93

Please sign in to comment.