Skip to content

Add background speed control and improve random background animation #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define PERIOD_CLOCK_UPDATE 20
#define PERIOD_LED_UPDATE 100
#define PERIOD_NIGHTMODE_CHECK 20000
#define PERIOD_BACKGROUND_RANDOM 1000
#define PERIOD_BACKGROUND_RANDOM 20

#define EEPROM_SIZE 30 // size of EEPROM to save persistent variables
#define ADR_NM_START_H 0
Expand All @@ -16,6 +16,7 @@
#define ADR_NM_END_M 12
#define ADR_BRIGHTNESS_BACKGROUND 16
#define ADR_BRIGHTNESS_TIME 17
#define ADR_SPEED_BACKGROUND 18
#define ADR_BG_RED 21
#define ADR_BG_GREEN 22
#define ADR_BG_BLUE 23
Expand Down
10 changes: 9 additions & 1 deletion data/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@
}

.show{
height: 240px;
height: 270px;
transition: height 1s;
}

Expand Down Expand Up @@ -284,6 +284,10 @@ <h1 id="headline">DIGITALCLOCK</h1>
<label for="brightnessBackground">Brightness Background:</label>
<input type="range" id="brightnessBackground" name="volume" min="10" max="255">
</div>
<div class="number-container">
<label for="speedBackground">Background Speed:</label>
<input type="range" id="speedBackground" name="volume" min="0.2" max="5" step="0.1">
</div>
<div class="number-container">
<label for="nm_start" style="align-self: flex-start">Nightmode start time: </label>
<input type="time" id="nm_start" name="nm_start" min="00:00" max="23:59">
Expand Down Expand Up @@ -449,6 +453,7 @@ <h1 id="headline">DIGITALCLOCK</h1>
document.getElementById("nm_end").value = myVar.nightModeEnd.replace("-", ":");
document.getElementById("brightnessTime").value = parseInt(myVar.brightnessTime);
document.getElementById("brightnessBackground").value = parseInt(myVar.brightnessBackground);
document.getElementById("speedBackground").value = parseFloat(myVar.speedBackground);

console.log(myVar);
}
Expand All @@ -467,6 +472,7 @@ <h1 id="headline">DIGITALCLOCK</h1>
var nmEnd = document.getElementById("nm_end");
var sld_brightnessTime = document.getElementById("brightnessTime");
var sld_brightnessBackground = document.getElementById("brightnessBackground");
var sld_speedBackground = document.getElementById("speedBackground");
var ckb_resetWifi = document.querySelector('input[id="reset_wifi"]');
var cmdstr = "./cmd?setting=";
cmdstr += nmStart.value.replace(":", "-");
Expand All @@ -476,6 +482,8 @@ <h1 id="headline">DIGITALCLOCK</h1>
cmdstr += sld_brightnessTime.value;
cmdstr += "-";
cmdstr += sld_brightnessBackground.value;
cmdstr += "-";
cmdstr += sld_speedBackground.value;
console.log(cmdstr);
sendCommand(cmdstr);
if(ckb_resetWifi.checked) {
Expand Down
12 changes: 10 additions & 2 deletions data/index_de.html
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@
}

.show{
height: 240px;
height: 270px;
transition: height 1s;
}

Expand Down Expand Up @@ -285,7 +285,11 @@ <h1 id="headline">DIGITALCLOCK</h1>
<input type="range" id="brightnessBackground" name="volume" min="10" max="255">
</div>
<div class="number-container">
<label for="nm_start" style="align-self: flex-start">Nachtmodus Startzeit: </label>
<label for="speedBackground">Hintergrund Geschw.:</label>
<input type="range" id="speedBackground" name="volume" min="0.2" max="5" step="0.1">
</div>
<div class="number-container">
<label for="nm_start" style="align-self: flex-start">Nightmode Startzeit: </label>
<input type="time" id="nm_start" name="nm_start" min="00:00" max="23:59">
</div>
<div class="number-container">
Expand Down Expand Up @@ -447,6 +451,7 @@ <h1 id="headline">DIGITALCLOCK</h1>
document.getElementById("nm_end").value = myVar.nightModeEnd.replace("-", ":");
document.getElementById("brightnessTime").value = parseInt(myVar.brightnessTime);
document.getElementById("brightnessBackground").value = parseInt(myVar.brightnessBackground);
document.getElementById("speedBackground").value = parseFloat(myVar.speedBackground);

