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 VersionMetadata = 0;
const char VersionBranch[] = "develop";
const char VersionSemVer[] = "0.1.0-develop.8";
const char VersionFullSemVer[] = "0.1.0-develop.8";
const char VersionCommitDate[] = "2020-09-23";
const char VersionSemVer[] = "0.1.0-develop.9";
const char VersionFullSemVer[] = "0.1.0-develop.9";
const char VersionCommitDate[] = "2020-10-09";
#endif

View File

@ -37,9 +37,11 @@ void handleSetRainbow(AsyncWebServerRequest *request)
_dln("API :: set/rainbow");
AsyncWebParameter* speedParam = request->getParam("speed");
AsyncWebParameter* lightnessParam = request->getParam("lightness");
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);
}

View File

@ -27,32 +27,44 @@ void Strip::init(uint16_t ledCount)
void Strip::tick()
{
if (tickMethod != nullptr)
(*this.*tickMethod)();
switch (mSetting)
{
case StripSetting::Static:
case StripSetting::Rainbow:
break;
case StripSetting::RainbowMoving:
tickRainbow();
break;
}
}
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);
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);
mBus->ClearTo(corrected);
this->update();
update();
}
void Strip::setRainbow(uint16_t speed)
void Strip::setRainbow(uint16_t speed, uint8_t lightness)
{
lastTick = currentTime;
delay = (uint32_t)(1000.0F / (float)speed);
tickMethod = speed > 0 ? &Strip::tickRainbow : nullptr;
if (mSetting != StripSetting::Rainbow && mSetting != StripSetting::RainbowMoving)
mRainbowShift = 0;
mSetting = speed > 0 ? StripSetting::RainbowMoving : StripSetting::Rainbow;
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++)
{
@ -62,6 +74,11 @@ void Strip::setRainbow(uint16_t speed)
delete color;
if (mRainbowShift > 0)
mBus->RotateLeft(mRainbowShift);
this->update();
}
@ -77,11 +94,15 @@ void Strip::update()
void Strip::tickRainbow()
{
uint32_t shiftAmount = (currentTime - lastTick) / delay;
if (shiftAmount == 0)
if (currentTime - mLastTick < mDelay)
return;
lastTick = currentTime;
mBus->RotateLeft(shiftAmount);
// TODO for slower speeds it is quite noticable that the pixels simply
// 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();
}

View File

@ -11,24 +11,31 @@
#include "./config.h"
enum StripSetting
{
Static = 0,
Rainbow = 1,
RainbowMoving = 2
};
class Strip
{
private:
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 tickRainbow();
public:
void init(uint16_t ledCount);
void tick();
void setStatic(const RgbwColor color);
void setRainbow(uint16_t speed);
void setRainbow(uint16_t speed, uint8_t lightness);
};
#endif

View File

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

View File

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

View File

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

View File

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

View File

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