#include "time.h" #include #define _TASK_SLEEP_ON_IDLE_RUN //ToDo check benefit #include #include #include // UpdateServer includes #ifdef ESP8266 #include # include #include #define MYTZ TZ_Europe_Berlin #include // settimeofday_cb() //#include //#include #include // struct timeval #include // sntp_servermode_dhcp() #elif defined(ESP32) #include // For ESP32 IotWebConf provides a drop-in replacement for UpdateServer. # include #include #endif #define MOD(a,b) ((((a)%(b))+(b))%(b)) /* Model I LDR (GL5516 ) is connected to GPIO 34 (Analog ADC1_CH6, 12bit resolution default Light Resistance (at 10 Lux): 5-10 Kohm Dark Resistance: 0.5 Mohm over a 56k voltage divider . Dark (0.5MOhm) , 10Lux (5-10kOhm) ----------------- ESP8266 24LED 5V--10k-+-LDR--GND -ADC - 150k--220k-+-100k--GND ----------------- ESP8266 60LED 5V--??k-+-LDR--??k-GND - 39k--220k-+-100k--GND -ADC */ #ifdef ESP8266 #define LDR_PIN A0 #define IOTWEBCONF_DEBUG_DISABLED #define DATA_PIN D7 //DMA RDX0/GPIO3 | Uart1 TXD1/GPIO2 | UART0 GPIO1 #elif defined(ESP32) #define LDR_PIN A6 #define DATA_PIN 17 #endif /* useful preselection NO following hour NO three block hour marking quarter hour marking */ #define NUM_LEDS 60 //24 #define SERIAL_BAUD 115200 #define RGBW const bool clockwiseRing = false; volatile bool singleSecond = false; //show seconds volatile bool allDotsOn = true; //lighten up all leds #if NUM_LEDS == 60 volatile bool followingHour = true; //move hour like an analog one #else volatile bool followingHour = false; //disabled due limited resolution #endif volatile int hourOffset = 0; void bootAnimCallback(); void clockTickCallback(); void ledRefreshCallback(); void brightnessAdjustmentCallback(); void iotWebConfLoopCallback(); #ifdef RGBW #define MINIMAL_BRIGHTNESS 5 #define LDR_SCALE 16 #define colorSaturation 255 #ifdef ESP8266 //NeoPixelBrightnessBus strip(NUM_LEDS);//RDX0 GPIO3 //NeoPixelBrightnessBus strip(NUM_LEDS); //NeoPixelBrightnessBus strip(NUM_LEDS); NeoPixelBrightnessBus strip(NUM_LEDS, DATA_PIN); #elif defined(ESP32) NeoPixelBrightnessBus strip(NUM_LEDS, DATA_PIN); //ESP32 #endif RgbwColor red(colorSaturation, 0, 0, 0); RgbwColor green(0, colorSaturation, 0, 0); RgbwColor blue(0, 0, colorSaturation, 0); RgbwColor realWhite(colorSaturation); RgbwColor white(0, 0, 0, 40); //darkish dirt RgbwColor whiter(0, 0, 0, 120); //darkish dirt RgbwColor white12(0, 0, 0, 192); //darkish dirt RgbwColor black(0); RgbwColor gold(HtmlColor( 0xFFD700 ) ); RgbwColor orangered(HtmlColor( 0xFF4500 ) ); RgbwColor orange(HtmlColor( 0xFFA500 ) ); RgbwColor darkred(HtmlColor( 0x800000) ); RgbwColor darkgreen(HtmlColor( 0x006400) ); RgbwColor lightgreen(HtmlColor( 0x30ee30) ); RgbwColor temp; RgbwColor secondsColor = black; RgbwColor minuteColor = darkred; RgbwColor hourColor = gold; RgbwColor highnoonColor = white12; RgbwColor backlightColor = white; RgbwColor hourMarkingColor = whiter; void transformtoHtmlColor (char* sOutput, RgbwColor* inputColor) { //Serial.printf("InputColor: R:%i G:%i B:%i W:%i\n", inputColor.R, inputColor.G, inputColor.B, inputColor.W); if (inputColor->IsMonotone()) { //Serial.print("White: "); Serial.println(inputColor->W); HtmlColor(RgbColor(inputColor->W, inputColor->W, inputColor->W)).ToNumericalString(sOutput, 12); //Serial.println((char*)sOutput); } else { //Serial.print("Color: "); Serial.print(inputColor->R); Serial.print(inputColor->G); Serial.println(inputColor->B); HtmlColor(RgbColor(inputColor->R, inputColor->G, inputColor->B)).ToNumericalString(sOutput, 12); //Serial.println((char*)sOutput); } } void transformHtmltoStrip(RgbwColor* outputColor, char* sInput) { HtmlColor htmlTemp; //Serial.print("HtmltoStrip "); //Serial.println((char*)sInput); htmlTemp.Parse( sInput ); RgbwColor stripColor( htmlTemp ); //Serial.printf("StripColor: R:%i G:%i B:%i W:%i\n", stripColor.R, stripColor.G, stripColor.B, stripColor.W); memcpy(outputColor, &stripColor, sizeof(stripColor)); } #else #define MINIMAL_BRIGHTNESS 20 #define LDR_SCALE 16 #define colorSaturation 192 #ifdef ESP8266 //NeoPixelBrightnessBus strip(NUM_LEDS);//RDX0 GPIO3 Broken due IoTWebConf NeoPixelBrightnessBus strip(NUM_LEDS); //NeoPixelBrightnessBus strip(NUM_LEDS, DATA_PIN); #elif defined(ESP32) NeoPixelBrightnessBus strip(NUM_LEDS, DATA_PIN); //ESP32 #endif RgbColor red(colorSaturation, 0, 0); RgbColor green(0, colorSaturation, 0); RgbColor blue(0, 0, colorSaturation); RgbColor realWhite(colorSaturation); RgbColor black(0); RgbColor white(30, 40, 35); //darkish dirt RgbColor whiter(120, 120, 120); //darkish dirt RgbColor white12(255, 255, 255); //darkish dirt RgbColor gold(HtmlColor( 0xFFD700 )); RgbColor orangered(HtmlColor( 0xFF4500 )); RgbColor orange(HtmlColor( 0xFFA500 )); RgbColor darkred(HtmlColor( 0x800000 )); RgbColor darkgreen(HtmlColor( 0x006400 )); RgbColor lightgreen(HtmlColor( 0x90ee90 )); RgbColor temp; RgbColor secondsColor = black; RgbColor minuteColor = darkred; RgbColor hourColor = gold; RgbColor highnoonColor = white12; RgbColor backlightColor = white; RgbColor hourMarkingColor = whiter; void transformtoHtmlColor (char* sOutput, RgbColor* inputColor) { HtmlColor(RgbColor(inputColor->R, inputColor->G, inputColor->B)).ToNumericalString(sOutput, 12); } void transformHtmltoStrip(RgbColor* outputColor, char* sInput) { HtmlColor htmlTemp; //Serial.print("HtmltoStrip "); //Serial.println((char*)sInput); htmlTemp.Parse( sInput ); RgbColor stripColor( htmlTemp ); //Serial.printf("StripColor: R:%i G:%i B:%i W:%i\n", stripColor.R, stripColor.G, stripColor.B, stripColor.W); memcpy(outputColor, &stripColor, sizeof(stripColor)); } #endif const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 3600; //ToDo changable from user const int daylightOffset_sec = 3600; struct tm timeinfo; volatile int currentSec = 59; volatile int currentMin = 1; volatile int currentHour = 2; volatile bool NTPreachable = false; #ifdef LDR_PIN // variable for storing the potentiometer value volatile unsigned int ldrValue = 0; #endif volatile int MAX_BRIGHTNESS = 200; // WebPortal const char thingName[] = "NTP-Clock-RGBLED"; const char wifiInitialApPassword[] = "12345678"; #define STRING_LEN 63 #define NUMBER_LEN 4 // -- Maximal length the input-range attributes can have. //#define COLOR_ATTR_LENGTH 60 // -- Configuration specific key. The value should be modified if config structure was changed. #define CONFIG_VERSION "V1.1.8" const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\n\ function colorCh(id)\n\ {\n\ var x=document.getElementById(id);\n\ var s=document.getElementById(id + 'Val');\n\ s.innerHTML = x.value;\n\ }\n\n\ document.addEventListener('DOMContentLoaded', function(event) {\n\ let elements = document.querySelectorAll('input[type=\"password\"]');\n\ for (let p of elements) {\n\ let btn = document.createElement('INPUT'); btn.type = 'button'; btn.value = '🔓'; btn.style.width = 'auto'; p.style.width = '80%'; p.parentNode.insertBefore(btn,p.nextSibling);\n\ btn.onclick = function() { if (p.type === 'password') { p.type = 'text'; btn.value = '🔒'; } else { p.type = 'password'; btn.value = '🔓'; } }\n\ };\n\ });\n"; // -- We need to create our custom HtmlFormatProvider to add some javasripts. class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider { protected: String getScriptInner() override { return HtmlFormatProvider::getScriptInner() + String(FPSTR(CUSTOMHTML_SCRIPT_INNER)); } }; // -- Javascript block will be added to the header. //const char CUSTOMHTML_BODY_INNER[] PROGMEM = " "; //const char CUSTOMHTML_BODY_INNER[] PROGMEM = " "; DNSServer dnsServer; WebServer server(80); #ifdef ESP8266 ESP8266HTTPUpdateServer httpUpdater; #elif defined(ESP32) HTTPUpdateServer httpUpdater; #endif IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION); iotwebconf::ParameterGroup timeGroup = iotwebconf::ParameterGroup("Time", "Time settings"); iotwebconf::TextTParameter ntpServerParam = iotwebconf::Builder>("ntpServer"). label("NTP Server"). defaultValue("pool.ntp.org"). build(); iotwebconf::ParameterGroup ledGroup = iotwebconf::ParameterGroup("LED", "LED settings"); iotwebconf::IntTParameter maxBrightnessParam = iotwebconf::Builder>("Max Brightness"). label("Max brightness"). defaultValue(200). min(MINIMAL_BRIGHTNESS). max(MAX_BRIGHTNESS). step(1). build(); iotwebconf::CheckboxTParameter singleSecondParam = iotwebconf::Builder("singleSecond"). label("single Second visible"). #if NUM_LEDS == 60 defaultValue(true). build(); #else defaultValue(false). build(); #endif iotwebconf::CheckboxTParameter allDotsOnParam = iotwebconf::Builder("allDotsOn"). label("all Dots lighten on"). defaultValue(true). build(); iotwebconf::CheckboxTParameter followingHourParam = iotwebconf::Builder("followingHour"). label("following Hour"). #if NUM_LEDS == 60 defaultValue(true). build(); #else defaultValue(false). build(); #endif iotwebconf::ColorTParameter hourColorParam = iotwebconf::Builder("Stundenfarbe"). label("Stundenfarbe"). defaultValue("#FFD700"). build(); iotwebconf::ColorTParameter minuteColorParam = iotwebconf::Builder("Minutenfarbe"). label("Minutenfarbe"). defaultValue("#800000"). build(); iotwebconf::ColorTParameter secondsColorParam = iotwebconf::Builder("Sekundenfarbe"). label("Sekundenfarbe"). defaultValue("#000000"). build(); iotwebconf::ColorTParameter highnoonColorParam = iotwebconf::Builder("12 Uhr Farbe"). label("12 Uhr Farbe"). defaultValue("#C0C0C0"). build(); iotwebconf::ColorTParameter backlightColorParam = iotwebconf::Builder("Hintergrundfarbe"). label("Hintergrundfarbe"). defaultValue("#1E2823"). build(); iotwebconf::ColorTParameter hourMarkingColorParam = iotwebconf::Builder("Stundenmarkierung"). label("Stundenmarkierung"). defaultValue("#787878"). build(); // -- An instance must be created from the class defined above. CustomHtmlFormatProvider customHtmlFormatProvider; Task bootAnim(200, TASK_FOREVER, &bootAnimCallback); Task clockTick(1000, TASK_FOREVER, &clockTickCallback); Task ledRefresh(200, TASK_FOREVER, &ledRefreshCallback); #ifdef LDR_PIN Task brightness(10000, TASK_FOREVER, &brightnessAdjustmentCallback); #endif Task iotwebconfLoop(1000, TASK_FOREVER, &iotWebConfLoopCallback); Scheduler runner; #ifdef ESP8266 bool getLocalTime(struct tm * info, uint32_t ms) { uint32_t start = millis(); time_t now; while ((millis() - start) <= ms) { time(&now); localtime_r(&now, info); if (info->tm_year > (2016 - 1900)) { return true; } delay(10); } return false; } #endif String printLocalTime() { if (!getLocalTime(&timeinfo, 200)) { Serial.println("Failed to obtain time"); NTPreachable = false; return "N/A"; } //Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S"); char timeStringBuff[50]; //50 chars should be enough strftime(timeStringBuff, sizeof(timeStringBuff), "%A, %B %d %Y %H:%M:%S", &timeinfo); //Serial.println(timeStringBuff); NTPreachable = true; return timeStringBuff; } /** Handle web requests to "/" path. */ void iotWebConfHandleRoot() { // -- Let IotWebConf test and handle captive portal requests. if (iotWebConf.handleCaptivePortal()) { // -- Captive portal request were already served. return; } //char sTemp[12]; String s = ""; s += ""; //s += CUSTOMHTML_BODY_INNER; s += "RGB LED Clock"; s += "RGB LED Clock"; s += "