console.log(myVar);
}
Expand All @@ -465,6 +470,7 @@ <h1 id="headline">DIGITALCLOCK</h1>
var nmEnd = document.getElementById("nm_end");
var sld_brightnessTime = document.getElementById("brightnessTime");
var sld_brightnessBackground = document.getElementById("brightnessBackground");
var sld_speedBackground = document.getElementById("speedBackground");
var ckb_resetWifi = document.querySelector('input[id="reset_wifi"]');
var cmdstr = "./cmd?setting=";
cmdstr += nmStart.value.replace(":", "-");
Expand All @@ -474,6 +480,8 @@ <h1 id="headline">DIGITALCLOCK</h1>
cmdstr += sld_brightnessTime.value;
cmdstr += "-";
cmdstr += sld_brightnessBackground.value;
cmdstr += "-";
cmdstr += sld_speedBackground.value;
console.log(cmdstr);
sendCommand(cmdstr);
if(ckb_resetWifi.checked) {
Expand Down
17 changes: 15 additions & 2 deletions digitalclock_esp8266.ino
Original file line number Diff line number Diff line change
Expand Up @@ -241,8 +241,9 @@ void loop() {
lastLedStep = millis();
}

if(millis() - lastRandomBackground > PERIOD_BACKGROUND_RANDOM){
if(!ledOff && !nightMode && millis() - lastRandomBackground > PERIOD_BACKGROUND_RANDOM){
segmentClock.randomizeBackground();
ledstrip.drawOnLEDsInstant();
lastRandomBackground = millis();
}

Expand Down Expand Up @@ -403,13 +404,18 @@ void loadBrightnessSettingsFromEEPROM()
{
uint8_t brightnessTime = EEPROM.read(ADR_BRIGHTNESS_TIME);
uint8_t brightnessBackground = EEPROM.read(ADR_BRIGHTNESS_BACKGROUND);
float speedBackground = EEPROM.read(ADR_SPEED_BACKGROUND) / 100.0; // read speed as percentage
if (brightnessTime < 10)
brightnessTime = 10;
if (brightnessBackground < 10)
brightnessBackground = 10;
if (speedBackground < 0.2)
speedBackground = 0.2; // set minimum speed to 0.2
segmentClock.setTimeBrightness(brightnessTime);
segmentClock.setBackgroundBrightness(brightnessBackground);
logger.logString("BrightnessTime: " + String(brightnessTime) + ", BrightnessBackround: " + String(brightnessBackground));
segmentClock.setBackgroundAnimationSpeed(speedBackground);
logger.logString("BrightnessTime: " + String(brightnessTime) + ", BrightnessBackround: " + String(brightnessBackground)
+ ", SpeedBackground: " + String(speedBackground));
}

/**
Expand Down Expand Up @@ -492,24 +498,29 @@ void handleCommand() {
nightModeEndMin = split(timestr, '-', 3).toInt();
uint8_t brightnessTime = split(timestr, '-', 4).toInt();
uint8_t brightnessBackground = split(timestr, '-', 5).toInt();
float speedBackground = split(timestr, '-', 6).toFloat();
if(nightModeStartHour > 23) nightModeStartHour = 22; // set default
if(nightModeStartMin > 59) nightModeStartMin = 0;
if(nightModeEndHour > 23) nightModeEndHour = 7; // set default
if(nightModeEndMin > 59) nightModeEndMin = 0;
if(brightnessTime < 10) brightnessTime = 10;
if(brightnessBackground < 10) brightnessBackground = 10;
if(speedBackground < 0.2) speedBackground = 0.2; // set minimum speed
EEPROM.write(ADR_NM_START_H, nightModeStartHour);
EEPROM.write(ADR_NM_START_M, nightModeStartMin);
EEPROM.write(ADR_NM_END_H, nightModeEndHour);
EEPROM.write(ADR_NM_END_M, nightModeEndMin);
EEPROM.write(ADR_BRIGHTNESS_TIME, brightnessTime);
EEPROM.write(ADR_BRIGHTNESS_BACKGROUND, brightnessBackground);
EEPROM.write(ADR_SPEED_BACKGROUND, (uint8_t)(speedBackground * 100)); // store speed as percentage
EEPROM.commit();
logger.logString("Nightmode starts at: " + String(nightModeStartHour) + ":" + String(nightModeStartMin));
logger.logString("Nightmode ends at: " + String(nightModeEndHour) + ":" + String(nightModeEndMin));
logger.logString("BrightnessTime: " + String(brightnessTime) + ", BrightnessBackground: " + String(brightnessBackground));
logger.logString("SpeedBackground: " + String(speedBackground));
segmentClock.setTimeBrightness(brightnessTime);
segmentClock.setBackgroundBrightness(brightnessBackground);
segmentClock.setBackgroundAnimationSpeed(speedBackground);
lastNightmodeCheck = 0;
}
else if (server.argName(0) == "resetwifi"){
Expand Down Expand Up @@ -577,6 +588,8 @@ void handleDataRequest() {
message += "\"brightnessTime\":\"" + String(segmentClock.getBrightnessTime()) + "\"";
message += ",";
message += "\"brightnessBackground\":\"" + String(segmentClock.getBrightnessBackground()) + "\"";
message += ",";
message += "\"speedBackground\":\"" + String(segmentClock.getBackgroundAnimationSpeed()) + "\"";
}
message += "}";
logger.logString(message);
Expand Down
46 changes: 40 additions & 6 deletions segment_clock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ SegmentClock::SegmentClock(LEDStrip *ledstrip, UDPLogger *logger)
this->ledstrip = ledstrip;
this->logger = logger;
calcBackgroundIds();

speeds = new float[LED_COUNT];
phases = new float[LED_COUNT];

for (int i = 0; i < LED_COUNT; i++)
{
speeds[i] = 0.5 + random(100) / 100.0; // Speeds between 0.5 and 1.5
phases[i] = random(0, 628) / 100.0; // Phase offset between 0 and 2π
}
}

/**
Expand Down Expand Up @@ -75,6 +84,16 @@ void SegmentClock::setBackgroundBrightness(uint8_t brightness)
this->brightness_background = brightness;
}

/**
* @brief Set the speed of the background animation
*
* @param speed speed of the background animation
*/
void SegmentClock::setBackgroundAnimationSpeed(float speed)
{
this->animation_speed = speed;
}

/**
* @brief Get the brightness of the time
*/
Expand All @@ -91,21 +110,36 @@ uint8_t SegmentClock::getBrightnessBackground()
return brightness_background;
}

/**
* @brief Get the speed of the background animation
*/
float SegmentClock::getBackgroundAnimationSpeed()
{
return animation_speed;
}

/**
* @brief Randomize the background of the clock
*/
void SegmentClock::randomizeBackground()
{
for(int i = 0; i < LED_COUNT - 30; i++)
background_time += 0.02 * animation_speed;

for (int i = 0; i < num_background_leds; i++)
{
uint8_t brightness = (random(255) / 255.0) * brightness_background;
// Smooth brightness using sine wave animation
float brightnessFactor = (sin(background_time * speeds[ids_of_background[i]] + phases[ids_of_background[i]]) + 1.0) / 2.0;
uint8_t brightness = brightnessFactor * brightness_background;

uint32_t color = scaleColor(color_background, brightness);
ledstrip->setPixel(ids_of_background[i], color);
ledstrip->setPixel(ids_of_background[i], color);
}

for(int i = 0; i < num_temp_background_leds; i++)
for (int i = 0; i < num_temp_background_leds; i++)
{
uint8_t brightness = (random(255) / 255.0) * brightness_background;
// Smooth brightness using sine wave animation
float brightnessFactor = (sin(background_time * speeds[ids_of_background_temp[i]] + phases[ids_of_background_temp[i]]) + 1.0) / 2.0;
uint8_t brightness = brightnessFactor * brightness_background;

uint32_t color = scaleColor(color_background, brightness);
ledstrip->setPixel(ids_of_background_temp[i], color);
}
Expand Down
16 changes: 13 additions & 3 deletions segment_clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ class SegmentClock{
void setTimeBrightness(uint8_t brightness);
void setBackgroundColor(uint32_t color);
void setBackgroundBrightness(uint8_t brightness);
void setBackgroundAnimationSpeed(float speed);
uint8_t getBrightnessTime();
uint8_t getBrightnessBackground();
float getBackgroundAnimationSpeed();
void randomizeBackground();

private:
Expand All @@ -41,9 +43,17 @@ class SegmentClock{
const uint8_t ids_of_third_segment[7] = {28, 22, 21, 32, 38, 39, 30};
const uint8_t ids_of_fourth_segment[7] = {4, 2, 1, 8, 11, 12, 6};
const uint8_t ids_of_points[2] = {45, 47};
uint8_t ids_of_background[LED_COUNT- 30];
uint8_t ids_of_background_temp[30];
uint8_t num_temp_background_leds = 0;
const static uint8_t num_segment_leds = 30;
const static uint8_t num_background_leds = LED_COUNT - num_segment_leds;
uint8_t num_temp_background_leds = 0; // number of segment leds that are temporarly are part of the background
uint8_t ids_of_background[num_background_leds];
uint8_t ids_of_background_temp[num_segment_leds];

// Animation state for smooth brightness changes
float* speeds; // Array of speed factors for each LED
float* phases; // Array of phase offsets for each LED
float background_time = 0; // Global time for background animation in seconds (updated every 20ms)
float animation_speed = 1.0; // Default speed multiplier (1.0 = normal speed)

uint32_t color_background = LEDStrip::Color24bit(0, 0, 0);
uint32_t color_time = LEDStrip::Color24bit(255, 255, 255);
Expand Down