Added lightness option for rainbow effect

Added UI for rainbow effect
This commit is contained in:
Mark van Renswoude 2020-10-09 21:20:19 +02:00
parent 16743c505d
commit eefe7c2b77
10 changed files with 1323 additions and 1208 deletions

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,8 @@ const uint8_t VersionMinor = 1;
const uint8_t VersionPatch = 0; const uint8_t VersionPatch = 0;
const uint8_t VersionMetadata = 0; const uint8_t VersionMetadata = 0;
const char VersionBranch[] = "develop"; const char VersionBranch[] = "develop";
const char VersionSemVer[] = "0.1.0-develop.8"; const char VersionSemVer[] = "0.1.0-develop.9";
const char VersionFullSemVer[] = "0.1.0-develop.8"; const char VersionFullSemVer[] = "0.1.0-develop.9";
const char VersionCommitDate[] = "2020-09-23"; const char VersionCommitDate[] = "2020-10-09";
#endif #endif

View File

@ -37,9 +37,11 @@ void handleSetRainbow(AsyncWebServerRequest *request)
_dln("API :: set/rainbow"); _dln("API :: set/rainbow");
AsyncWebParameter* speedParam = request->getParam("speed"); AsyncWebParameter* speedParam = request->getParam("speed");
AsyncWebParameter* lightnessParam = request->getParam("lightness");
uint16_t speed = speedParam == nullptr ? 0 : speedParam->value().toInt(); uint16_t speed = speedParam == nullptr ? 0 : speedParam->value().toInt();
strip->setRainbow(speed); uint8_t lightness = lightnessParam == nullptr ? 0 : lightnessParam->value().toInt();
strip->setRainbow(speed, lightness);
request->send(200); request->send(200);
} }

View File

