Skip to content

Commit

Permalink
Merge branch 'candle'
Browse files Browse the repository at this point in the history
  • Loading branch information
jiripraus committed Dec 23, 2020
2 parents 9de5e56 + b97ae23 commit 24044dd
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/floower-esp32/automaton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ void Automaton::onLeafTouch(FloowerTouchEvent event) {
if (disabledTouchUp) {
disabledTouchUp = false;
}
else if (floower->isIdle()) {
else if (!floower->arePetalsMoving() && !floower->isChangingColor()) {
if (state == STATE_STANDBY) {
// open + set color
if (!floower->isLit()) {
Expand Down
8 changes: 4 additions & 4 deletions src/floower-esp32/floower-esp32.ino
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void loop() {
periodicOperationsTime = now + PERIODIC_OPERATIONS_INTERVAL;
periodicOperation();
}
if (initRemoteTime != 0 && initRemoteTime < now && floower.isIdle()) {
if (initRemoteTime != 0 && initRemoteTime < now && !floower.arePetalsMoving()) {
initRemoteTime = 0;
remote.init();
remote.startAdvertising();
Expand All @@ -141,7 +141,7 @@ void loop() {
// plan to enter deep sleep in inactivity
if (deepSleepEnabled && !batteryDead) {
// plan to enter deep sleep to save power if floower is in open/dark position & remote is not connected
if (!batteryCharging && !floower.isLit() && floower.isIdle() && floower.getPetalsOpenLevel() == 0 && !remote.isConnected()) {
if (!batteryCharging && !floower.isLit() && !floower.arePetalsMoving() && floower.getPetalsOpenLevel() == 0 && !remote.isConnected()) {
if (deepSleepTime == 0) {
planDeepSleep(DEEP_SLEEP_INACTIVITY_TIMEOUT);
}
Expand All @@ -158,8 +158,8 @@ void loop() {
}
#endif

// save some power when flower is idle
if (floower.isIdle()) {
// save some power when flower is not animating
if (!floower.isAnimating()) {
delay(10);
}
}
Expand Down
37 changes: 26 additions & 11 deletions src/floower-esp32/floower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ unsigned long Floower::touchStartedTime = 0;
unsigned long Floower::touchEndedTime = 0;
unsigned long Floower::lastTouchTime = 0;

const RgbColor candleColor(178, 45, 0); // 36

Floower::Floower(Config *config) : config(config), animations(2), pixels(7, NEOPIXEL_PIN) {}

void Floower::init() {
Expand Down Expand Up @@ -235,6 +237,7 @@ void Floower::setColor(RgbColor color, FloowerColorMode colorMode, int transitio

pixelsColorMode = colorMode;
pixelsTargetColor = color;
interruptiblePixelsAnimation = false;

ESP_LOGI(LOG_TAG, "Color %d,%d,%d", color.R, color.G, color.B);

Expand Down Expand Up @@ -289,12 +292,19 @@ RgbColor Floower::getCurrentColor() {
}

void Floower::startAnimation(FloowerColorAnimation animation) {
interruptiblePixelsAnimation = true;

if (animation == RAINBOW) {
pixelsOriginColor = pixelsColor;
animations.StartAnimation(1, 10000, [=](const AnimationParam& param){ pixelsRainbowAnimationUpdate(param); });
}
else if (animation == CANDLE) {
animations.StartAnimation(1, 10000, [=](const AnimationParam& param){ pixelsCandleAnimationUpdate(param); });
pixelsTargetColor = pixelsColor = RgbColor(candleColor); // candle orange
for (uint8_t i = 0; i < 6; i++) {
candleOriginColors[i] = pixelsTargetColor;
candleTargetColors[i] = pixelsTargetColor;
}
animations.StartAnimation(1, 100, [=](const AnimationParam& param){ pixelsCandleAnimationUpdate(param); });
}
}

Expand Down Expand Up @@ -322,18 +332,19 @@ void Floower::pixelsRainbowAnimationUpdate(const AnimationParam& param) {
}

void Floower::pixelsCandleAnimationUpdate(const AnimationParam& param) {
HsbColor hsbOriginal = HsbColor(pixelsOriginColor);
float hue = hsbOriginal.H + param.progress;
if (hue > 1.0) {
hue = hue - 1;
pixels.SetPixelColor(0, pixelsTargetColor);
for (uint8_t i = 0; i < 6; i++) {
pixels.SetPixelColor(i + 1, RgbColor::LinearBlend(candleOriginColors[i], candleTargetColors[i], param.progress));
}
pixelsColor = RgbColor(HsbColor(hue, 1, 0.4)); // TODO: fine tune
showColor(pixelsColor);

if (param.state == AnimationState_Completed) {
if (pixelsTargetColor.CalculateBrightness() > 0) { // while there is something to show
animations.RestartAnimation(param.index);
HsbColor candleHsbColor = HsbColor(candleColor);
for (uint8_t i = 0; i < 6; i++) {
candleHsbColor.B = random(20, 100) / 100.0;
candleOriginColors[i] = candleTargetColors[i];
candleTargetColors[i] = RgbColor(candleHsbColor);
}
animations.StartAnimation(param.index, random(10, 400), [=](const AnimationParam& param){ pixelsCandleAnimationUpdate(param); });
}
}

Expand All @@ -351,12 +362,16 @@ bool Floower::isLit() {
return pixelsPowerOn;
}

bool Floower::isAnimating() {
return !animations.IsAnimating();
}

bool Floower::arePetalsMoving() {
return animations.IsAnimationActive(0);
}

bool Floower::isIdle() {
return !animations.IsAnimating();
bool Floower::isChangingColor() {
return (!interruptiblePixelsAnimation && animations.IsAnimationActive(1));
}

void Floower::acty() {
Expand Down
10 changes: 8 additions & 2 deletions src/floower-esp32/floower.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,10 @@ class Floower {
RgbColor getCurrentColor();
void startAnimation(FloowerColorAnimation animation);
void stopAnimation(bool retainColor);
bool arePetalsMoving();
bool isLit();
bool isIdle();
bool isAnimating();
bool arePetalsMoving();
bool isChangingColor();

void acty();
Battery readBatteryState();
Expand Down Expand Up @@ -107,6 +108,11 @@ class Floower {
FloowerColorMode pixelsColorMode;
bool pixelsPowerOn;

// leds animations
bool interruptiblePixelsAnimation = false;
RgbColor candleOriginColors[6];
RgbColor candleTargetColors[6];

// touch
FloowerOnLeafTouchCallback touchCallback;
static unsigned long touchStartedTime;
Expand Down
43 changes: 28 additions & 15 deletions src/floower-esp32/remote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,35 +40,37 @@ static const char* LOG_TAG = "Remote";
#define BATTERY_POWER_STATE_DISCHARGING B00101111

// BLE data packets
#define STATE_PACKET_SIZE 4

typedef struct StatePacketData {
byte petalsOpenLevel; // 0-100%, read-write
byte petalsOpenLevel; // normally petals open level 0-100%, read-write
byte R; // 0-255, read-write
byte G; // 0-255, read-write
byte B; // 0-255, read-write

RgbColor getColor() {
return RgbColor(R, G, B);
}
};

#define STATE_PACKET_SIZE 4
typedef union StatePacket {
StatePacketData data;
uint8_t bytes[STATE_PACKET_SIZE];
};

#define STATE_CHANGE_PACKET_SIZE 6

// TODO: define
#define STATE_TRANSITION_MODE_BIT_COLOR 0
#define STATE_TRANSITION_MODE_BIT_PETALS 1
#define STATE_TRANSITION_MODE_BIT_PETALS 1 // when this bit is set, the VALUE parameter means open level of petals (0-100%)
#define STATE_TRANSITION_MODE_BIT_ANIMATION 2 // when this bit is set, the VALUE parameter means ID of animation

typedef struct StateChangePacketData : StatePacketData {
typedef struct StateChangePacketData {
byte value;
byte R; // 0-255, read-write
byte G; // 0-255, read-write
byte B; // 0-255, read-write
byte duration; // 100 of milliseconds
byte mode; // transition mode
byte mode; // 8 flags, see defines above

RgbColor getColor() {
return RgbColor(R, G, B);
}
};

#define STATE_CHANGE_PACKET_SIZE 6
typedef union StateChangePacket {
StateChangePacketData data;
uint8_t bytes[STATE_CHANGE_PACKET_SIZE];
Expand Down Expand Up @@ -189,7 +191,7 @@ void Remote::onTakeOver(RemoteTakeOverCallback callback) {
}

void Remote::setBatteryLevel(uint8_t level, bool charging) {
if (deviceConnected && batteryService != nullptr && floower->isIdle()) {
if (deviceConnected && batteryService != nullptr && !floower->arePetalsMoving()) {
ESP_LOGD(LOG_TAG, "level: %d, charging: %d", level, charging);

BLECharacteristic* characteristic = batteryService->getCharacteristic(BATTERY_LEVEL_UUID);
Expand Down Expand Up @@ -222,7 +224,18 @@ void Remote::StateChangeCharacteristicsCallbacks::onWrite(BLECharacteristic *cha
}
if (CHECK_BIT(statePacket.data.mode, STATE_TRANSITION_MODE_BIT_PETALS)) {
// petals open/close
remote->floower->setPetalsOpenLevel(statePacket.data.petalsOpenLevel, statePacket.data.duration * 100);
remote->floower->setPetalsOpenLevel(statePacket.data.value, statePacket.data.duration * 100);
}
else if (CHECK_BIT(statePacket.data.mode, STATE_TRANSITION_MODE_BIT_ANIMATION)) {
// play animation (according to value)
switch (statePacket.data.value) {
case 1:
remote->floower->startAnimation(FloowerColorAnimation::RAINBOW);
break;
case 2:
remote->floower->startAnimation(FloowerColorAnimation::CANDLE);
break;
}
}

if (remote->takeOverCallback != nullptr) {
Expand Down

0 comments on commit 24044dd

Please sign in to comment.