"; s += ""; s += "
Current Time:"; s += printLocalTime(); s += "
"; s += ""; s += ""; s += ""; if (singleSecond) { s += ""; } if (allDotsOn) { s += ""; } s += "
NTP Server:"; s += ntpServerParam.value(); s += "
Current Brightness value: "; s += String(strip.GetBrightness()); s += "
Max Brightness value: "; s += maxBrightnessParam.value(); s += "
Show Seconds: "; s += (singleSecondParam.isChecked() ? "Yes" : "No"); s += "
All Dots On: "; s += (allDotsOnParam.isChecked() ? "Yes" : "No"); s += "
Following Hour: "; s += (followingHourParam.isChecked() ? "Yes" : "No"); s += "
"; s += "
High noon:
Hour color:
Minute color:
Seconds color:
Backlight:
Hour Marking:
"; s += "

"; s += "Go to configure page to change values."; s += "\n"; server.send(200, "text/html; charset=UTF-8", s); } void iotWebConfConfigSaved() { //ToDo ntpServerParamValue; MAX_BRIGHTNESS = maxBrightnessParam.value(); singleSecond = singleSecondParam.isChecked() ? true : false; //Serial.println(singleSecondParam.isChecked() ? "true" : "false"); allDotsOn = allDotsOnParam.isChecked() ? true : false; //Serial.println(allDotsOnParam.isChecked() ? "true" : "false"); #if NUM_LEDS == 60 followingHour = followingHourParam.isChecked() ? true : false; if (!followingHour) { hourOffset = 0 ; } #endif //Serial.println(followingHourParam.isChecked() ? "true" : "false"); transformHtmltoStrip(&highnoonColor, (char*)&highnoonColorParam.value()); transformHtmltoStrip(&hourColor, (char*)&hourColorParam.value()); transformHtmltoStrip(&minuteColor, (char*)&minuteColorParam.value()); transformHtmltoStrip(&secondsColor, (char*)&secondsColorParam.value()); transformHtmltoStrip(&backlightColor, (char*)&backlightColorParam.value()); transformHtmltoStrip(&hourMarkingColor, (char*)&hourMarkingColorParam.value()); Serial.println("Configuration was updated."); } void iotWebConf_Setup() { timeGroup.addItem(&ntpServerParam); ledGroup.addItem(&maxBrightnessParam); ledGroup.addItem(&singleSecondParam); ledGroup.addItem(&allDotsOnParam); #if NUM_LEDS == 60 ledGroup.addItem(&followingHourParam); #endif ledGroup.addItem(&hourColorParam); ledGroup.addItem(&minuteColorParam); ledGroup.addItem(&secondsColorParam); ledGroup.addItem(&highnoonColorParam); ledGroup.addItem(&backlightColorParam); ledGroup.addItem(&hourMarkingColorParam); iotWebConf.addParameterGroup(&timeGroup); iotWebConf.addParameterGroup(&ledGroup); iotWebConf.setConfigSavedCallback(&iotWebConfConfigSaved); //iotWebConf.setWifiConnectionTimeoutMs(60000); iotWebConf.setWifiConnectionCallback(&syncNTP); //NTP call after connection established //iotWebConf.setFormValidator(&iotWebConfFormValidator); iotWebConf.getApTimeoutParameter()->visible = true; iotWebConf.setupUpdateServer( [](const char* updatePath) { httpUpdater.setup(&server, updatePath); }, [](const char* userName, char* password) { httpUpdater.updateCredentials(userName, password); }); iotWebConf.setHtmlFormatProvider(&customHtmlFormatProvider); // -- Initializing the configuration. iotWebConf.init(); // -- Set up required URL handlers on the web server. server.on("/", iotWebConfHandleRoot); server.on("/config", [] { iotWebConf.handleConfig(); }); server.onNotFound([]() { iotWebConf.handleNotFound(); }); Serial.println("Ready."); Serial.flush(); } void syncNTP() { if (iotWebConf.getState() == iotwebconf::OnLine) { //init and get the time #ifdef ESP8266 //sntp_servermode_dhcp(0); configTime(MYTZ, ntpServerParam.value()); #endif #ifdef ESP32 configTime(0, 0, ntpServer); // TZ string information: https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html setenv("TZ", "AEST-10", 1); tzset(); // save the TZ variable //setTimeZone(long offset, int daylight); //configTime(gmtOffset_sec, daylightOffset_sec, ntpServerParamValue); #endif Serial.println(printLocalTime()); if (NTPreachable) { if (clockwiseRing) { currentSec = timeinfo.tm_sec; currentMin = timeinfo.tm_min; currentHour = MOD(timeinfo.tm_hour, 12); } else { //inverted logic - remaining time currentSec = 60 - timeinfo.tm_sec; currentMin = 60 - timeinfo.tm_min; currentHour = 12 - MOD(timeinfo.tm_hour, 12); } Serial.println("NTP mapped: " + String(int(currentHour * NUM_LEDS / 12)) + ":" + String(int(currentMin * NUM_LEDS / 60)) + ":" + String(int(currentSec * NUM_LEDS / 60))); bootAnim.disable(); iotWebConfConfigSaved(); ledRefresh.enable(); //clockTick.enable(); #ifdef LDR_PIN brightness.enable(); #endif } clockTick.enable(); //enable to check for ntp every 60 seconds } } void setup() { #ifdef LDR_PIN pinMode(LDR_PIN, INPUT_PULLUP); #endif pinMode(DATA_PIN, OUTPUT); Serial.begin(SERIAL_BAUD); Serial.flush(); Serial.print("\n\n\nCPU Frequency is: "); #ifdef ESP8266 Serial.print(ESP.getCpuFreqMHz()); Serial.println(" Mhz"); Serial.print("Chip ID: "); Serial.println(ESP.getFlashChipId()); #elif defined(ESP32) Serial.print(getCpuFrequencyMhz()); //Get CPU clock Serial.println(" Mhz"); uint32_t chipId = 0; for (int i = 0; i < 17; i = i + 8) { chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } Serial.printf("ESP32 Chip model = %s Rev %d\n", ESP.getChipModel(), ESP.getChipRevision()); Serial.printf("This chip has %d cores\n", ESP.getChipCores()); Serial.print("Chip ID: "); Serial.println(chipId); #endif Serial.print("MAC address: "); Serial.println(WiFi.macAddress()); //Get CPU clock #ifdef RGBW Serial.println("RGBW"); #else Serial.println("RGB"); #endif strip.Begin(); strip.ClearTo(white); strip.SetBrightness( MINIMAL_BRIGHTNESS ); strip.Show(); runner.init(); runner.addTask(ledRefresh); runner.addTask(clockTick); #ifdef LDR_PIN runner.addTask(brightness); #endif runner.addTask(bootAnim); runner.addTask(iotwebconfLoop); bootAnim.enable(); iotwebconfLoop.enable(); iotWebConf_Setup(); //Serial.end(); #ifdef ESP8266 ESP.wdtDisable(); ESP.wdtEnable(1000); #endif #if defined(ESP32) #endif } void loop() { runner.execute(); yield(); //iotWebConfLoopCallback();//ToDo put in a task, measure the runtime ESP.wdtFeed(); /* while (Serial.available()) Serial.read(); */ } void ledRefreshCallback() { temp = allDotsOn ? backlightColor : black; strip.ClearTo(temp); for (int dot = 0; dot < NUM_LEDS; dot++) { #if NUM_LEDS == 60 //1 dot hour marking if (MOD(dot, 5) == 0) { strip.SetPixelColor(dot, hourMarkingColor); } #endif #if NUM_LEDS == 24 //1 dot quarter marking if (MOD(dot, 6) == 0) { strip.SetPixelColor(dot, hourMarkingColor); } #endif } strip.SetPixelColor(0, highnoonColor); //define high noon #if NUM_LEDS == 60 //3 dots hour strip.SetPixelColor(MOD(int(currentHour * NUM_LEDS / 12 - 1 + hourOffset), NUM_LEDS), hourColor); strip.SetPixelColor(MOD(int(currentHour * NUM_LEDS / 12 + 0 + hourOffset), NUM_LEDS), hourColor); strip.SetPixelColor(MOD(int(currentHour * NUM_LEDS / 12 + 1 + hourOffset), NUM_LEDS), hourColor); if (singleSecond) { strip.SetPixelColor(MOD(int(currentSec * NUM_LEDS / 60 + 0), NUM_LEDS), allDotsOn ? secondsColor : backlightColor); } #else strip.SetPixelColor(MOD(int(currentHour * NUM_LEDS / 12 + 0 + hourOffset), NUM_LEDS) , hourColor); #endif strip.SetPixelColor(MOD(int(currentMin * NUM_LEDS / 60 + 0), NUM_LEDS), minuteColor); strip.Show(); } // Scheduler void clockTickCallback() { #ifdef LDR_PIN ldrValue = (ldrValue + analogRead(LDR_PIN)); #endif if (clockwiseRing) { if (currentSec >= 60) { currentSec = 0; currentMin++; if (!NTPreachable) { syncNTP(); } if (currentMin >= 60) { currentMin = 0; currentHour++; if (currentHour >= 12) { currentHour = 0; syncNTP(); } } if (followingHour) { hourOffset = int(currentMin * NUM_LEDS / 60 / 12); //Serial.println("clockwise hourOffset: " + String(hourOffset)); } //Serial.println(String(interruptCounter) + " | Ring Index: " + String(currentHour / (12 / NUM_LEDS)) + ":" + String(currentMin / (60 / NUM_LEDS)) + ":" + String(currentSec / (60 / NUM_LEDS))); } currentSec++; } else { if (currentSec < 0) { currentSec = 59; currentMin--; if (!NTPreachable) { syncNTP(); } if (currentMin < 0) { currentMin = 59; currentHour--; if (currentHour < 0) { currentHour = 11; syncNTP(); } } if (followingHour) { hourOffset = 0 - int((60 - currentMin * NUM_LEDS / 60) / 12); //negative value //Serial.println("Anticlockwise hourOffset: " + String(hourOffset)); } //Serial.println(String(interruptCounter) + " | Ring Index: " + String(currentHour / (12 / NUM_LEDS)) + ":" + String(currentMin / (60 / NUM_LEDS)) + ":" + String(currentSec / (60 / NUM_LEDS))); } currentSec--; } } void bootAnimCallback() { strip.ClearTo(black); int tail = -1; if (clockwiseRing) { currentSec++; if (currentSec >= NUM_LEDS) { currentSec = 0; } } else { currentSec--; tail = 1; if (currentSec < 0) { currentSec = NUM_LEDS - 1; } } if (iotWebConf.getState() == iotwebconf::OnLine && !NTPreachable) { strip.ClearTo(white); strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), black); strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), black); strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), black); } if (iotWebConf.getState() == iotwebconf::Connecting ) { strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), white); strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), whiter); strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), white12); } if (iotWebConf.getState() == iotwebconf::ApMode ) { strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), lightgreen); strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), green); strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), darkgreen); } if (iotWebConf.getState() == iotwebconf::Boot || iotWebConf.getState() == iotwebconf::NotConfigured) { strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), orangered); strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), red); strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), darkred); } strip.Show(); } #ifdef LDR_PIN void brightnessAdjustmentCallback() { //ToDo split measurement from setting //Serial.println(ldrValue); //brigthness begin ldrValue = ldrValue / 10; int x; if (ldrValue == 0) { strip.SetBrightness( MAX_BRIGHTNESS ); } else { x = int(MINIMAL_BRIGHTNESS + (MAX_BRIGHTNESS - MINIMAL_BRIGHTNESS) / ((ldrValue / LDR_SCALE) + 1) ); strip.SetBrightness(x); } //Serial.println("Brightness: " + String(strip.GetBrightness()) + "(" + String(ldrValue) + ")"); ldrValue = 0; strip.Show(); } #endif void iotWebConfLoopCallback() { iotWebConf.doLoop(); }