@ -27,32 +27,44 @@ void Strip::init(uint16_t ledCount)
void Strip::tick() void Strip::tick()
{ {
if (tickMethod != nullptr) switch (mSetting)
(*this.*tickMethod)(); {
case StripSetting::Static:
case StripSetting::Rainbow:
break;
case StripSetting::RainbowMoving:
tickRainbow();
break;
}
} }
void Strip::setStatic(const RgbwColor color) void Strip::setStatic(const RgbwColor color)
{ {
tickMethod = nullptr; mSetting = StripSetting::Static;
_d("Strip :: setStatic, color = "); _d(color.R); _d(","); _d(color.G); _d(","); _d(color.B); _d(","); _dln(color.W); _d("Strip :: setStatic, color = "); _d(color.R); _d(","); _d(color.G); _d(","); _d(color.B); _d(","); _dln(color.W);
RgbwColor corrected = colorGamma.Correct(color); RgbwColor corrected = colorGamma.Correct(color);
_d("Strip :: setStatic, gamma corrected = "); _d(corrected.R); _d(","); _d(corrected.G); _d(","); _d(corrected.B); _d(","); _dln(corrected.W); _d("Strip :: setStatic, gamma corrected = "); _d(corrected.R); _d(","); _d(corrected.G); _d(","); _d(corrected.B); _d(","); _dln(corrected.W);
mBus->ClearTo(corrected); mBus->ClearTo(corrected);
this->update(); update();
} }
void Strip::setRainbow(uint16_t speed) void Strip::setRainbow(uint16_t speed, uint8_t lightness)
{ {
lastTick = currentTime; if (mSetting != StripSetting::Rainbow && mSetting != StripSetting::RainbowMoving)
delay = (uint32_t)(1000.0F / (float)speed); mRainbowShift = 0;
tickMethod = speed > 0 ? &Strip::tickRainbow : nullptr;
mSetting = speed > 0 ? StripSetting::RainbowMoving : StripSetting::Rainbow;
uint16_t ledCount = systemSettings->ledCount(); uint16_t ledCount = systemSettings->ledCount();
HslColor* color = new HslColor(0, 1, 0.5); mDelay = speed > 0 ? (uint32_t)(1000.0F / (float)speed) : 0;
mLastTick = currentTime;
HslColor* color = new HslColor(0, 1, (float)lightness / 255.0F);
for (uint16_t ledIndex = 0; ledIndex < ledCount; ledIndex++) for (uint16_t ledIndex = 0; ledIndex < ledCount; ledIndex++)
{ {
@ -62,6 +74,11 @@ void Strip::setRainbow(uint16_t speed)
delete color; delete color;
if (mRainbowShift > 0)
mBus->RotateLeft(mRainbowShift);
this->update(); this->update();
} }
@ -77,11 +94,15 @@ void Strip::update()
void Strip::tickRainbow() void Strip::tickRainbow()
{ {
uint32_t shiftAmount = (currentTime - lastTick) / delay; if (currentTime - mLastTick < mDelay)
if (shiftAmount == 0)
return; return;
lastTick = currentTime; // TODO for slower speeds it is quite noticable that the pixels simply
mBus->RotateLeft(shiftAmount); // shift. Figure out where the pivot point for that is, and switch to
// a smoother (but more calculation intensive) variant
mRainbowShift = (mRainbowShift + 1) % systemSettings->ledCount();
mLastTick = currentTime;
mBus->RotateLeft(1);
this->update(); this->update();
} }

View File

@ -11,24 +11,31 @@
#include "./config.h" #include "./config.h"
enum StripSetting
{
Static = 0,
Rainbow = 1,
RainbowMoving = 2
};
class Strip class Strip
{ {
private: private:
NeoPixelBus<NeoPixelBusFeature, NeoPixelBusMethod>* mBus; NeoPixelBus<NeoPixelBusFeature, NeoPixelBusMethod>* mBus;
void(Strip::*tickMethod)() = nullptr;
uint32_t lastTick;
uint32_t delay; StripSetting mSetting;
uint32_t mLastTick;
uint32_t mDelay;
uint16_t mRainbowShift;
void update(); void update();
void tickRainbow(); void tickRainbow();
public: public:
void init(uint16_t ledCount); void init(uint16_t ledCount);
void tick(); void tick();
void setStatic(const RgbwColor color); void setStatic(const RgbwColor color);
void setRainbow(uint16_t speed); void setRainbow(uint16_t speed, uint8_t lightness);
}; };
#endif #endif

View File

@ -27,8 +27,7 @@ export default {
if (this.disabled) if (this.disabled)
return; return;
this.value = !this.value; this.$emit('input', !this.value);
this.$emit('input', this.value);
}, },
handleKeyDown(event) handleKeyDown(event)

View File

@ -25,8 +25,7 @@ export default {
if (this.disabled) if (this.disabled)
return; return;
this.value = this.id; this.$emit('input', this.id);
this.$emit('input', this.value);
}, },
handleKeyDown(event) handleKeyDown(event)

View File

