Compare commits

...

2 Commits

Author SHA1 Message Date
Dirk Jahnke f4fbd95183 Fixed writeAllConfigs.
Ignore changes if value does not change.
2019-06-07 09:22:12 +02:00
Dirk Jahnke 30a30b30de Feature: Added blinking when fastclock is halted. Added Magenta and Cyan colors. 2019-06-07 08:42:48 +02:00
4 changed files with 161 additions and 124 deletions

View File

@ -128,11 +128,10 @@ void Config::loadFile(const char *filename, const char * const sectionConfigItem
} }
void Config::writeAllConfigs(void) { void Config::writeAllConfigs(void) {
boolean allChangesWritten = false;
logHeap(); logHeap();
debug.out(F("Write all changed configs, checking ")); debug.out(numberOfConfigItems); debug.outln(F(" items."));
while (!allChangesWritten) {
for (int i=0; i<numberOfConfigItems; ++i) { for (int i=0; i<numberOfConfigItems; ++i) {
debug.out("["); debug.out(i); debug.out("] ");
debug.out(configItems[i].section); debug.out(configItems[i].section);
debug.out("."); debug.out(".");
debug.out(configItems[i].name); debug.out(configItems[i].name);
@ -142,12 +141,9 @@ void Config::writeAllConfigs(void) {
debug.outln(configItems[i].value); debug.outln(configItems[i].value);
if (configItems[i].changed) { if (configItems[i].changed) {
writeConfigFile(configItems[i].section); writeConfigFile(configItems[i].section);
break; // leave for-loop and restart search for changes
} }
} }
// no further changes found, we are done logHeap();
allChangesWritten = true;
}
} }
void Config::writeConfigFile(String filename) { void Config::writeConfigFile(String filename) {
@ -229,9 +225,11 @@ void Config::setString(String key, String value) {
debug.out(F("ERROR: Tried to set new value, but cannot find config item ")); debug.outln(key); debug.out(F("ERROR: Tried to set new value, but cannot find config item ")); debug.outln(key);
} else { } else {
// debug.outln(configItems[index].value); // debug.outln(configItems[index].value);
if (!configItems[index].value.equals(value)) {
configItems[index].value = String(value); configItems[index].value = String(value);
configItems[index].changed = true; configItems[index].changed = true;
} }
}
} }

View File

