mirror of
https://github.com/wled/WLED.git
synced 2025-07-09 20:06:33 +00:00
Introduce network type (previous virtual)
- phase shifting correction (limit to PWM CCT)
This commit is contained in:
parent
820df0c596
commit
b2e00eb868
@ -427,6 +427,9 @@ BusPwm::BusPwm(BusConfig &bc)
|
||||
#else
|
||||
ledcSetup(_ledcStart + i, _frequency, _depth);
|
||||
ledcAttachPin(_pins[i], _ledcStart + i);
|
||||
// LEDC timer reset credit @dedehai
|
||||
uint8_t group = ((_ledcStart + i) / 8), channel = ((_ledcStart + i) % 8); // _ledcStart + i is always less than MAX_LED_CHANNELS/LEDC_CHANNELS
|
||||
ledc_timer_rst((ledc_mode_t)group, (ledc_channel_t)channel); // reset timer so all timers are almost in sync (for phase shift)
|
||||
#endif
|
||||
}
|
||||
_hasRgb = hasRGB(bc.type);
|
||||
@ -496,29 +499,30 @@ uint32_t BusPwm::getPixelColor(uint16_t pix) const {
|
||||
|
||||
void BusPwm::show() {
|
||||
if (!_valid) return;
|
||||
unsigned numPins = getPins();
|
||||
unsigned maxBri = (1<<_depth) - 1;
|
||||
const unsigned numPins = getPins();
|
||||
const unsigned maxBri = (1<<_depth);
|
||||
// use CIE brightness formula
|
||||
unsigned pwmBri = (unsigned)_bri * 100;
|
||||
if(pwmBri < 2040) pwmBri = ((pwmBri << _depth) + 115043) / 230087; //adding '0.5' before division for correct rounding
|
||||
if (pwmBri < 2040)
|
||||
pwmBri = ((pwmBri << _depth) + 115043) / 230087; //adding '0.5' before division for correct rounding
|
||||
else {
|
||||
pwmBri += 4080;
|
||||
float temp = (float)pwmBri / 29580;
|
||||
temp = temp * temp * temp * (1<<_depth) - 1;
|
||||
temp = temp * temp * temp * maxBri;
|
||||
pwmBri = (unsigned)temp;
|
||||
}
|
||||
// determine phase shift POC (credit @dedehai)
|
||||
[[maybe_unused]] uint32_t phaseOffset = maxBri / numPins;
|
||||
for (unsigned i = 0; i < numPins; i++) {
|
||||
unsigned scaled = (_data[i] * pwmBri) / 255;
|
||||
if (_reversed) scaled = maxBri - scaled;
|
||||
#ifdef ESP8266
|
||||
analogWrite(_pins[i], scaled);
|
||||
#else
|
||||
if (_needsRefresh) { // hacked to determine if phase shifted PWM is requested
|
||||
// CCT blending has to be 0 for phse shift to work (WW & CW must not overlap)
|
||||
if (_type == TYPE_ANALOG_2CH && _needsRefresh && Bus::getCCTBlend() == 0) { // hacked to determine if phase shifted PWM is requested
|
||||
if (scaled >= maxBri/2) scaled = maxBri/2 - 1; // safety check & add dead time of 1 pulse
|
||||
uint8_t group = ((_ledcStart + i) / 8), channel = ((_ledcStart + i) % 8); // _ledcStart + i is always less than MAX_LED_CHANNELS/LEDC_CHANNELS
|
||||
ledc_set_duty_with_hpoint((ledc_mode_t)group, (ledc_channel_t)channel, scaled, phaseOffset*i);
|
||||
ledc_update_duty((ledc_mode_t)group, (ledc_channel_t)channel);
|
||||
ledc_set_duty_and_update((ledc_mode_t)group, (ledc_channel_t)channel, scaled, (maxBri / numPins)*i);
|
||||
} else
|
||||
ledcWrite(_ledcStart + i, scaled);
|
||||
#endif
|
||||
@ -719,8 +723,8 @@ String BusManager::getLEDTypesJSONString(void) {
|
||||
{TYPE_WS2805, "D", PSTR("WS2805 RGBCW")},
|
||||
{TYPE_SM16825, "D", PSTR("SM16825 RGBCW")},
|
||||
{TYPE_WS2812_1CH_X3, "D", PSTR("WS2811 White")},
|
||||
//{TYPE_WS2812_2CH_X3, "D", PSTR("WS2811 CCT")},
|
||||
//{TYPE_WS2812_WWA, "D", PSTR("WS2811 WWA")},
|
||||
//{TYPE_WS2812_2CH_X3, "D", PSTR("WS2811 CCT")}, // not implemented
|
||||
//{TYPE_WS2812_WWA, "D", PSTR("WS2811 WWA")}, // not implemented
|
||||
{TYPE_WS2801, "2P", PSTR("WS2801")},
|
||||
{TYPE_APA102, "2P", PSTR("APA102")},
|
||||
{TYPE_LPD8806, "2P", PSTR("LPD8806")},
|
||||
@ -732,11 +736,15 @@ String BusManager::getLEDTypesJSONString(void) {
|
||||
{TYPE_ANALOG_3CH, "AAA", PSTR("PWM RGB")},
|
||||
{TYPE_ANALOG_4CH, "AAAA", PSTR("PWM RGBW")},
|
||||
{TYPE_ANALOG_5CH, "AAAAA", PSTR("PWM RGB+CCT")},
|
||||
//{TYPE_ANALOG_6CH, "AAAAAA", PSTR("PWM RGB+DCCT")},
|
||||
{TYPE_NET_DDP_RGB, "V", PSTR("DDP RGB (network)")},
|
||||
{TYPE_NET_ARTNET_RGB, "V", PSTR("Art-Net RGB (network)")},
|
||||
{TYPE_NET_DDP_RGBW, "V", PSTR("DDP RGBW (network)")},
|
||||
{TYPE_NET_ARTNET_RGBW, "V", PSTR("Art-Net RGBW (network)")}
|
||||
//{TYPE_ANALOG_6CH, "AAAAAA", PSTR("PWM RGB+DCCT")}, // unimplementable ATM
|
||||
{TYPE_NET_DDP_RGB, "N", PSTR("DDP RGB (network)")},
|
||||
{TYPE_NET_ARTNET_RGB, "N", PSTR("Art-Net RGB (network)")},
|
||||
{TYPE_NET_DDP_RGBW, "N", PSTR("DDP RGBW (network)")},
|
||||
{TYPE_NET_ARTNET_RGBW, "N", PSTR("Art-Net RGBW (network)")},
|
||||
// hypothetical extensions
|
||||
//{TYPE_VIRTUAL_I2C_W, "V", PSTR("I2C White (virtual)")}, // allows setting I2C address in _pin[0]
|
||||
//{TYPE_VIRTUAL_I2C_CCT, "V", PSTR("I2C CCT (virtual)")}, // allows setting I2C address in _pin[0]
|
||||
//{TYPE_VIRTUAL_I2C_RGB, "V", PSTR("I2C RGB (virtual)")}, // allows setting I2C address in _pin[0]
|
||||
};
|
||||
String json = "[";
|
||||
for (const auto &type : types) {
|
||||
|
@ -24,7 +24,8 @@
|
||||
function isAna(t) { return gT(t).t === "" || isPWM(t); } // is analog type
|
||||
function isDig(t) { return gT(t).t === "D" || isD2P(t); } // is digital type
|
||||
function isD2P(t) { return gT(t).t === "2P"; } // is digital 2 pin type
|
||||
function isVir(t) { return gT(t).t === "V"; } // is virtual type
|
||||
function isNet(t) { return gT(t).t === "N"; } // is network type
|
||||
function isVir(t) { return gT(t).t === "V" || isNet(t); } // is virtual type
|
||||
function hasRGB(t) { return !!(gT(t).c & 0x01); } // has RGB
|
||||
function hasW(t) { return !!(gT(t).c & 0x02); } // has white channel
|
||||
function hasCCT(t) { return !!(gT(t).c & 0x04); } // is white CCT enabled
|
||||
@ -202,12 +203,10 @@
|
||||
let len = parseInt(d.getElementsByName("LC"+n)[0].value);
|
||||
len += parseInt(d.getElementsByName("SL"+n)[0].value); // skipped LEDs are allocated too
|
||||
let dbl = 0;
|
||||
let ch = 3;
|
||||
let ch = 3*hasRGB(t) + hasW(t) + hasCCT(t);
|
||||
let mul = 1;
|
||||
if (isDig(t)) {
|
||||
if (is16b(t)) len *= 2; // 16 bit LEDs
|
||||
if (t > 28 && t < 40) ch = 4; //RGBW
|
||||
if (t == 28) ch = 5; //GRBCW
|
||||
if (maxM < 10000 && d.getElementsByName("L0"+n)[0].value == 3) { //8266 DMA uses 5x the mem
|
||||
mul = 5;
|
||||
}
|
||||
@ -216,7 +215,6 @@
|
||||
}
|
||||
if (d.Sf.LD.checked) dbl = len * ch; // double buffering
|
||||
}
|
||||
if (isVir(t) && t == 88) ch = 4;
|
||||
return len * ch * mul + dbl;
|
||||
}
|
||||
|
||||
@ -232,27 +230,36 @@
|
||||
let p1d = "";
|
||||
let off = "Off Refresh";
|
||||
switch (gT(t).t.charAt(0)) {
|
||||
case '2':
|
||||
case '2': // 2 pin digital
|
||||
p1d = "Clock "+p0d;
|
||||
case 'D':
|
||||
// fallthrough
|
||||
case 'D': // digital
|
||||
p0d = "Data "+p0d;
|
||||
break;
|
||||
case 'A':
|
||||
if (gT(t).t.length > 1) {
|
||||
p0d = "GPIOs:";
|
||||
off = "Phase shift";
|
||||
} else gId(`dig${n}f`).style.display = "none";
|
||||
case 'A': // PWM analog
|
||||
switch (gT(t).t.length) { // type length determines number of GPIO used
|
||||
case 1: break;
|
||||
case 2: off = "Phase shift";
|
||||
if (d.Sf["CB"].value != 0) gId(`rf${n}`).checked = 0; // disable phase shifting
|
||||
gId(`rf${n}`).disabled = (d.Sf["CB"].value != 0); // prevent changes
|
||||
// fallthrough
|
||||
default: p0d = "GPIOs:"; break;
|
||||
}
|
||||
// PWM CCT allows phase shifting
|
||||
gId(`dig${n}f`).style.display = (gT(t).t.length != 2) ? "none" : "inline";
|
||||
break;
|
||||
case 'V':
|
||||
case 'N': // network
|
||||
p0d = "IP address:";
|
||||
break;
|
||||
case 'V': // virtual/non-GPIO based
|
||||
p0d = "Config:"
|
||||
break;
|
||||
}
|
||||
gId("p0d"+n).innerText = p0d;
|
||||
gId("p1d"+n).innerText = p1d;
|
||||
gId("off"+n).innerText = off;
|
||||
// secondary pins show/hide (type string length is equivalent to number of pins used; except for virtual and on/off)
|
||||
let pins = gT(t).t.length + 3*isVir(t); // fixes virtual pins to 4
|
||||
if (pins == 0) pins = 1; // fixes on/off pin
|
||||
// secondary pins show/hide (type string length is equivalent to number of pins used; except for network and on/off)
|
||||
let pins = Math.min(gT(t).t.length,1) + 3*isNet(t); // fixes network pins to 4
|
||||
for (let p=1; p<5; p++) {
|
||||
var LK = d.Sf["L"+p+n];
|
||||
if (!LK) continue;
|
||||
@ -909,7 +916,7 @@ Swap: <select id="xw${s}" name="XW${s}">
|
||||
<br>
|
||||
Calculate CCT from RGB: <input type="checkbox" name="CR"><br>
|
||||
CCT IC used (Athom 15W): <input type="checkbox" name="IC"><br>
|
||||
CCT additive blending: <input type="number" class="s" min="0" max="100" name="CB" required> %
|
||||
CCT additive blending: <input type="number" class="s" min="0" max="100" name="CB" onchange="UI()" required> %
|
||||
</div>
|
||||
<h3>Advanced</h3>
|
||||
Palette blending:
|
||||
|
Loading…
x
Reference in New Issue
Block a user