@ -32,7 +32,14 @@ export default {
tabTitle: 'Status', tabTitle: 'Status',
title: 'Current status', title: 'Current status',
staticOff: 'Off' static: 'Static color',
staticOff: 'Off',
rainbow: {
title: 'Rainbow',
speed: 'Speed (LEDs/second)',
lightness: 'Lightness'
}
}, },
connection: { connection: {

View File

@ -32,7 +32,14 @@ export default {
tabTitle: 'Status', tabTitle: 'Status',
title: 'Huidige status', title: 'Huidige status',
staticOff: 'Uit' static: 'Vaste kleur',
staticOff: 'Uit',
rainbow: {
title: 'Regenboog',
speed: 'Snelheid (LEDs/seconde)',
lightness: 'Helderheid'
}
}, },
connection: { connection: {

View File

@ -7,6 +7,8 @@
</div> </div>
<div v-else> <div v-else>
<Radio :title="$i18n.t('status.static')" v-model="type" id="static"></Radio>
<div class="slidercontainer"> <div class="slidercontainer">
<input type="range" min="0" max="255" class="slider red" v-model.number="static.r"> <input type="range" min="0" max="255" class="slider red" v-model.number="static.r">
</div> </div>
@ -23,6 +25,18 @@
<div class="buttons"> <div class="buttons">
<a class="button button-secondary" @click.prevent="staticOff">{{ $t('status.staticOff') }}</a> <a class="button button-secondary" @click.prevent="staticOff">{{ $t('status.staticOff') }}</a>
</div> </div>
<Radio :title="$i18n.t('status.rainbow.title')" v-model="type" id="rainbow"></Radio>
<p>{{ $i18n.t('status.rainbow.speed') }}</p>
<div class="slidercontainer">
<input type="range" min="0" max="200" class="slider white" v-model.number="rainbow.speed">
</div>
<p>{{ $i18n.t('status.rainbow.lightness') }}</p>
<div class="slidercontainer">
<input type="range" min="0" max="255" class="slider white" v-model.number="rainbow.lightness">
</div>
</div> </div>
</div> </div>
</template> </template>
@ -31,18 +45,22 @@
import axios from 'axios'; import axios from 'axios';
import LoadingIndicator from '@/components/loadingIndicator.vue'; import LoadingIndicator from '@/components/loadingIndicator.vue';
import BaseVM from '@/BaseVM'; import BaseVM from '@/BaseVM';
import Radio from '@/components/radio.vue';
export default { export default {
mixins: [BaseVM], mixins: [BaseVM],
components: { components: {
LoadingIndicator LoadingIndicator,
Radio
}, },
data() data()
{ {
return { return {
static: null type: 'static',
static: null,
rainbow: null
} }
}, },
@ -51,16 +69,25 @@ export default {
{ {
const self = this; const self = this;
self.disableSetStatic = false; self.updating = false;
self.setStaticTimer = false; self.updateTimer = false;
self.load() self.load()
.then(() => .then(() =>
{ {
self.$watch('static', () => self.$watch(
{ () =>
self.staticChanged(); {
}, { deep: true }); return [
this.type,
this.static.r, this.static.g, this.static.b, this.static.w,
this.rainbow.speed, this.rainbow.lightness
];
},
() =>
{
self.changed();
});
}); });
}, },
@ -78,6 +105,11 @@ export default {
w: 0 w: 0
}; };
self.rainbow = {
speed: 0,
lightness: 128
};
return Promise.resolve(true); return Promise.resolve(true);
}, },
@ -93,45 +125,65 @@ export default {
}, },
staticChanged() changed()
{ {
const self = this; const self = this;
console.log(self.setStaticTimer);
if (self.setStaticTimer === false) if (self.updateTimer === false)
self.setStaticTimer = setTimeout(() => self.updateTimer = setTimeout(() =>
{ {
self.setStatic(); self.update();
}, 200); }, 200);
}, },
setStatic() update()
{ {
console.log(this.type);
const self = this; const self = this;
if (self.settingStatic) if (self.updating)
{ {
self.setStaticTimer = setTimeout(() => self.updateTimer = setTimeout(() =>
{ {
self.setStatic(); self.update();
}, 200); }, 200);
return; return;
} }
self.settingStatic = true;
self.setStaticTimer = false; let url;
let params;
switch (this.type)
{
case 'static':
url = '/api/set/static';
params = this.static;
break;
case 'rainbow':
url = '/api/set/rainbow';
params = this.rainbow;
break;
default:
return;
}
axios.get('/api/set/static', { params: this.static }) self.updating = true;
self.updateTimer = false;
axios.get(url, { params: params })
.then(response => .then(response =>
{ {
}) })
.catch(e => self.handleAPIError('error.setColor', e)) .catch(e => self.handleAPIError('error.setColor', e))
.then(() => .then(() =>
{ {
self.settingStatic = false; self.updating = false;
}); });
} }
} }