mirror of
https://github.com/wled/WLED.git
synced 2025-12-28 19:08:00 +00:00
Compare commits
7 Commits
copilot/fi
...
copilot/re
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dc85a0eaf7 | ||
|
|
7aeee543ef | ||
|
|
96f47e7f71 | ||
|
|
9a066d286f | ||
|
|
1c2cacf185 | ||
|
|
f1f067e93a | ||
|
|
8a2a7054ab |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -25,3 +25,4 @@ wled-update.sh
|
||||
/wled00/Release
|
||||
/wled00/wled00.ino.cpp
|
||||
/wled00/html_*.h
|
||||
_codeql_detected_source_root
|
||||
|
||||
@@ -20,17 +20,19 @@ float UsermodTemperature::readDallas() {
|
||||
}
|
||||
#endif
|
||||
switch(sensorFound) {
|
||||
case 0x10: // DS18S20 has 9-bit precision
|
||||
case 0x10: // DS18S20 has 9-bit precision - 1-bit fraction part
|
||||
result = (data[1] << 8) | data[0];
|
||||
retVal = float(result) * 0.5f;
|
||||
break;
|
||||
case 0x22: // DS18B20
|
||||
case 0x28: // DS1822
|
||||
case 0x22: // DS1822
|
||||
case 0x28: // DS18B20
|
||||
case 0x3B: // DS1825
|
||||
case 0x42: // DS28EA00
|
||||
result = (data[1]<<4) | (data[0]>>4); // we only need whole part, we will add fraction when returning
|
||||
if (data[1] & 0x80) result |= 0xF000; // fix negative value
|
||||
retVal = float(result) + ((data[0] & 0x08) ? 0.5f : 0.0f);
|
||||
// 12-bit precision - 4-bit fraction part
|
||||
result = (data[1] << 8) | data[0];
|
||||
// Clear LSBs to match desired precision (9/10/11-bit) rounding towards negative infinity
|
||||
result &= 0xFFFF << (3 - (resolution & 3));
|
||||
retVal = float(result) * 0.0625f; // 2^(-4)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -69,8 +71,8 @@ bool UsermodTemperature::findSensor() {
|
||||
if (oneWire->crc8(deviceAddress, 7) == deviceAddress[7]) {
|
||||
switch (deviceAddress[0]) {
|
||||
case 0x10: // DS18S20
|
||||
case 0x22: // DS18B20
|
||||
case 0x28: // DS1822
|
||||
case 0x22: // DS1822
|
||||
case 0x28: // DS18B20
|
||||
case 0x3B: // DS1825
|
||||
case 0x42: // DS28EA00
|
||||
DEBUG_PRINTLN(F("Sensor found."));
|
||||
@@ -277,6 +279,7 @@ void UsermodTemperature::addToConfig(JsonObject &root) {
|
||||
top[FPSTR(_parasite)] = parasite;
|
||||
top[FPSTR(_parasitePin)] = parasitePin;
|
||||
top[FPSTR(_domoticzIDX)] = idx;
|
||||
top[FPSTR(_resolution)] = resolution;
|
||||
DEBUG_PRINTLN(F("Temperature config saved."));
|
||||
}
|
||||
|
||||
@@ -304,6 +307,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
|
||||
parasite = top[FPSTR(_parasite)] | parasite;
|
||||
parasitePin = top[FPSTR(_parasitePin)] | parasitePin;
|
||||
idx = top[FPSTR(_domoticzIDX)] | idx;
|
||||
resolution = top[FPSTR(_resolution)] | resolution;
|
||||
|
||||
if (!initDone) {
|
||||
// first run: reading from cfg.json
|
||||
@@ -324,7 +328,7 @@ bool UsermodTemperature::readFromConfig(JsonObject &root) {
|
||||
}
|
||||
}
|
||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||
return !top[FPSTR(_domoticzIDX)].isNull();
|
||||
return !top[FPSTR(_resolution)].isNull();
|
||||
}
|
||||
|
||||
void UsermodTemperature::appendConfigData() {
|
||||
@@ -332,6 +336,14 @@ void UsermodTemperature::appendConfigData() {
|
||||
oappend(F("',1,'<i>(if no Vcc connected)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_parasitePin)).c_str());
|
||||
oappend(F("',1,'<i>(for external MOSFET)</i>');")); // 0 is field type, 1 is actual field
|
||||
oappend(F("dd=addDD('")); oappend(String(FPSTR(_name)).c_str());
|
||||
oappend(F("','")); oappend(String(FPSTR(_resolution)).c_str()); oappend(F("');"));
|
||||
oappend(F("addO(dd,'0.5 °C (9-bit)',0);"));
|
||||
oappend(F("addO(dd,'0.25°C (10-bit)',1);"));
|
||||
oappend(F("addO(dd,'0.125°C (11-bit)',2);"));
|
||||
oappend(F("addO(dd,'0.0625°C (12-bit)',3);"));
|
||||
oappend(F("addInfo('")); oappend(String(FPSTR(_name)).c_str()); oappend(F(":")); oappend(String(FPSTR(_resolution)).c_str());
|
||||
oappend(F("',1,'<i>(ignored on DS18S20)</i>');")); // 0 is field type, 1 is actual field
|
||||
}
|
||||
|
||||
float UsermodTemperature::getTemperature() {
|
||||
@@ -351,6 +363,7 @@ const char UsermodTemperature::_readInterval[] PROGMEM = "read-interval-s";
|
||||
const char UsermodTemperature::_parasite[] PROGMEM = "parasite-pwr";
|
||||
const char UsermodTemperature::_parasitePin[] PROGMEM = "parasite-pwr-pin";
|
||||
const char UsermodTemperature::_domoticzIDX[] PROGMEM = "domoticz-idx";
|
||||
const char UsermodTemperature::_resolution[] PROGMEM = "resolution";
|
||||
const char UsermodTemperature::_sensor[] PROGMEM = "sensor";
|
||||
const char UsermodTemperature::_temperature[] PROGMEM = "temperature";
|
||||
const char UsermodTemperature::_Temperature[] PROGMEM = "/temperature";
|
||||
|
||||
@@ -48,6 +48,7 @@ class UsermodTemperature : public Usermod {
|
||||
|
||||
bool HApublished = false;
|
||||
int16_t idx = -1; // Domoticz virtual sensor idx
|
||||
uint8_t resolution = 0; // 9bits=0, 10bits=1, 11bits=2, 12bits=3
|
||||
|
||||
// strings to reduce flash memory usage (used more than twice)
|
||||
static const char _name[];
|
||||
@@ -56,6 +57,7 @@ class UsermodTemperature : public Usermod {
|
||||
static const char _parasite[];
|
||||
static const char _parasitePin[];
|
||||
static const char _domoticzIDX[];
|
||||
static const char _resolution[];
|
||||
static const char _sensor[];
|
||||
static const char _temperature[];
|
||||
static const char _Temperature[];
|
||||
|
||||
@@ -156,7 +156,7 @@ void ParticleSystem2D::setParticleSize(uint8_t size) {
|
||||
particleHardRadius = PS_P_MINHARDRADIUS + ((particlesize * 52) >> 6); // use 1 pixel + 80% of size for hard radius (slight overlap with boarders so they do not "float" and nicer stacking)
|
||||
}
|
||||
else if (particlesize == 0)
|
||||
particleHardRadius = particleHardRadius >> 1; // single pixel particles have half the radius (i.e. 1/2 pixel)
|
||||
particleHardRadius = PS_P_MINHARDRADIUS >> 1; // single pixel particles have half the radius (i.e. 1/2 pixel)
|
||||
}
|
||||
|
||||
// enable/disable gravity, optionally, set the force (force=8 is default) can be -127 to +127, 0 is disable
|
||||
@@ -595,7 +595,7 @@ void ParticleSystem2D::render() {
|
||||
if (fireIntesity) { // fire mode
|
||||
brightness = (uint32_t)particles[i].ttl * (3 + (fireIntesity >> 5)) + 5;
|
||||
brightness = min(brightness, (uint32_t)255);
|
||||
baseRGB = ColorFromPaletteWLED(SEGPALETTE, brightness, 255, LINEARBLEND_NOWRAP);
|
||||
baseRGB = ColorFromPaletteWLED(SEGPALETTE, brightness, 255, LINEARBLEND_NOWRAP); // map hue to brightness for fire effect
|
||||
}
|
||||
else {
|
||||
brightness = min((particles[i].ttl << 1), (int)255);
|
||||
@@ -842,7 +842,7 @@ void ParticleSystem2D::handleCollisions() {
|
||||
for (uint32_t bin = 0; bin < numBins; bin++) {
|
||||
binParticleCount = 0; // reset for this bin
|
||||
int32_t binStart = bin * binWidth - overlap; // note: first bin will extend to negative, but that is ok as out of bounds particles are ignored
|
||||
int32_t binEnd = binStart + binWidth + overlap; // note: last bin can be out of bounds, see above;
|
||||
int32_t binEnd = binStart + binWidth + (overlap << 1); // add twice the overlap as start is start-overlap, note: last bin can be out of bounds, see above;
|
||||
|
||||
// fill the binIndices array for this bin
|
||||
for (uint32_t i = 0; i < usedParticles; i++) {
|
||||
@@ -879,7 +879,7 @@ void ParticleSystem2D::handleCollisions() {
|
||||
massratio1 = (mass2 << 8) / totalmass; // massratio 1 depends on mass of particle 2, i.e. if 2 is heavier -> higher velocity impact on 1
|
||||
massratio2 = (mass1 << 8) / totalmass;
|
||||
}
|
||||
// note: using the same logic as in 1D is much slower though it would be more accurate but it is not really needed in 2D
|
||||
// note: using the same logic as in 1D is much slower though it would be more accurate but it is not really needed in 2D: particles slipping through each other is much less visible
|
||||
int32_t dx = (particles[idx_j].x + particles[idx_j].vx) - (particles[idx_i].x + particles[idx_i].vx); // distance with lookahead
|
||||
if (dx * dx < collDistSq) { // check x direction, if close, check y direction (squaring is faster than abs() or dual compare)
|
||||
int32_t dy = (particles[idx_j].y + particles[idx_j].vy) - (particles[idx_i].y + particles[idx_i].vy); // distance with lookahead
|
||||
@@ -1247,7 +1247,7 @@ void ParticleSystem1D::setParticleSize(const uint8_t size) {
|
||||
particleHardRadius = PS_P_MINHARDRADIUS_1D + ((particlesize * 52) >> 6); // use 1 pixel + 80% of size for hard radius (slight overlap with boarders so they do not "float" and nicer stacking)
|
||||
}
|
||||
else if (particlesize == 0)
|
||||
particleHardRadius = particleHardRadius >> 1; // single pixel particles have half the radius (i.e. 1/2 pixel)
|
||||
particleHardRadius = PS_P_MINHARDRADIUS_1D >> 1; // single pixel particles have half the radius (i.e. 1/2 pixel)
|
||||
}
|
||||
|
||||
// enable/disable gravity, optionally, set the force (force=8 is default) can be -127 to +127, 0 is disable
|
||||
@@ -1632,7 +1632,7 @@ void ParticleSystem1D::handleCollisions() {
|
||||
for (uint32_t bin = 0; bin < numBins; bin++) {
|
||||
binParticleCount = 0; // reset for this bin
|
||||
int32_t binStart = bin * binWidth - overlap; // note: first bin will extend to negative, but that is ok as out of bounds particles are ignored
|
||||
int32_t binEnd = binStart + binWidth + overlap; // note: last bin can be out of bounds, see above
|
||||
int32_t binEnd = binStart + binWidth + (overlap << 1); // add twice the overlap as start is start-overlap, note: last bin can be out of bounds, see above
|
||||
|
||||
// fill the binIndices array for this bin
|
||||
for (uint32_t i = 0; i < usedParticles; i++) {
|
||||
|
||||
@@ -451,7 +451,7 @@ struct BusConfig {
|
||||
//validates start and length and extends total if needed
|
||||
bool adjustBounds(uint16_t& total) {
|
||||
if (!count) count = 1;
|
||||
if (count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS;
|
||||
if (!Bus::isVirtual(type) && count > MAX_LEDS_PER_BUS) count = MAX_LEDS_PER_BUS;
|
||||
if (start >= MAX_LEDS) return false;
|
||||
//limit length of strip if it would exceed total permissible LEDs
|
||||
if (start + count > MAX_LEDS) count = MAX_LEDS - start;
|
||||
|
||||
@@ -397,11 +397,19 @@ button, .btn {
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="ed active">
|
||||
<div>
|
||||
<h3>Video Lab</h3>
|
||||
<div><small>Stream video and generate animated GIFs (beta)</small></div>
|
||||
<button class="btn" id="t2" style="display:none"></button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="ed active">
|
||||
<div>
|
||||
<h3>PIXEL MAGIC Tool</h3>
|
||||
<div><small>Legacy pixel art editor</small></div>
|
||||
<button class="btn" id="t2" style="display:none"></button>
|
||||
<button class="btn" id="t3" style="display:none"></button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
@@ -439,7 +447,8 @@ let fL; // file list
|
||||
await segLoad(); // load available segments
|
||||
await flU(); // update file list
|
||||
toolChk('pixelpaint.htm','t1'); // update buttons of additional tools
|
||||
toolChk('pxmagic.htm','t2');
|
||||
toolChk('videolab.htm','t2');
|
||||
toolChk('pxmagic.htm','t3');
|
||||
await fsMem(); // show file system memory info
|
||||
})();
|
||||
|
||||
|
||||
@@ -330,33 +330,29 @@
|
||||
}
|
||||
// do we have a led count field
|
||||
if (nm=="LC") {
|
||||
if (!isHub75(t)) {
|
||||
LC.max = isAna(t) ? 1 : (isDig(t) ? maxPB : 16384); // set max value
|
||||
} else {
|
||||
LC.min = undefined;
|
||||
LC.max = undefined;
|
||||
}
|
||||
let c = parseInt(LC.value,10); //get LED count
|
||||
if (!customStarts || !startsDirty[toNum(n)]) gId("ls"+n).value = sLC; //update start value
|
||||
gId("ls"+n).disabled = !customStarts; //enable/disable field editing
|
||||
if (c) {
|
||||
let s = parseInt(gId("ls"+n).value); //start value
|
||||
if (s+c > sLC) sLC = s+c; //update total count
|
||||
if (c > maxLC) maxLC = c; //max per output
|
||||
if (!isVir(t)) sPC += c; //virtual out busses do not count towards physical LEDs
|
||||
if (isDig(t)) {
|
||||
if (c > maxLC) maxLC = c; //max per output
|
||||
sDI += c; // summarize digital LED count
|
||||
let maPL = parseInt(d.Sf["LA"+n].value);
|
||||
if (maPL == 255) maPL = 12;
|
||||
if (maPL == 255) maPL = 12; // wacky WS2815 mode (255 == 12mA per LED)
|
||||
busMA += maPL*c; // summarize maximum bus current (calculated)
|
||||
}
|
||||
} // increase led count
|
||||
return;
|
||||
}
|
||||
// do we have led pins for digital leds
|
||||
if (nm=="L0" || nm=="L1") {
|
||||
if (!isHub75(t)) {
|
||||
d.Sf["LC"+n].max = maxPB; // update max led count value
|
||||
}
|
||||
else {
|
||||
d.Sf["LC"+n].min = undefined;
|
||||
d.Sf["LC"+n].max = undefined;
|
||||
}
|
||||
}
|
||||
// ignore IP address (stored in pins for virtual busses)
|
||||
if (nm.search(/^L[0-3]/) == 0) { // pin fields
|
||||
if (isVir(t)) {
|
||||
|
||||
Reference in New Issue
Block a user