Merge pull request 'colorPicker' (#7) from colorPicker into master
Reviewed-on: #7
This commit is contained in:
commit
00eb84389b
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.bin
|
@ -1,6 +1,4 @@
|
||||
#include <WiFi.h>
|
||||
#include "time.h"
|
||||
|
||||
#include <TaskScheduler.h>
|
||||
|
||||
|
||||
@ -9,8 +7,17 @@
|
||||
#include <IotWebConfUsing.h>
|
||||
// UpdateServer includes
|
||||
#ifdef ESP8266
|
||||
#include <ESP8266WiFi.h>
|
||||
# include <ESP8266HTTPUpdateServer.h>
|
||||
#include <TZ.h>
|
||||
#define MYTZ TZ_Europe_Berlin
|
||||
#include <coredecls.h> // settimeofday_cb()
|
||||
//#include <Schedule.h>
|
||||
//#include <PolledTimeout.h>
|
||||
#include <sys/time.h> // struct timeval
|
||||
#include <sntp.h> // sntp_servermode_dhcp()
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
// For ESP32 IotWebConf provides a drop-in replacement for UpdateServer.
|
||||
# include <IotWebConfESP32HTTPUpdateServer.h>
|
||||
#endif
|
||||
@ -22,14 +29,23 @@
|
||||
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
|
||||
*/
|
||||
#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 NUM_LEDS 60
|
||||
#define COLOR_ORDER GRB
|
||||
#define DATA_PIN 17
|
||||
#endif
|
||||
#define NUM_LEDS 60
|
||||
#define SERIAL_BAUD 115200
|
||||
|
||||
//#define RGBW
|
||||
#define RGBW
|
||||
volatile bool singleSecond = true; //show seconds
|
||||
volatile bool allDotsOn = true; //lighten up all leds
|
||||
volatile bool followingHour = true; //move hour like an analog one
|
||||
@ -44,8 +60,14 @@ void brightnessAdjustmentCallback();
|
||||
#define MINIMAL_BRIGHTNESS 5
|
||||
#define LDR_SCALE 16
|
||||
#define colorSaturation 255
|
||||
//NeoPixelBrightnessBus<NeoGrbwFeature, Neo800KbpsMethod> strip(NUM_LEDS, DATA_PIN); //SK6812
|
||||
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod> strip(NUM_LEDS, DATA_PIN);
|
||||
#ifdef ESP8266
|
||||
//NeoPixelBrightnessBus<NeoGrbwFeature, Neo800KbpsMethod> strip(NUM_LEDS);//RDX0 GPIO3
|
||||
//NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266AsyncUart0Sk6812Method> strip(NUM_LEDS);
|
||||
//NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart0Sk6812Method> strip(NUM_LEDS);
|
||||
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266BitBang800KbpsMethod> strip(NUM_LEDS, DATA_PIN);
|
||||
#elif defined(ESP32)
|
||||
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod> 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);
|
||||
@ -57,16 +79,55 @@ 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(0x90ee90));
|
||||
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<HtmlColorNames>( 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
|
||||
//NeoPixelBrightnessBus<NeoGrbFeature, Neo800KbpsMethod> strip(NUM_LEDS, DATA_PIN); //ws2812B
|
||||
NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s1800KbpsMethod> strip(NUM_LEDS, DATA_PIN);
|
||||
#ifdef ESP8266
|
||||
//NeoPixelBrightnessBus<NeoGrbFeature, Neo800KbpsMethod> strip(NUM_LEDS);//RDX0 GPIO3 Broken due IoTWebConf
|
||||
NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266Uart1800KbpsMethod> strip(NUM_LEDS);
|
||||
//NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp8266BitBang800KbpsMethod> strip(NUM_LEDS, DATA_PIN);
|
||||
#elif defined(ESP32)
|
||||
NeoPixelBrightnessBus<NeoGrbFeature, NeoEsp32I2s1800KbpsMethod> strip(NUM_LEDS, DATA_PIN); //ESP32
|
||||
#endif
|
||||
RgbColor red(colorSaturation, 0, 0);
|
||||
RgbColor green(0, colorSaturation, 0);
|
||||
RgbColor blue(0, 0, colorSaturation);
|
||||
@ -75,70 +136,115 @@ 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 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<HtmlColorNames>( 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
|
||||
|
||||
//NTP handler
|
||||
//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";
|
||||
//ToDo add internal LED and check visibility
|
||||
#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.0.0"
|
||||
#define CONFIG_VERSION "V1.1.4"
|
||||
|
||||
// -- Javascript block will be added to the header. 🔒 🔓
|
||||
const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\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 = '83%'; 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";
|
||||
//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " <link rel='icon' src='data:image/png;base64,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'/>";
|
||||
DNSServer dnsServer;
|
||||
WebServer server(80);
|
||||
#ifdef ESP8266
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
#elif defined(ESP32)
|
||||
HTTPUpdateServer httpUpdater;
|
||||
#endif
|
||||
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";
|
||||
const char IOTWEBCONF_HTML_FORM_COLOR_PARAM[] PROGMEM =
|
||||
"<div class='{s}' '><label for='{i}'>{b}</label> (<span id='{i}Val'>{v}</span>)"
|
||||
"<input type='{t}' id='{i}' "
|
||||
"name='{i}' style=\"padding: unset\" maxlength={l} placeholder='{p}' value='{v}' {c}/>"
|
||||
"<div class='em'>{e}</div></div>\n";
|
||||
|
||||
char ntpServerParamValue[STRING_LEN];
|
||||
char maxBrightnessParamValue[NUMBER_LEN];
|
||||
char singleSecondParamValue[STRING_LEN];
|
||||
char allDotsOnParamValue[STRING_LEN];
|
||||
char followingHourParamValue[STRING_LEN];
|
||||
// -- Our custom class declaration. You should move it to a .h fine in your project.
|
||||
class ColorWithValueParameter : public iotwebconf::NumberParameter
|
||||
{
|
||||
public:
|
||||
ColorWithValueParameter(
|
||||
const char* label, const char* id, char* valueBuffer, int length,
|
||||
const char* defaultValue
|
||||
) : iotwebconf::NumberParameter(
|
||||
label, id, valueBuffer, length, defaultValue)
|
||||
{
|
||||
snprintf(
|
||||
this->_colorAttr, COLOR_ATTR_LENGTH,
|
||||
"oninput='colorCh(this.id)'");
|
||||
|
||||
IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
|
||||
IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings");
|
||||
IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org");
|
||||
IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings");
|
||||
IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'");
|
||||
IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true);
|
||||
IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true);
|
||||
IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true);
|
||||
this->customHtml = this->_colorAttr;
|
||||
};
|
||||
protected:
|
||||
// Overrides
|
||||
virtual String renderHtml(
|
||||
bool dataArrived, bool hasValueFromPost, String valueFromPost) override
|
||||
{
|
||||
return TextParameter::renderHtml("color", hasValueFromPost, valueFromPost);
|
||||
};
|
||||
virtual String getHtmlTemplate()
|
||||
{
|
||||
return FPSTR(IOTWEBCONF_HTML_FORM_COLOR_PARAM);
|
||||
};
|
||||
|
||||
private:
|
||||
char _colorAttr[COLOR_ATTR_LENGTH];
|
||||
};
|
||||
|
||||
// -- We need to create our custom HtmlFormatProvider to add some javasripts.
|
||||
class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider
|
||||
{
|
||||
protected:
|
||||
@ -157,22 +263,87 @@ class CustomHtmlFormatProvider : public iotwebconf::HtmlFormatProvider
|
||||
}
|
||||
*/
|
||||
};
|
||||
// -- Javascript block will be added to the header.
|
||||
/*
|
||||
const char CUSTOMHTML_SCRIPT_INNER[] PROGMEM = "\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 = '83%'; 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";
|
||||
*/
|
||||
//const char CUSTOMHTML_BODY_INNER[] PROGMEM = " <link rel='icon' src='data:image/png;base64,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'/>";
|
||||
DNSServer dnsServer;
|
||||
WebServer server(80);
|
||||
#ifdef ESP8266
|
||||
ESP8266HTTPUpdateServer httpUpdater;
|
||||
#elif defined(ESP32)
|
||||
HTTPUpdateServer httpUpdater;
|
||||
#endif
|
||||
|
||||
char ntpServerParamValue[STRING_LEN];
|
||||
char maxBrightnessParamValue[NUMBER_LEN];
|
||||
char singleSecondParamValue[STRING_LEN];
|
||||
char allDotsOnParamValue[STRING_LEN];
|
||||
char followingHourParamValue[STRING_LEN];
|
||||
char hourColorParamValue[COLOR_ATTR_LENGTH];
|
||||
char minuteColorParamValue[COLOR_ATTR_LENGTH];
|
||||
char secondsColorParamValue[COLOR_ATTR_LENGTH];
|
||||
char highnoonColorParamValue[COLOR_ATTR_LENGTH];
|
||||
char backlightColorParamValue[COLOR_ATTR_LENGTH];
|
||||
char hourMarkingColorParamValue[COLOR_ATTR_LENGTH];
|
||||
|
||||
IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
|
||||
IotWebConfParameterGroup timeGroup = IotWebConfParameterGroup("Time", "Time settings");
|
||||
IotWebConfTextParameter ntpServerParam = IotWebConfTextParameter("NTP Server", "ntpServer", ntpServerParamValue, STRING_LEN, "pool.ntp.org");
|
||||
IotWebConfParameterGroup ledGroup = IotWebConfParameterGroup("LED", "LED settings");
|
||||
IotWebConfNumberParameter maxBrightnessParam = IotWebConfNumberParameter("Max BRIGHTNESS", "max brightness", maxBrightnessParamValue, NUMBER_LEN, "200", "20..254", "min='20' max='254' step='1'");
|
||||
IotWebConfCheckboxParameter singleSecondParam = IotWebConfCheckboxParameter("Show Seconds", "singleSecond", singleSecondParamValue, STRING_LEN, true);
|
||||
IotWebConfCheckboxParameter allDotsOnParam = IotWebConfCheckboxParameter("all Dots lighten on", "allDotsOn", allDotsOnParamValue, STRING_LEN, true);
|
||||
IotWebConfCheckboxParameter followingHourParam = IotWebConfCheckboxParameter("following Hour", "followingHour", followingHourParamValue, STRING_LEN, true);
|
||||
ColorWithValueParameter hourColorParam = ColorWithValueParameter("Stundenfarbe", "hourColorParam", hourColorParamValue, COLOR_ATTR_LENGTH, "#FFD700");
|
||||
ColorWithValueParameter minuteColorParam = ColorWithValueParameter("Minutenfarbe", "minuteColorParam", minuteColorParamValue, COLOR_ATTR_LENGTH, "#800000");
|
||||
ColorWithValueParameter secondsColorParam = ColorWithValueParameter("Sekundenfarbe", "secondsColorParam", secondsColorParamValue, COLOR_ATTR_LENGTH, "#000000");
|
||||
ColorWithValueParameter highnoonColorParam = ColorWithValueParameter("12Uhr Farbe", "highnoonColorParam", highnoonColorParamValue, COLOR_ATTR_LENGTH, "#C0C0C0");
|
||||
ColorWithValueParameter backlightColorParam = ColorWithValueParameter("Hintergrundfarbe", "backlightColorParam", backlightColorParamValue, COLOR_ATTR_LENGTH, "#1E2823");
|
||||
ColorWithValueParameter hourMarkingColorParam = ColorWithValueParameter("Stundenmarkierung", "hourMarkingColorParam", hourMarkingColorParamValue, COLOR_ATTR_LENGTH, "#787878");
|
||||
|
||||
|
||||
// -- An instance must be created from the class defined above.
|
||||
CustomHtmlFormatProvider customHtmlFormatProvider;
|
||||
|
||||
//ToDo color Picker Second, 12Clock, Minute, Hour
|
||||
|
||||
|
||||
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(200, TASK_FOREVER, &iotWebConf.doLoop);
|
||||
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)) {
|
||||
if (!getLocalTime(&timeinfo, 200)) {
|
||||
Serial.println("Failed to obtain time");
|
||||
NTPreachable = false;
|
||||
return "";
|
||||
}
|
||||
//Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
|
||||
@ -180,6 +351,7 @@ String printLocalTime() {
|
||||
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;
|
||||
|
||||
}
|
||||
@ -194,7 +366,7 @@ void iotWebConfHandleRoot() {
|
||||
// -- Captive portal request were already served.
|
||||
return;
|
||||
}
|
||||
|
||||
char sTemp[12];
|
||||
String s = "<!DOCTYPE html><html lang=\"en\"><head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\"/>";
|
||||
s += "<meta http-equiv=\"refresh\" content=\"30\">";
|
||||
//s += CUSTOMHTML_BODY_INNER;
|
||||
@ -204,7 +376,8 @@ void iotWebConfHandleRoot() {
|
||||
s += "<table>";
|
||||
s += "<tr><td>Current Time:</td><td>";
|
||||
s += printLocalTime();
|
||||
s += "</td></tr><tr></tr><tr><td>NTP Server:</td><td>";
|
||||
s += "</td></tr></table><table>";
|
||||
s += "<tr></tr><tr><td>NTP Server:</td><td>";
|
||||
s += ntpServerParamValue;
|
||||
s += "</td><tr><tr><td>Current Brightness value: </td><td>";
|
||||
s += String(strip.GetBrightness());
|
||||
@ -216,7 +389,35 @@ void iotWebConfHandleRoot() {
|
||||
s += (allDotsOn ? "Yes" : "No");
|
||||
s += "</td></tr><tr><td>Following Hour: </td><td>";
|
||||
s += (followingHour ? "Yes" : "No");
|
||||
s += "<td></tr></table>";
|
||||
s += "</td></tr><tr><td>";
|
||||
s += "<tr><td>High noon: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &highnoonColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr>";
|
||||
s += "<tr><td>Hour color: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &hourColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr>";
|
||||
s += "<tr><td>Minute color: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &minuteColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr>";
|
||||
if (singleSecond) {
|
||||
s += "<tr><td>Seconds color: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &secondsColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr>";
|
||||
}
|
||||
if (allDotsOn) {
|
||||
s += "<tr><td>Backlight: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &backlightColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr>";
|
||||
}
|
||||
s += "<tr><td>Hour Marking: </td><td style=\"border: 1px solid #000000; background-color:";
|
||||
transformtoHtmlColor ((char*)&sTemp, &hourMarkingColor);
|
||||
s += sTemp;
|
||||
s += ";\"><td></tr></table>";
|
||||
s += "<p>";
|
||||
s += "Go to <a href='config'>configure page</a> to change values.";
|
||||
s += "</body></html>\n";
|
||||
@ -234,30 +435,15 @@ void iotWebConfConfigSaved()
|
||||
//Serial.println(allDotsOnParam.isChecked() ? "true" : "false");
|
||||
followingHour = followingHourParam.isChecked() ? true : false;
|
||||
//Serial.println(followingHourParam.isChecked() ? "true" : "false");
|
||||
|
||||
transformHtmltoStrip(&highnoonColor, (char*)&highnoonColorParamValue);
|
||||
transformHtmltoStrip(&hourColor, (char*)&hourColorParamValue);
|
||||
transformHtmltoStrip(&minuteColor, (char*)&minuteColorParamValue);
|
||||
transformHtmltoStrip(&secondsColor, (char*)&secondsColorParamValue);
|
||||
transformHtmltoStrip(&backlightColor, (char*)&backlightColorParamValue);
|
||||
transformHtmltoStrip(&hourMarkingColor, (char*)&hourMarkingColorParamValue);
|
||||
Serial.println("Configuration was updated.");
|
||||
|
||||
}
|
||||
/*
|
||||
bool iotWebConfFormValidator(iotwebconf::WebRequestWrapper* webRequestWrapper)
|
||||
{
|
||||
|
||||
Serial.println("Validating form.");
|
||||
boolean valid = true;
|
||||
|
||||
int l = server.arg(ntpServerParam.getId()).length();
|
||||
if (l < 3)
|
||||
{
|
||||
ntpServerParam.errorMessage = "Please provide at least 3 characters for this test!";
|
||||
valid = false;
|
||||
}
|
||||
int b = atoi(maxBrightnessParamValue);
|
||||
if (b < MINIMAL_BRIGHTNESS || b > 254)
|
||||
{
|
||||
valid = false;
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
*/
|
||||
|
||||
void iotWebConf_Setup() {
|
||||
|
||||
@ -267,6 +453,12 @@ void iotWebConf_Setup() {
|
||||
ledGroup.addItem(&singleSecondParam);
|
||||
ledGroup.addItem(&allDotsOnParam);
|
||||
ledGroup.addItem(&followingHourParam);
|
||||
ledGroup.addItem(&hourColorParam);
|
||||
ledGroup.addItem(&minuteColorParam);
|
||||
ledGroup.addItem(&secondsColorParam);
|
||||
ledGroup.addItem(&highnoonColorParam);
|
||||
ledGroup.addItem(&backlightColorParam);
|
||||
ledGroup.addItem(&hourMarkingColorParam);
|
||||
|
||||
iotWebConf.addParameterGroup(&timeGroup);
|
||||
iotWebConf.addParameterGroup(&ledGroup);
|
||||
@ -301,46 +493,64 @@ void iotWebConf_Setup() {
|
||||
void syncNTP() {
|
||||
if (iotWebConf.getState() == IOTWEBCONF_STATE_ONLINE) {
|
||||
//init and get the time
|
||||
configTime(gmtOffset_sec, daylightOffset_sec, ntpServerParamValue);
|
||||
#ifdef ESP8266
|
||||
//sntp_servermode_dhcp(0);
|
||||
configTime(MYTZ, ntpServerParamValue);
|
||||
#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());
|
||||
//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(currentHour) + ":" + String(currentMin) + ":" + String(currentSec));
|
||||
bootAnim.disable();
|
||||
ledRefresh.enable();
|
||||
clockTick.enable();
|
||||
brightness.enable();
|
||||
if (NTPreachable) {
|
||||
//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(currentHour) + ":" + String(currentMin) + ":" + String(currentSec));
|
||||
bootAnim.disable();
|
||||
ledRefresh.enable();
|
||||
clockTick.enable();
|
||||
#ifdef LDR_PIN
|
||||
brightness.enable();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
#elif defined(ESP32)
|
||||
Serial.print(getCpuFrequencyMhz()); //Get CPU clock
|
||||
#endif
|
||||
Serial.println(" Mhz");
|
||||
Serial.print("MAC address: ");
|
||||
Serial.println(WiFi.macAddress()); //Get CPU clock
|
||||
|
||||
Serial.println("-----------------------\nSettings\n-----------------------");
|
||||
Serial.printf("Show single second: \t%s\n", singleSecond ? "yes" : "no");
|
||||
Serial.printf("Lighten up all LEDs: \t%s\n", allDotsOn ? "yes" : "no");
|
||||
Serial.printf("Following Hour: \t%s\n\n", followingHour ? "yes" : "no");
|
||||
|
||||
strip.Begin();
|
||||
strip.SetBrightness( MINIMAL_BRIGHTNESS );
|
||||
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);
|
||||
bootAnim.enable();
|
||||
|
||||
@ -359,34 +569,40 @@ void loop()
|
||||
}
|
||||
|
||||
void ledRefreshCallback() {
|
||||
temp = allDotsOn ? white : black;
|
||||
temp = allDotsOn ? backlightColor : black;
|
||||
strip.ClearTo(temp);
|
||||
//1 dot hour marking
|
||||
for (int dot = 0; dot < NUM_LEDS; dot++) {
|
||||
if (MOD(dot, 5) == 0) {
|
||||
strip.SetPixelColor(dot, whiter);
|
||||
strip.SetPixelColor(dot, hourMarkingColor);
|
||||
}
|
||||
}
|
||||
//3 dots hour
|
||||
strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), gold);
|
||||
strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), gold);
|
||||
strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), gold);
|
||||
strip.SetPixelColor(MOD((currentHour * 5 - 1 + hourOffset), NUM_LEDS), hourColor);
|
||||
strip.SetPixelColor(MOD((currentHour * 5 + 0 + hourOffset), NUM_LEDS), hourColor);
|
||||
strip.SetPixelColor(MOD((currentHour * 5 + 1 + hourOffset), NUM_LEDS), hourColor);
|
||||
|
||||
strip.SetPixelColor(0, white12); //define high noon
|
||||
strip.SetPixelColor(0, highnoonColor); //define high noon
|
||||
|
||||
if (singleSecond) {
|
||||
strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : white));
|
||||
strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (secondsColor));
|
||||
//strip.SetPixelColor(MOD((currentSec + 0), NUM_LEDS), (allDotsOn ? black : secondsColor));
|
||||
}
|
||||
strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), darkred);
|
||||
strip.SetPixelColor(MOD((currentMin + 0), NUM_LEDS), minuteColor);
|
||||
strip.Show();
|
||||
}
|
||||
|
||||
// Scheduler
|
||||
void clockTickCallback() {
|
||||
#ifdef LDR_PIN
|
||||
ldrValue = (ldrValue + analogRead(LDR_PIN));
|
||||
#endif
|
||||
if (currentSec < 0) {
|
||||
currentSec = 59;
|
||||
currentMin--;
|
||||
if (!NTPreachable) {
|
||||
syncNTP();
|
||||
}
|
||||
if (currentMin < 0) {
|
||||
currentMin = 59;
|
||||
currentHour--;
|
||||
@ -406,29 +622,39 @@ void clockTickCallback() {
|
||||
|
||||
void bootAnimCallback() {
|
||||
strip.ClearTo(black);
|
||||
currentSec--;
|
||||
if (currentSec < 0) {
|
||||
currentSec = 59;
|
||||
int tail = -1;
|
||||
currentSec--;
|
||||
if (currentSec < 0) {
|
||||
currentSec = NUM_LEDS-1;
|
||||
tail = 1;
|
||||
}
|
||||
|
||||
if (iotWebConf.getState() == IOTWEBCONF_STATE_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_STATE_CONNECTING) {
|
||||
strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), white);
|
||||
strip.SetPixelColor(MOD((currentSec - 1), NUM_LEDS), whiter);
|
||||
strip.SetPixelColor(MOD((currentSec - 2), NUM_LEDS), white12);
|
||||
strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), whiter);
|
||||
strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), white12);
|
||||
}
|
||||
if (iotWebConf.getState() == IOTWEBCONF_STATE_AP_MODE) {
|
||||
strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), lightgreen);
|
||||
strip.SetPixelColor(MOD((currentSec - 1), NUM_LEDS), green);
|
||||
strip.SetPixelColor(MOD((currentSec - 2), NUM_LEDS), darkgreen);
|
||||
strip.SetPixelColor(MOD((currentSec - 1 * tail), NUM_LEDS), green);
|
||||
strip.SetPixelColor(MOD((currentSec - 2 * tail), NUM_LEDS), darkgreen);
|
||||
}
|
||||
if (iotWebConf.getState() == IOTWEBCONF_STATE_BOOT || iotWebConf.getState() == IOTWEBCONF_STATE_NOT_CONFIGURED) {
|
||||
strip.SetPixelColor(MOD((currentSec - 0), NUM_LEDS), orangered);
|
||||
strip.SetPixelColor(MOD((currentSec - 1), NUM_LEDS), red);
|
||||
strip.SetPixelColor(MOD((currentSec - 2), NUM_LEDS), darkred);
|
||||
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() {
|
||||
//Serial.println(ldrValue);
|
||||
//brigthness begin
|
||||
@ -441,7 +667,8 @@ void brightnessAdjustmentCallback() {
|
||||
x = int(MINIMAL_BRIGHTNESS + (MAX_BRIGHTNESS - MINIMAL_BRIGHTNESS) / ((ldrValue / LDR_SCALE) + 1) );
|
||||
strip.SetBrightness(x);
|
||||
}
|
||||
Serial.println("Brightness: " + String(strip.GetBrightness()) + "(" + String(ldrValue) + ")");
|
||||
//Serial.println("Brightness: " + String(strip.GetBrightness()) + "(" + String(ldrValue) + ")");
|
||||
ldrValue = 0;
|
||||
strip.Show();
|
||||
}
|
||||
#endif
|
||||
|
Binary file not shown.
29
README.md
29
README.md
@ -1,13 +1,15 @@
|
||||
# Anleitung RGB LED Uhr
|
||||
|
||||
Dies ist eine Beschreibung der RGB LED Uhr
|
||||
Nach jeden Neustart wird der eigene WiFi Accesspoint für 30 Sekunden aktiviert. Verbindet man sich mit diesem, so kann man etwaige Fehler korrigieren.
|
||||
# Schnellstart
|
||||
Sobald die Uhr mit Strom versorgt wird ( 5V, 500mAh) bietet das Board (Lolin32lite) einen WiFi Accesspoint "NTP-Clock-RGBLED" an und drei LEDs in roten Farben kreisen schnell herum. Zu diesem kann man sich verbinden (Passwort: 12345678) bzw das Smartphone meldet, dass eine Anmeldung erforderlich ist. Man kommt zunächst auf der Übersichtsseite an. Diese ist prinzipiell uninteressant, stattdessen muss die Internetverbindung konfiguriert werden. Hierzu klickt man auf "Config" und trägt die folgenden drei Dinge ein:
|
||||
- Ein Passwort für die Uhr
|
||||
Sobald die Uhr mit Strom versorgt wird ( 5V, 500mAh) bietet das Board (Lolin32lite) einen WiFi Accesspoint "NTP-Clock-RGBLED" an und drei LEDs in roten Farben kreisen schnell herum. Zu diesem kann man sich verbinden (Passwort: 12345678) bzw. das Smartphone meldet, dass eine Anmeldung erforderlich ist. Man kommt zunächst auf der Übersichtsseite an. Diese ist später erst interessant, stattdessen muss die Internetverbindung konfiguriert werden. Hierzu klickt man auf "Config" und trägt die folgenden drei Dinge ein:
|
||||
|
||||
- Ein Passwort für die Uhr bzw den temporären Accesspoint
|
||||
- Den Namen des Wlans
|
||||
- Das Passwort des Wlans
|
||||
Der Rest ist nicht notwendig. Sobald man die Werte gespeichert hat, trennt man das Smartphone vom WLAN. Die drei kreisenden LEDs können dann weiß kurz aufleuchten, üblicherweise sieht man dies nicht, da sobald die Uhrzeit verfügbar ist, diese angezeigt wird. Damit ist die Uhr konfiguriert.
|
||||
Ab sofort ist die Uhr unter einer neuen IP erreichbar, sodass dort weitere Einstellungen vorgenommen werden können. Die Uhr merkt sich auch die Einstellungen.
|
||||
|
||||
Der Rest ist nicht notwendig. Sobald man die Werte gespeichert hat, trennt man das Smartphone vom WLAN der Uhr. Die drei kreisenden LEDs können dann weiß kurz aufleuchten. Üblicherweise sieht man dies nicht, da sobald die Uhrzeit verfügbar ist, diese angezeigt wird. In seltenen Fällen wird der Ring weiß beleuchtet und drei schwarze LEDs kreisen. Dies bedeutet, dass keine Uhrzeit zur Verfügung steht. Ansonsten ist damit die Uhr konfiguriert.
|
||||
Ab sofort ist die Uhr unter einer neuen IP erreichbar (nachzusehen im Router), sodass dort weitere Einstellungen vorgenommen werden können. Die Uhr merkt sich auch die getätigten Einstellungen.
|
||||
# erweiterte Einstellungen
|
||||
Es wird unter der IP 192.168.4.1 ein Webserver angeboten (sofern über den Accesspoint direkt verbunden), der zwei Webseiten anzeigen kann. Primär wird die Statusseite angezeigt, die alle wesentlichen Parameter auflistet:
|
||||
- Aktuelle NTP Zeit
|
||||
@ -17,6 +19,12 @@ Ab sofort ist die Uhr unter einer neuen IP erreichbar, sodass dort weitere Einst
|
||||
- Anzeige der einzelnen Sekunden
|
||||
- Aufleuchten aller LEDs
|
||||
- Folgende Stunde (wie auf einer analogen Uhr)
|
||||
- Farbwahl der 12Uhr Markierung
|
||||
- Farbwahl der aktuelle Stunde (3LED)
|
||||
- Farbwahl der aktuellen Minute (1LED)
|
||||
- Farbwahl der aktuellen Sekunde (1LED)
|
||||
- Farbwahl der übrigen LEDs
|
||||
- Farbwahl der restlichen Stunden (10 LEDs)
|
||||
|
||||
Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Möglichkeit für den Upload einer neuen Firmware sowie die aktuelle Firmwareversion wird angezeigt.
|
||||
|
||||
@ -44,13 +52,16 @@ Unten auf der Statusseite gibt es einen Link zur Konfigurationsseite, eine Mögl
|
||||
- Show Seconds
|
||||
- all Dots lighten up
|
||||
- following Hour
|
||||
- hourColor
|
||||
- minuteColor
|
||||
- secondsColor
|
||||
- highnoonColor
|
||||
- backlightColor
|
||||
- hourMarkingColor
|
||||
|
||||
- firmware update link
|
||||
- Firmware config version 'xxxx'
|
||||
|
||||
## ausstehende Verbesserungen
|
||||
- [ ] RGB Auswahl Sekunden
|
||||
- [ ] RGB Auswahl Minuten
|
||||
- [ ] RGB Auswahl Stunden
|
||||
- [ ] RGB Auswahl 12 Uhr
|
||||
- [ ] flüssige Helligkeitsadaptierung
|
||||
- [ ] härtes non-blocking Verhalten
|
||||
|
Loading…
Reference in New Issue
Block a user