From 4f28b11cf7a798845dfdf7d7a45d2008056d7f6b Mon Sep 17 00:00:00 2001 From: Dirk Jahnke Date: Tue, 4 Jun 2019 20:41:41 +0200 Subject: [PATCH] Configuration via Web-Interface introduced. Can change color and brightness. --- src/SevenSegmentClock.cpp | 33 ++++-- src/SevenSegmentClock.h | 10 +- src/main.cpp | 235 ++++++++++++++++++++++++++++++++++---- 3 files changed, 247 insertions(+), 31 deletions(-) diff --git a/src/SevenSegmentClock.cpp b/src/SevenSegmentClock.cpp index d7effe4..f0a4354 100644 --- a/src/SevenSegmentClock.cpp +++ b/src/SevenSegmentClock.cpp @@ -112,6 +112,8 @@ static const unsigned char PROGMEM charMapping[] = { /* || */ Seg_a + Seg_c + Seg_e + Seg_g }; +uint8_t SevenSegmentClock::brightness; + void SevenSegmentClock::displaySegment(unsigned int ledAddress, uint32_t color) { //Serial.print("displaySegment led="); Serial.print(ledAddress); Serial.print(" color=0x"); Serial.println(color, HEX); for (int i=0; ishow(); - Serial.print("Shown: "); Serial.print(displayText[0]); Serial.print(displayText[1]); - Serial.print(':'); Serial.print(displayText[2]); Serial.println(displayText[3]); + //Serial.print("Shown: "); Serial.print(displayText[0]); Serial.print(displayText[1]); + //Serial.print(':'); Serial.print(displayText[2]); Serial.println(displayText[3]); lastUpdate_ms = millis(); } } @@ -283,6 +285,26 @@ uint32_t SevenSegmentClock::red, SevenSegmentClock::green, SevenSegmentClock::bl uint8_t SevenSegmentClock::LedDataPin; Adafruit_NeoPixel *SevenSegmentClock::strip; +void SevenSegmentClock::initColors(uint8_t _brightness) { + 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::setColor(SevenSegmentClock::getColor()); // reset color to enforce reclaculation +} + +void SevenSegmentClock::setColor(Color color) { + currentColorHandle = color; + switch (currentColorHandle) { + case Black: currentColor = SevenSegmentClock::black; break; + case Blue: currentColor = SevenSegmentClock::blue; break; + case Red: currentColor = SevenSegmentClock::red; break; + case Green: currentColor = SevenSegmentClock::green; break; + case White: currentColor = SevenSegmentClock::white; break; + } +} + void SevenSegmentClock::begin(void) { Serial.println("Init Neopixels ..."); Serial.print("LED pin="); Serial.println(LedDataPin); @@ -291,10 +313,7 @@ void SevenSegmentClock::begin(void) { strip->begin(); strip->clear(); strip->show(); - SevenSegmentClock::red = strip->Color(colorSaturation, 0, 0); - SevenSegmentClock::green = strip->Color(0, colorSaturation, 0); - SevenSegmentClock::blue = strip->Color(0, 0, colorSaturation); - SevenSegmentClock::white = strip->Color(colorSaturation, colorSaturation, colorSaturation); - SevenSegmentClock::black = strip->Color(0, 0, 0); + initColors(colorSaturation); SevenSegmentClock::currentColor = SevenSegmentClock::blue; + SevenSegmentClock::currentColorHandle = SevenSegmentClock::Blue; } diff --git a/src/SevenSegmentClock.h b/src/SevenSegmentClock.h index 984d524..fc8bf3c 100644 --- a/src/SevenSegmentClock.h +++ b/src/SevenSegmentClock.h @@ -19,20 +19,28 @@ public: enum BlinkMode { NoBlinking, ClockBlinking, SeperatorBlinking, DecimalPointBlinking }; void setBlinkMode(BlinkMode _blinkMode) { blinkMode = _blinkMode; }; void setClockHalted(bool halted) { clockHalted = halted; }; + enum Color { Black, Red, Green, Blue, White }; + void setColor(Color color); + Color getColor(void) { return currentColorHandle; }; static uint32_t red, green, blue, white, black; enum ClockDisplayStatus { Off, Booting, Halted, StandardClock, FastClock }; void displayDigit(unsigned int digitNum, char c); void displaySeperator(char seperatorCharacter); + void setBrightness(uint8_t b) { brightness=b; initColors(b); }; + uint8_t getBrightness(void) { return brightness; }; private: - void init(void) { displayStatus = Off; clockHour=12; clockMinute=34; setClockHalted(true); }; + void init(void) { displayStatus = Off; clockHour=12; clockMinute=34; setClockHalted(true); currentColorHandle = Blue; currentColor = blue; }; static uint8_t LedDataPin; static Adafruit_NeoPixel *strip; static BlinkMode blinkMode; + static uint8_t brightness; ClockDisplayStatus displayStatus; int clockHour; int clockMinute; bool clockHalted; + Color currentColorHandle; uint32_t currentColor; void displaySegment(unsigned int ledAddress, uint32_t color); + void initColors(uint8_t _brightness); }; #endif diff --git a/src/main.cpp b/src/main.cpp index 1f659b6..304a97b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,21 +11,81 @@ #include #include "SevenSegmentClock.h" -#define USE_CONFIG false static const char *appName = "FastclockClient7Seg"; #define MAX_CLOCK_NAME_LEN 16 +#define MAX_CLOCK_CHANNEL_STRING_LEN 3 +#define MAX_CLOCK_COLOR_LEN 16 +#define DEFAULT_CLOCK_NAME "fastclk" +#define DEFAULT_CLOCK_CHANNEL_STRING "1" #define DEFAULT_CLOCK_CHANNEL 1 +#define DEFAULT_CLOCK_COLOR "blue" SevenSegmentClock sevenSegmentClock; +ESP8266WebServer *server; char static_ip[16] = "10.0.1.56"; char static_gw[16] = "10.0.1.1"; char static_sn[16] = "255.255.255.0"; -char clockName[MAX_CLOCK_NAME_LEN+1] = "fastclk"; +static struct ColorSelection { + uint8_t id; + SevenSegmentClock::Color colorHandle; + String colorName; +} colorSelection[] = { + { 1, SevenSegmentClock::Black, "black" }, + { 2, SevenSegmentClock::Blue, "blue" }, + { 3, SevenSegmentClock::Red, "red" }, + { 4, SevenSegmentClock::Green, "green" }, + { 5, SevenSegmentClock::White, "white" } +}; + +static const String getColorName(uint8_t color) { + for (unsigned int i=0; i{v}"; +const char _STYLE[] PROGMEM = ""; +const char _SCRIPT[] PROGMEM = ""; +const char _HEAD_END[] PROGMEM = "
"; +const char _PORTAL_OPTIONS[] PROGMEM = "



"; +const char _ITEM[] PROGMEM = "
{v} {r}%
"; +const char _FORM_START[] PROGMEM = "

"; +const char _FORM_PARAM[] PROGMEM = "
"; +const char _FORM_COLOR_HEADLINE[] PROGMEM = "
Display color:
"; +const char _FORM_COLOR_BLUE[] PROGMEM = "
"; +const char _FORM_COLOR_RED[] PROGMEM = "
"; +const char _FORM_COLOR_GREEN[] PROGMEM = "
"; +const char _FORM_COLOR_WHITE[] PROGMEM = "
"; +const char _FORM_BRIGHTNESS[] PROGMEM = "

"; +const char _FORM_END[] PROGMEM = "
"; +const char _SCAN_LINK[] PROGMEM = "
"; +const char _SAVED[] PROGMEM = "
Credentials Saved
Trying to connect ESP to network.
If it fails reconnect to AP to try again
"; +const char _END[] PROGMEM = "
"; - // put your setup code here, to run once: +void appConfig() { + String page = FPSTR(_HEAD); + String input; + String value; + + page.replace("{v}", "7Seg Config"); + page += FPSTR(_SCRIPT); + page += FPSTR(_STYLE); + //page += _customHeadElement; + page += FPSTR(_HEAD_END); + page += String(F("

")); + page += appName; + page += String(F("

")); + page += String(F("

Clock Options

")); + //page += FPSTR(_PORTAL_OPTIONS); + page += FPSTR(_FORM_START); + page += FPSTR(_FORM_COLOR_HEADLINE); + input = FPSTR(_FORM_COLOR_BLUE); + input.replace("{check}", (clockColor == SevenSegmentClock::Blue) ? "checked" : ""); + page += input; + input = FPSTR(_FORM_COLOR_RED); + input.replace("{check}", (clockColor == SevenSegmentClock::Red) ? "checked" : ""); + page += input; + input = FPSTR(_FORM_COLOR_GREEN); + input.replace("{check}", (clockColor == SevenSegmentClock::Green) ? "checked" : ""); + page += input; + input = FPSTR(_FORM_COLOR_WHITE); + input.replace("{check}", (clockColor == SevenSegmentClock::White) ? "checked" : ""); + page += input; + input = FPSTR(_FORM_BRIGHTNESS); + value = String(sevenSegmentClock.getBrightness()); + input.replace("{bright}", value); + page += input; + + page += FPSTR(_FORM_END); + page += FPSTR(_END); + + server->sendHeader("Content-Length", String(page.length())); + server->send(200, "text/html", page); +} + +void appConfigSave() { + String page = FPSTR(_HEAD); + + Serial.print("appConfigSave "); Serial.print(server->args()); Serial.println(" arguments"); + for (int i=0; iargs(); ++i) { + Serial.print(server->argName(i)); + Serial.print(": "); + Serial.println(server->arg(i)); + } + if (server->hasArg("b")) { + sevenSegmentClock.setBrightness(server->arg("b").toInt()); + } + if (server->hasArg("c")) { + String colorName = server->arg("c"); + SevenSegmentClock::Color colorHandle = getColorHandleByName(server->arg("c")); + sevenSegmentClock.setColor(colorHandle); + } + page.replace("{v}", "7Seg Config"); + page += FPSTR(_SCRIPT); + page += FPSTR(_STYLE); + //page += _customHeadElement; + page += FPSTR(_HEAD_END); + page += String(F("

")); + page += appName; + page += String(F("

")); + page += String(F("
Configuration updated.
")); + page += FPSTR(_END); + server->sendHeader("Content-Length", String(page.length())); + server->send(200, "text/html", page); +} + +void setup() { Serial.begin(115200); + Serial.println("---"); Serial.print("Starting *** "); Serial.println(appName); + Serial.print("Reset reason: "); Serial.println(ESP.getResetReason()); //clean FS, for testing @@ -122,7 +274,6 @@ void setup() { if (SPIFFS.begin()) { Serial.println("mounted file system"); -#if USE_CONFIG if (SPIFFS.exists("/config.json")) { //file exists, reading and loading Serial.println("reading config file"); @@ -134,10 +285,10 @@ void setup() { std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); - DynamicJsonDocument jsonBuffer(2048); - JsonObject json = jsonBuffer.createObject(); - DeserializationError error = deserializeJson(jsonBuffer, json); - serializeJson(json, Serial); + DynamicJsonDocument config(2048); + //JsonObject json = jsonBuffer.createObject(); + DeserializationError error = deserializeJson(config, configFile); + serializeJson(config, Serial); if (!error) { Serial.println("\nparsed json"); @@ -145,6 +296,23 @@ void setup() { //**strcpy(mqtt_port, json["mqtt_port"]); //strcpy(blynk_token, json["blynk_token"]); + if (config["clock_name"]) { + strncpy(clockName, config["clock_name"], MAX_CLOCK_NAME_LEN); + } else { + Serial.println("no clock name in config"); + } + if (config["clock_channel"]) { + strncpy(clockChannelString, config["clock_channel"], MAX_CLOCK_CHANNEL_STRING_LEN); + } else { + Serial.println("no clock channel in config"); + } + if (config["clock_color"]) { + //strncpy(clockColor, config["clock_color"], MAX_CLOCK_COLOR_LEN); + clockColor = getColorHandle(config["clock_color"]); + } else { + Serial.println("no clock color in config"); + } +#if 0 if (json["ip"]) { Serial.print("setting custom ip from config: "); //**strcpy(static_ip, json["ip"]); @@ -157,12 +325,18 @@ void setup() { } else { Serial.println("no custom ip in config"); } +#endif } else { - Serial.println("failed to load json config"); + Serial.println("failed to load json config, using defaults"); + strncpy(clockName, DEFAULT_CLOCK_NAME, MAX_CLOCK_NAME_LEN); + strncpy(clockChannelString, DEFAULT_CLOCK_CHANNEL_STRING, MAX_CLOCK_CHANNEL_STRING_LEN); + //strncpy(clockColor, DEFAULT_CLOCK_COLOR, MAX_CLOCK_COLOR_LEN); + clockColor = SevenSegmentClock::Blue; } } + } else { + Serial.println("no config file found"); } -#endif } else { Serial.println("failed to mount FS"); } @@ -177,7 +351,21 @@ void setup() { fastclock.begin(); pinMode(POWER_OFF_PIN, INPUT); */ + setupWifiConnection(); + + Serial.println("Have following configuration:"); + Serial.print(" Clock name: "); Serial.println(clockName); + Serial.print(" Clock channel: "); Serial.println(clockChannelString); + Serial.print(" Clock color: "); Serial.println(getColorName(clockColor)); + + Serial.println("Starting 7-segment clock display ..."); sevenSegmentClock.begin(); + + // setting up web server for clock configuration + server = new ESP8266WebServer(80); + server->on("/config", HTTP_GET, appConfig); + server->on("/configsave", HTTP_GET, appConfigSave); + server->begin(); } int hours = 0, minutes = 0; @@ -194,4 +382,5 @@ void loop() { if (hours % 4 == 0) sevenSegmentClock.setBlinkMode(SevenSegmentClock::SeperatorBlinking); else sevenSegmentClock.setBlinkMode(SevenSegmentClock::NoBlinking); } sevenSegmentClock.displayUpdate(); + server->handleClient(); }