@ -11,7 +11,9 @@ SevenSegmentClock::colorSelection[] = {
{ Red, "Red", 255, 0, 0 }, { Red, "Red", 255, 0, 0 },
{ Green, "Green", 0, 255, 0 }, { Green, "Green", 0, 255, 0 },
{ White, "White", 255, 255, 255 }, { White, "White", 255, 255, 255 },
{ Yellow, "Yellow", 255, 255, 0 } { Yellow, "Yellow", 255, 255, 0 },
{ Magenta, "Magenta", 255, 0, 255 },
{ Magenta, "Cyan", 0, 255, 255 }
}; };
int SevenSegmentClock::numberOfSupportedColors = sizeof(SevenSegmentClock::colorSelection) / sizeof(SevenSegmentClock::colorSelection[0]); int SevenSegmentClock::numberOfSupportedColors = sizeof(SevenSegmentClock::colorSelection) / sizeof(SevenSegmentClock::colorSelection[0]);
@ -173,23 +175,27 @@ void SevenSegmentClock::displayDigit(unsigned int digitNum, char charToDisplay)
} }
void SevenSegmentClock::displaySeperator(char seperatorCharacter) { void SevenSegmentClock::displaySeperator(char seperatorCharacter) {
displaySeperator(seperatorCharacter, currentColor);
}
void SevenSegmentClock::displaySeperator(char seperatorCharacter, uint32_t color) {
//Serial.print("displaySeperator: seperator="); Serial.println(seperatorCharacter); //Serial.print("displaySeperator: seperator="); Serial.println(seperatorCharacter);
switch (seperatorCharacter) { switch (seperatorCharacter) {
case '.': case '.':
case ',': case ',':
strip->setPixelColor(decimalPointLed, currentColor); strip->setPixelColor(decimalPointLed, color);
strip->setPixelColor(clockSeperatorLed1, black); strip->setPixelColor(clockSeperatorLed1, black);
strip->setPixelColor(clockSeperatorLed2, black); strip->setPixelColor(clockSeperatorLed2, black);
break; break;
case ':': case ':':
strip->setPixelColor(decimalPointLed, black); strip->setPixelColor(decimalPointLed, black);
strip->setPixelColor(clockSeperatorLed1, currentColor); strip->setPixelColor(clockSeperatorLed1, color);
strip->setPixelColor(clockSeperatorLed2, currentColor); strip->setPixelColor(clockSeperatorLed2, color);
break; break;
case '|': case '|':
strip->setPixelColor(decimalPointLed, currentColor); strip->setPixelColor(decimalPointLed, color);
strip->setPixelColor(clockSeperatorLed1, currentColor); strip->setPixelColor(clockSeperatorLed1, color);
strip->setPixelColor(clockSeperatorLed2, currentColor); strip->setPixelColor(clockSeperatorLed2, color);
break; break;
default: default:
Serial.print("SevenSegmentClock::displaySeperator: Unknown character to be displayed: "); Serial.print("SevenSegmentClock::displaySeperator: Unknown character to be displayed: ");
@ -203,6 +209,14 @@ void SevenSegmentClock::displaySeperator(char seperatorCharacter) {
} }
} }
void SevenSegmentClock::displaySeperator(uint32_t color) {
strip->setPixelColor(clockSeperatorLed1, color);
strip->setPixelColor(clockSeperatorLed2, color);
}
void SevenSegmentClock::displayDecimalPoint(uint32_t color) {
strip->setPixelColor(decimalPointLed, color);
}
void SevenSegmentClock::displayTime(int hour, int minute) { void SevenSegmentClock::displayTime(int hour, int minute) {
if (clockHour != hour || clockMinute != minute) { if (clockHour != hour || clockMinute != minute) {
@ -236,7 +250,9 @@ void SevenSegmentClock::displayUpdate(void) {
displayDigit(1, displayText[1]); displayDigit(1, displayText[1]);
displayDigit(2, displayText[2]); displayDigit(2, displayText[2]);
displayDigit(3, displayText[3]); displayDigit(3, displayText[3]);
displaySeperator(':'); //displaySeperator(':');
displaySeperator(currentColor);
displayDecimalPoint(black);
break; break;
case ClockBlinking: case ClockBlinking:
if (currentlyBlinkOn) { if (currentlyBlinkOn) {
@ -244,17 +260,15 @@ void SevenSegmentClock::displayUpdate(void) {
displayDigit(1, displayText[1]); displayDigit(1, displayText[1]);
displayDigit(2, displayText[2]); displayDigit(2, displayText[2]);
displayDigit(3, displayText[3]); displayDigit(3, displayText[3]);
displaySeperator(':'); //displaySeperator(':');
displaySeperator(currentColor);
} else { } else {
displayDigit(0, ' '); displayDigit(0, ' ');
displayDigit(1, ' '); displayDigit(1, ' ');
displayDigit(2, ' '); displayDigit(2, ' ');
displayDigit(3, ' '); displayDigit(3, ' ');
displaySeperator(' '); //displaySeperator(' ');
} displaySeperator(black);
if (millis() > nextBlinkSwitch_ms) {
currentlyBlinkOn = !currentlyBlinkOn;
nextBlinkSwitch_ms = millis() + (currentlyBlinkOn ? BLINK_ON_TIME_ms : BLINK_OFF_TIME_ms);
} }
break; break;
case SeperatorBlinking: case SeperatorBlinking:
@ -263,13 +277,13 @@ void SevenSegmentClock::displayUpdate(void) {
displayDigit(2, displayText[2]); displayDigit(2, displayText[2]);
displayDigit(3, displayText[3]); displayDigit(3, displayText[3]);
if (currentlyBlinkOn) { if (currentlyBlinkOn) {
displaySeperator('|'); //displaySeperator('|');
displaySeperator(currentColor);
displayDecimalPoint(currentColor);
} else { } else {
displaySeperator(' '); //displaySeperator(' ');
} displaySeperator(black);
if (millis() > nextBlinkSwitch_ms) { displayDecimalPoint(black);
currentlyBlinkOn = !currentlyBlinkOn;
nextBlinkSwitch_ms = millis() + (currentlyBlinkOn ? BLINK_ON_TIME_ms : BLINK_OFF_TIME_ms);
} }
break; break;
case DecimalPointBlinking: case DecimalPointBlinking:
@ -278,16 +292,31 @@ void SevenSegmentClock::displayUpdate(void) {
displayDigit(2, displayText[2]); displayDigit(2, displayText[2]);
displayDigit(3, displayText[3]); displayDigit(3, displayText[3]);
if (currentlyBlinkOn) { if (currentlyBlinkOn) {
displaySeperator('.'); //displaySeperator('.');
displayDecimalPoint(currentColor);
} else { } else {
displaySeperator(' '); //displaySeperator(' ');
displayDecimalPoint(black);
}
break;
case DecimalPointColoredBlinking:
displayDigit(0, displayText[0]);
displayDigit(1, displayText[1]);
displayDigit(2, displayText[2]);
displayDigit(3, displayText[3]);
if (currentlyBlinkOn) {
//displaySeperator('.', currentColor);
displayDecimalPoint(currentColor);
} else {
//displaySeperator('.', blinkColor);
displayDecimalPoint(blinkColor);
}
break;
} }
if (millis() > nextBlinkSwitch_ms) { if (millis() > nextBlinkSwitch_ms) {
currentlyBlinkOn = !currentlyBlinkOn; currentlyBlinkOn = !currentlyBlinkOn;
nextBlinkSwitch_ms = millis() + (currentlyBlinkOn ? BLINK_ON_TIME_ms : BLINK_OFF_TIME_ms); nextBlinkSwitch_ms = millis() + (currentlyBlinkOn ? BLINK_ON_TIME_ms : BLINK_OFF_TIME_ms);
} }
break;
}
strip->show(); strip->show();
//Serial.print("Shown: "); Serial.print(displayText[0]); Serial.print(displayText[1]); //Serial.print("Shown: "); Serial.print(displayText[0]); Serial.print(displayText[1]);
//Serial.print(':'); Serial.print(displayText[2]); Serial.println(displayText[3]); //Serial.print(':'); Serial.print(displayText[2]); Serial.println(displayText[3]);
@ -295,35 +324,68 @@ void SevenSegmentClock::displayUpdate(void) {
} }
} }
uint32_t SevenSegmentClock::red, SevenSegmentClock::green, SevenSegmentClock::blue, SevenSegmentClock::white, SevenSegmentClock::black, SevenSegmentClock::yellow;
uint8_t SevenSegmentClock::LedDataPin; uint8_t SevenSegmentClock::LedDataPin;
Adafruit_NeoPixel *SevenSegmentClock::strip; Adafruit_NeoPixel *SevenSegmentClock::strip;
void SevenSegmentClock::initColors(uint8_t _brightness) {
#if 0
SevenSegmentClock::red = strip->Color(_brightness, 0, 0);
SevenSegmentClock::green = strip->Color(0, _brightness, 0);
SevenSegmentClock::blue = strip->Color(0, 0, _brightness);
SevenSegmentClock::white = strip->Color(_brightness, _brightness, _brightness);
SevenSegmentClock::black = strip->Color(0, 0, 0);
SevenSegmentClock::yellow = strip->Color(_brightness, _brightness, 0);
SevenSegmentClock::setColor(SevenSegmentClock::getColor()); // reset color to enforce reclaculation
#endif
}
void SevenSegmentClock::setColor(Color color) { void SevenSegmentClock::setColor(Color color) {
currentColorHandle = color; currentColorHandle = color;
currentColor = getColorByHandle(color); currentColor = getColorByHandle(color);
#if 0 }
switch (currentColorHandle) {
case Black: currentColor = SevenSegmentClock::black; break; void SevenSegmentClock::setBlinkColor(Color color) {
case Blue: currentColor = SevenSegmentClock::blue; break; blinkColorHandle=color;
case Red: currentColor = SevenSegmentClock::red; break; blinkColor=getColorByHandle(color);
case Green: currentColor = SevenSegmentClock::green; break; debug.out(F("setBlinkColor to ")); debug.outln(getColorName(color));
case White: currentColor = SevenSegmentClock::white; break; }
case Yellow: currentColor = SevenSegmentClock::yellow; break;
String SevenSegmentClock::getColorName(Color handle) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].handle == handle)
return colorSelection[i].colorName;
} }
#endif debug.outln(F("ERROR: Unknown color / handle not known"), DEBUG_ERROR);
return String(F("ERROR: Unknown color handle"));
}
SevenSegmentClock::Color SevenSegmentClock::getColorHandle(int index) {
return colorSelection[index].handle;
}
uint32_t SevenSegmentClock::getAdjustedStripColor(uint8_t red, uint8_t green, uint8_t blue) {
return strip->Color((red * brightness) / 255, (green * brightness) / 255, (blue * brightness) / 255);
}
uint32 SevenSegmentClock::getColorByName(String name) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].colorName.equals(name)) {
return getAdjustedStripColor(colorSelection[i].red, colorSelection[i].green, colorSelection[i].blue);
}
}
debug.out(F("ERROR: Unknown color name "), DEBUG_ERROR);
debug.outln(name, DEBUG_ERROR);
return 0xffffffff;
}
uint32 SevenSegmentClock::getColorByHandle(Color handle) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].handle == handle) {
return getAdjustedStripColor(colorSelection[i].red, colorSelection[i].green, colorSelection[i].blue);
}
}
debug.outln(F("ERROR: Unknown color handle"), DEBUG_ERROR);
debug.out(F("Currently I know about ")); debug.out(numberOfSupportedColors); debug.outln(F(" colors."));
return 0xffffffff;
}
SevenSegmentClock::Color SevenSegmentClock::getColorHandleByName(String name) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].colorName.equals(name)) {
return colorSelection[i].handle;
}
}
debug.out(F("ERROR: Unknown color name "), DEBUG_ERROR);
debug.outln(name, DEBUG_ERROR);
return Green; // default
} }
void SevenSegmentClock::begin(void) { void SevenSegmentClock::begin(void) {
@ -332,9 +394,11 @@ void SevenSegmentClock::begin(void) {
Serial.print("Pixels="); Serial.println(PixelCount); Serial.print("Pixels="); Serial.println(PixelCount);
SevenSegmentClock::strip = new Adafruit_NeoPixel(PixelCount, LedDataPin, NEO_GRB + NEO_KHZ800); SevenSegmentClock::strip = new Adafruit_NeoPixel(PixelCount, LedDataPin, NEO_GRB + NEO_KHZ800);
strip->begin(); strip->begin();
setClockHalted(true);
setBrightness(20);
setColor(Green);
setBlinkColor(Red);
black = strip->Color(0, 0, 0);
strip->clear(); strip->clear();
strip->show(); strip->show();
initColors(colorSaturation);
SevenSegmentClock::currentColor = SevenSegmentClock::blue;
SevenSegmentClock::currentColorHandle = SevenSegmentClock::Blue;
} }

View File

@ -7,88 +7,55 @@
// avoid flickering of the display: // avoid flickering of the display:
#define TIME_BETWEEN_DISPLAY_UPDATES_ms 100 #define TIME_BETWEEN_DISPLAY_UPDATES_ms 100
#define BLINK_OFF_TIME_ms 200 #define BLINK_OFF_TIME_ms 400
#define BLINK_ON_TIME_ms 200 #define BLINK_ON_TIME_ms 400
#define defaultLedDataPin 2 #define defaultLedDataPin 2
class SevenSegmentClock { class SevenSegmentClock {
public: public:
SevenSegmentClock(Debug& _debug, Config& _config):debug(_debug), config(_config) { LedDataPin=defaultLedDataPin; init(); }; SevenSegmentClock(Debug& _debug, Config& _config):debug(_debug), config(_config) { LedDataPin=defaultLedDataPin; };
SevenSegmentClock(Debug& _debug, Config& _config, uint8_t dataPin):debug(_debug), config(_config) { LedDataPin=dataPin; init(); }; SevenSegmentClock(Debug& _debug, Config& _config, uint8_t dataPin):debug(_debug), config(_config) { LedDataPin=dataPin; };
void begin(void); void begin(void);
void displayTime(int hour, int minute); void displayTime(int hour, int minute);
void displayUpdate(void); void displayUpdate(void);
//void setClockSpeed(int _msPerModelSecond) { msPerModelSecond = _msPerModelSecond; setClockSpeed("x"); }; //void setClockSpeed(int _msPerModelSecond) { msPerModelSecond = _msPerModelSecond; setClockSpeed("x"); };
enum BlinkMode { NoBlinking, ClockBlinking, SeperatorBlinking, DecimalPointBlinking }; enum BlinkMode { NoBlinking, ClockBlinking, SeperatorBlinking, DecimalPointBlinking, DecimalPointColoredBlinking };
void setBlinkMode(BlinkMode _blinkMode) { blinkMode = _blinkMode; }; void setBlinkMode(BlinkMode _blinkMode) { blinkMode = _blinkMode; };
void setClockHalted(bool halted) { clockHalted = halted; }; void setClockHalted(bool halted) { clockHalted = halted; };
enum Color { Black, Red, Green, Blue, White, Yellow }; enum Color { Black, Red, Green, Blue, White, Yellow, Magenta, Cyan };
void setColor(Color color); void setColor(Color color);
void setBlinkColor(Color color);
Color getColor(void) { return currentColorHandle; }; Color getColor(void) { return currentColorHandle; };
enum ClockDisplayStatus { Off, Booting, Halted, StandardClock, FastClock };
void displayDigit(unsigned int digitNum, char c); void displayDigit(unsigned int digitNum, char c);
void displaySeperator(char seperatorCharacter); void displaySeperator(char seperatorCharacter);
void setBrightness(uint8_t b) { brightness=b; initColors(b); }; void displaySeperator(char seperatorCharacter, uint32_t color);
void displaySeperator(uint32_t color);
void displayDecimalPoint(uint32_t color);
void setBrightness(uint8_t b) { brightness=b; };
uint8_t getBrightness(void) { return brightness; }; uint8_t getBrightness(void) { return brightness; };
int getNumberSupportedColors(void) { return numberOfSupportedColors; }; int getNumberSupportedColors(void) { return numberOfSupportedColors; };
String getColorName(int index) { return String(colorSelection[index].colorName); }; String getColorName(int index) { return String(colorSelection[index].colorName); };
String getColorName(Color handle) { String getColorName(Color handle);
for (int i=0; i<numberOfSupportedColors; ++i) { Color getColorHandle(int index);
if (colorSelection[i].handle == handle) uint32_t getAdjustedStripColor(uint8_t red, uint8_t green, uint8_t blue);
return colorSelection[i].colorName; uint32 getColorByName(String name);
} uint32 getColorByHandle(Color handle);
debug.outln(F("ERROR: Unknown color / handle not known"), DEBUG_ERROR); Color getColorHandleByName(String name);
return String(F("ERROR: Unknown color handle"));
};
Color getColorHandle(int index) { return colorSelection[index].handle; };
uint32_t getAdjustedStripColor(uint8_t red, uint8_t green, uint8_t blue) {
return strip->Color((red * brightness) / 255, (green * brightness) / 255, (blue * brightness) / 255);
}
uint32 getColorByName(String name) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].colorName.equals(name)) {
return getAdjustedStripColor(colorSelection[i].red, colorSelection[i].green, colorSelection[i].blue);
}
}
debug.out(F("ERROR: Unknown color name "), DEBUG_ERROR);
debug.outln(name, DEBUG_ERROR);
return 0xffffffff;
};
uint32 getColorByHandle(Color handle) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].handle == handle) {
return getAdjustedStripColor(colorSelection[i].red, colorSelection[i].green, colorSelection[i].blue);
}
}
debug.outln(F("ERROR: Unknown color handle"), DEBUG_ERROR);
return 0xffffffff;
};
Color getColorHandleByName(String name) {
for (int i=0; i<numberOfSupportedColors; ++i) {
if (colorSelection[i].colorName.equals(name)) {
return colorSelection[i].handle;
}
}
debug.out(F("ERROR: Unknown color name "), DEBUG_ERROR);
debug.outln(name, DEBUG_ERROR);
return Green; // default
};
private: private:
Debug& debug; Debug& debug;
Config& config; Config& config;
void init(void) { displayStatus = Off; clockHour=12; clockMinute=34; setClockHalted(true); currentColorHandle = Green; currentColor = green; };
static uint8_t LedDataPin; static uint8_t LedDataPin;
static Adafruit_NeoPixel *strip; static Adafruit_NeoPixel *strip;
static BlinkMode blinkMode; static BlinkMode blinkMode;
static uint8_t brightness; static uint8_t brightness;
static uint32_t red, green, blue, white, black, yellow;
ClockDisplayStatus displayStatus;
int clockHour; int clockHour;
int clockMinute; int clockMinute;
bool clockHalted; bool clockHalted;
Color currentColorHandle; Color currentColorHandle;
Color blinkColorHandle;
uint32_t currentColor; uint32_t currentColor;
uint32_t blinkColor;
uint32_t black;
void displaySegment(unsigned int ledAddress, uint32_t color); void displaySegment(unsigned int ledAddress, uint32_t color);
void initColors(uint8_t _brightness);
static struct ColorSelection { static struct ColorSelection {
Color handle; Color handle;
String colorName; String colorName;

View File

@ -151,10 +151,18 @@ void loop() {
if (hours % 4 == 0) sevenSegmentClock.setBlinkMode(SevenSegmentClock::SeperatorBlinking); else sevenSegmentClock.setBlinkMode(SevenSegmentClock::NoBlinking); if (hours % 4 == 0) sevenSegmentClock.setBlinkMode(SevenSegmentClock::SeperatorBlinking); else sevenSegmentClock.setBlinkMode(SevenSegmentClock::NoBlinking);
} }
} else if (config.getString("appMode").equals(MODE_REALCLOCK)) { } else if (config.getString("appMode").equals(MODE_REALCLOCK)) {
sevenSegmentClock.setClockHalted(!fastclock.isActive());
sevenSegmentClock.setBlinkMode(SevenSegmentClock::NoBlinking);
sevenSegmentClock.displayTime(timeClient.getHours(), timeClient.getMinutes()); sevenSegmentClock.displayTime(timeClient.getHours(), timeClient.getMinutes());
} else if (config.getString("appMode").equals(MODE_FASTCLOCK)) { } else if (config.getString("appMode").equals(MODE_FASTCLOCK)) {
sevenSegmentClock.setClockHalted(!fastclock.isActive());
if (fastclock.isActive()) {
sevenSegmentClock.setBlinkMode(SevenSegmentClock::NoBlinking);
} else {
sevenSegmentClock.setBlinkMode(SevenSegmentClock::DecimalPointColoredBlinking);
}
sevenSegmentClock.displayTime(fastclock.getClockHours(), fastclock.getClockMinutes()); sevenSegmentClock.displayTime(fastclock.getClockHours(), fastclock.getClockMinutes());
} else { debug.outln("ERROR: Unknown appMode found.", DEBUG_ERROR); } } else { debug.outln(F("ERROR: Unknown appMode found."), DEBUG_ERROR); }
sevenSegmentClock.displayUpdate(); sevenSegmentClock.displayUpdate();
webUI->loop(); webUI->loop();