LED-Clock/60LED_WS2812B_NTP_Clock.ino

376 lines
12 KiB
Arduino
Raw Normal View History

2019-12-11 08:03:32 +00:00
#include "time.h"
#include <TaskScheduler.h>
2021-06-28 19:07:58 +00:00
#define _TASK_SLEEP_ON_IDLE_RUN //ToDo check benefit
2020-09-27 06:29:14 +00:00
#include <NeoPixelBrightnessBus.h>
2020-05-03 12:53:41 +00:00
#include <IotWebConf.h>
#include <IotWebConfTParameter.h>
2021-01-01 15:44:50 +00:00
// UpdateServer includes
#ifdef ESP8266
2021-01-28 18:00:15 +00:00
#include <ESP8266WiFi.h>
2021-01-01 15:44:50 +00:00
# include <ESP8266HTTPUpdateServer.h>
2021-01-28 18:00:15 +00:00
#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()
2021-01-01 15:44:50 +00:00
#elif defined(ESP32)
2021-01-28 18:00:15 +00:00
#include <WiFi.h>
2021-01-01 15:44:50 +00:00
// For ESP32 IotWebConf provides a drop-in replacement for UpdateServer.
# include <IotWebConfESP32HTTPUpdateServer.h>
#include <esp_task_wdt.h>
2021-01-01 15:44:50 +00:00
#endif
2019-12-11 08:03:32 +00:00
2019-12-12 18:06:56 +00:00
#define MOD(a,b) ((((a)%(b))+(b))%(b))
2021-11-26 11:10:53 +00:00
2021-01-28 18:00:15 +00:00
#ifdef ESP8266
#define LDR_PIN A0
2021-01-28 18:00:15 +00:00
#define IOTWEBCONF_DEBUG_DISABLED
#define DATA_PIN D7 //DMA RDX0/GPIO3 | Uart1 TXD1/GPIO2 | UART0 GPIO1
2021-01-28 18:00:15 +00:00
#elif defined(ESP32)
2020-09-27 06:29:14 +00:00
#define LDR_PIN A6
#define DATA_PIN 17
2021-01-28 18:00:15 +00:00
#endif
2021-05-06 20:41:54 +00:00
/* useful preselection
2021-05-07 14:17:23 +00:00
NO following hour
NO three block hour marking
quarter hour marking
2021-05-06 20:41:54 +00:00
*/
#define NUM_LEDS 60 //24
2020-12-26 15:00:29 +00:00
#define SERIAL_BAUD 115200
#define RGBW
2021-05-06 20:41:54 +00:00
const bool clockwiseRing = false;
volatile bool singleSecond = false; //show seconds
2021-01-08 20:10:16 +00:00
volatile bool allDotsOn = true; //lighten up all leds
2021-05-06 20:41:54 +00:00
#if NUM_LEDS == 60
2021-01-08 20:10:16 +00:00
volatile bool followingHour = true; //move hour like an analog one
2021-05-07 14:17:23 +00:00
#else
volatile bool followingHour = false; //disabled due limited resolution
2021-05-06 20:41:54 +00:00
#endif
2021-01-08 20:10:16 +00:00
volatile int hourOffset = 0;
2020-12-26 15:00:29 +00:00
void bootAnimCallback();
void clockTickCallback();
void ledRefreshCallback();
void brightnessAdjustmentCallback();
2021-11-26 11:10:53 +00:00
void brightnessFadingCallback();
2021-06-28 19:07:58 +00:00
void iotWebConfLoopCallback();
2020-12-26 15:00:29 +00:00
#ifdef RGBW
#define MINIMAL_BRIGHTNESS 5
2021-11-26 11:10:53 +00:00
#define LDR_SCALE 4
2020-12-26 15:00:29 +00:00
#define colorSaturation 255
2021-01-28 18:00:15 +00:00
#ifdef ESP8266
//NeoPixelBrightnessBus<NeoGrbwFeature, Neo800KbpsMethod> strip(NUM_LEDS);//RDX0 GPIO3
2021-01-28 18:00:15 +00:00
//NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266AsyncUart0Sk6812Method> strip(NUM_LEDS);
//NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266Uart0Sk6812Method> strip(NUM_LEDS);
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp8266BitBang800KbpsMethod> strip(NUM_LEDS, DATA_PIN);
2021-01-28 18:00:15 +00:00
#elif defined(ESP32)
NeoPixelBrightnessBus<NeoGrbwFeature, NeoEsp32I2s1800KbpsMethod> strip(NUM_LEDS, DATA_PIN); //ESP32
#endif
2020-09-27 06:29:14 +00:00
RgbwColor red(colorSaturation, 0, 0, 0);
RgbwColor green(0, colorSaturation, 0, 0);
RgbwColor blue(0, 0, colorSaturation, 0);
RgbwColor realWhite(colorSaturation);
2021-01-08 20:10:16 +00:00
RgbwColor white(0, 0, 0, 40); //darkish dirt
RgbwColor whiter(0, 0, 0, 120); //darkish dirt
2021-01-01 15:44:50 +00:00
RgbwColor white12(0, 0, 0, 192); //darkish dirt
2020-09-27 06:29:14 +00:00
RgbwColor black(0);
RgbwColor gold(HtmlColor( 0xFFD700 ) );
RgbwColor orangered(HtmlColor( 0xFF4500 ) );
RgbwColor orange(HtmlColor( 0xFFA500 ) );
2021-01-27 16:27:23 +00:00
RgbwColor darkred(HtmlColor( 0x800000) );
RgbwColor darkgreen(HtmlColor( 0x006400) );
RgbwColor lightgreen(HtmlColor( 0x30ee30) );
2020-12-26 15:00:29 +00:00
RgbwColor temp;
2021-01-30 13:04:23 +00:00
RgbwColor secondsColor = black;
2021-01-26 20:44:46 +00:00
RgbwColor minuteColor = darkred;
RgbwColor hourColor = gold;
RgbwColor highnoonColor = white12;
RgbwColor backlightColor = white;
RgbwColor hourMarkingColor = whiter;
2021-01-27 16:27:23 +00:00
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);
2021-01-30 13:04:23 +00:00
HtmlColor(RgbColor(inputColor->W, inputColor->W, inputColor->W)).ToNumericalString(sOutput, 12);
2021-01-27 16:27:23 +00:00
//Serial.println((char*)sOutput);
}
else {
//Serial.print("Color: "); Serial.print(inputColor->R); Serial.print(inputColor->G); Serial.println(inputColor->B);
2021-01-30 13:04:23 +00:00
HtmlColor(RgbColor(inputColor->R, inputColor->G, inputColor->B)).ToNumericalString(sOutput, 12);
2021-01-27 16:27:23 +00:00
//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));
}
2020-12-26 15:00:29 +00:00
#else
#define MINIMAL_BRIGHTNESS 20
#define LDR_SCALE 16
#define colorSaturation 192
#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
2020-12-26 15:00:29 +00:00
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
2021-01-27 16:27:23 +00:00
RgbColor gold(HtmlColor( 0xFFD700 ));
RgbColor orangered(HtmlColor( 0xFF4500 ));
RgbColor orange(HtmlColor( 0xFFA500 ));
RgbColor darkred(HtmlColor( 0x800000 ));
RgbColor darkgreen(HtmlColor( 0x006400 ));
RgbColor lightgreen(HtmlColor( 0x90ee90 ));
2020-12-26 15:00:29 +00:00
RgbColor temp;
2021-01-30 13:04:23 +00:00
RgbColor secondsColor = black;
2021-01-26 20:44:46 +00:00
RgbColor minuteColor = darkred;
RgbColor hourColor = gold;
RgbColor highnoonColor = white12;
RgbColor backlightColor = white;
RgbColor hourMarkingColor = whiter;
2021-01-27 16:27:23 +00:00
2021-01-30 13:04:23 +00:00
void transformtoHtmlColor (char* sOutput, RgbColor* inputColor) {
HtmlColor(RgbColor(inputColor->R, inputColor->G, inputColor->B)).ToNumericalString(sOutput, 12);
2021-01-27 16:27:23 +00:00
}
2021-01-30 13:04:23 +00:00
void transformHtmltoStrip(RgbColor* outputColor, char* sInput) {
2021-01-27 16:27:23 +00:00
HtmlColor htmlTemp;
//Serial.print("HtmltoStrip ");
//Serial.println((char*)sInput);
2021-01-30 13:04:23 +00:00
htmlTemp.Parse<HtmlColorNames>( sInput );
2021-01-27 16:27:23 +00:00
RgbColor stripColor( htmlTemp );
2021-01-30 13:04:23 +00:00
//Serial.printf("StripColor: R:%i G:%i B:%i W:%i\n", stripColor.R, stripColor.G, stripColor.B, stripColor.W);
2021-01-27 16:27:23 +00:00
memcpy(outputColor, &stripColor, sizeof(stripColor));
}
2020-12-26 15:00:29 +00:00
#endif
2019-12-11 08:03:32 +00:00
const char* ntpServer = "pool.ntp.org";
2020-12-26 15:00:29 +00:00
const long gmtOffset_sec = 3600; //ToDo changable from user
2020-05-03 12:53:41 +00:00
const int daylightOffset_sec = 3600;
struct tm timeinfo;
2021-01-28 18:00:15 +00:00
2019-12-11 08:03:32 +00:00
volatile int currentSec = 59;
volatile int currentMin = 1;
2021-01-01 15:44:50 +00:00
volatile int currentHour = 2;
2021-01-30 13:04:23 +00:00
volatile bool NTPreachable = false;
2019-12-11 08:03:32 +00:00
2021-11-26 11:10:53 +00:00
volatile int MAX_BRIGHTNESS = 200;
2021-01-28 18:00:15 +00:00
#ifdef LDR_PIN
2019-12-11 08:03:32 +00:00
// variable for storing the potentiometer value
2020-12-26 15:00:29 +00:00
volatile unsigned int ldrValue = 0;
2021-11-26 11:10:53 +00:00
volatile unsigned int targetBrightness = MAX_BRIGHTNESS;
2021-01-28 18:00:15 +00:00
#endif
2019-12-11 08:03:32 +00:00
2020-05-03 12:53:41 +00:00
// WebPortal
const char thingName[] = "NTP-Clock-RGBLED";
2020-12-26 15:00:29 +00:00
const char wifiInitialApPassword[] = "12345678";
2020-05-03 12:53:41 +00:00
#define STRING_LEN 63
#define NUMBER_LEN 4
2021-01-26 20:44:46 +00:00
// -- Maximal length the input-range attributes can have.
//#define COLOR_ATTR_LENGTH 60
2020-05-03 12:53:41 +00:00
// -- Configuration specific key. The value should be modified if config structure was changed.
#define CONFIG_VERSION "V1.1.8"
2021-01-01 15:44:50 +00:00
2020-05-03 12:53:41 +00:00
DNSServer dnsServer;
WebServer server(80);
2021-01-01 15:44:50 +00:00
#ifdef ESP8266
ESP8266HTTPUpdateServer httpUpdater;
#elif defined(ESP32)
HTTPUpdateServer httpUpdater;
#endif
2020-05-03 12:53:41 +00:00
IotWebConf iotWebConf(thingName, &dnsServer, &server, wifiInitialApPassword, CONFIG_VERSION);
iotwebconf::ParameterGroup timeGroup = iotwebconf::ParameterGroup("Time", "Time settings");
iotwebconf::TextTParameter<STRING_LEN> ntpServerParam =
iotwebconf::Builder<iotwebconf::TextTParameter<STRING_LEN>>("ntpServer").
label("NTP Server").
defaultValue("pool.ntp.org").
build();
iotwebconf::ParameterGroup ledGroup = iotwebconf::ParameterGroup("LED", "LED settings");
iotwebconf::IntTParameter<int16_t> maxBrightnessParam =
iotwebconf::Builder<iotwebconf::IntTParameter<int16_t>>("Max Brightness").
label("Max brightness").
defaultValue(200).
min(MINIMAL_BRIGHTNESS).
max(MAX_BRIGHTNESS).
step(1).
build();
iotwebconf::CheckboxTParameter singleSecondParam =
iotwebconf::Builder<iotwebconf::CheckboxTParameter>("singleSecond").
label("single Second visible").
2021-05-06 20:41:54 +00:00
#if NUM_LEDS == 60
defaultValue(true).
build();
2021-05-07 14:17:23 +00:00
#else
defaultValue(false).
build();
2021-05-06 20:41:54 +00:00
#endif
iotwebconf::CheckboxTParameter allDotsOnParam =
iotwebconf::Builder<iotwebconf::CheckboxTParameter>("allDotsOn").
label("all Dots lighten on").
defaultValue(true).
build();
iotwebconf::CheckboxTParameter followingHourParam =
iotwebconf::Builder<iotwebconf::CheckboxTParameter>("followingHour").
label("following Hour").
2021-05-06 20:41:54 +00:00
#if NUM_LEDS == 60
defaultValue(true).
build();
2021-05-07 14:17:23 +00:00
#else
defaultValue(false).
build();
2021-05-06 20:41:54 +00:00
#endif
iotwebconf::ColorTParameter hourColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("Stundenfarbe").
label("Stundenfarbe").
defaultValue("#FFD700").
build();
iotwebconf::ColorTParameter minuteColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("Minutenfarbe").
label("Minutenfarbe").
defaultValue("#800000").
build();
iotwebconf::ColorTParameter secondsColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("Sekundenfarbe").
label("Sekundenfarbe").
defaultValue("#000000").
build();
iotwebconf::ColorTParameter highnoonColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("12 Uhr Farbe").
label("12 Uhr Farbe").
defaultValue("#C0C0C0").
build();
iotwebconf::ColorTParameter backlightColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("Hintergrundfarbe").
label("Hintergrundfarbe").
defaultValue("#1E2823").
build();
iotwebconf::ColorTParameter hourMarkingColorParam =
iotwebconf::Builder<iotwebconf::ColorTParameter>("Stundenmarkierung").
label("Stundenmarkierung").
defaultValue("#787878").
build();
2021-01-01 15:44:50 +00:00
// -- An instance must be created from the class defined above.
CustomHtmlFormatProvider customHtmlFormatProvider;
2019-12-11 08:03:32 +00:00
Task bootAnim(200, TASK_FOREVER, &bootAnimCallback);
Task clockTick(1000, TASK_FOREVER, &clockTickCallback);
Task ledRefresh(200, TASK_FOREVER, &ledRefreshCallback);
2021-01-28 18:00:15 +00:00
#ifdef LDR_PIN
2021-11-26 11:10:53 +00:00
Task brightnessAdjustment(10000, TASK_FOREVER, &brightnessAdjustmentCallback);
Task brightnessFading(333, TASK_FOREVER, &brightnessFadingCallback);
2021-01-28 18:00:15 +00:00
#endif
2021-06-28 19:07:58 +00:00
Task iotwebconfLoop(1000, TASK_FOREVER, &iotWebConfLoopCallback);
Scheduler runner;
2020-09-27 06:29:14 +00:00
void setup() {
2021-01-28 18:00:15 +00:00
#ifdef LDR_PIN
2020-12-26 15:00:29 +00:00
pinMode(LDR_PIN, INPUT_PULLUP);
2021-01-28 18:00:15 +00:00
#endif
2020-09-27 06:29:14 +00:00
pinMode(DATA_PIN, OUTPUT);
2019-12-11 08:03:32 +00:00
2020-09-27 06:29:14 +00:00
Serial.begin(SERIAL_BAUD);
2020-12-26 15:00:29 +00:00
Serial.flush();
2021-11-26 11:10:53 +00:00
delay(100);
Serial.println();
Serial.print("\n\n\nCPU Frequency is: ");
2021-01-28 18:00:15 +00:00
#ifdef ESP8266
Serial.print(ESP.getCpuFreqMHz());
Serial.println(" Mhz");
Serial.print("Chip ID: ");
Serial.println(ESP.getFlashChipId());
2021-01-28 18:00:15 +00:00
#elif defined(ESP32)
2021-11-26 11:10:53 +00:00
setCpuFrequencyMhz(160);
2020-12-26 15:00:29 +00:00
Serial.print(getCpuFrequencyMhz()); //Get CPU clock
Serial.println(" Mhz");
2021-11-26 11:10:53 +00:00
uint32_t Freq = getXtalFrequencyMhz();
Serial.print("XTAL Freq = ");
Serial.print(Freq);
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
2021-01-08 20:10:16 +00:00
Serial.print("MAC address: ");
Serial.println(WiFi.macAddress()); //Get CPU clock
2019-12-11 08:03:32 +00:00
#ifdef RGBW
Serial.println("RGBW");
#else
Serial.println("RGB");
#endif
2020-09-27 06:29:14 +00:00
strip.Begin();
2020-12-26 15:00:29 +00:00
strip.ClearTo(white);
strip.SetBrightness( MINIMAL_BRIGHTNESS );
2020-09-27 06:29:14 +00:00
strip.Show();
runner.init();
runner.addTask(ledRefresh);
runner.addTask(clockTick);
2021-01-28 18:00:15 +00:00
#ifdef LDR_PIN
2021-11-26 11:10:53 +00:00
runner.addTask(brightnessAdjustment);
runner.addTask(brightnessFading);
2021-01-28 18:00:15 +00:00
#endif
runner.addTask(bootAnim);
runner.addTask(iotwebconfLoop);
bootAnim.enable();
2021-10-14 12:04:14 +00:00
iotwebconfLoop.enable();
2019-12-11 08:03:32 +00:00
2020-05-03 12:53:41 +00:00
iotWebConf_Setup();
2020-12-26 15:00:29 +00:00
//Serial.end();
#ifdef ESP8266
ESP.wdtDisable();
ESP.wdtEnable(1000);
#endif
#if defined(ESP32)
#endif
2019-12-11 08:03:32 +00:00
}
2020-05-03 12:53:41 +00:00
2019-12-11 08:03:32 +00:00
void loop()
{
runner.execute();
yield();
2021-11-26 11:10:53 +00:00
#ifdef ESP8266
ESP.wdtFeed();
2021-11-26 11:10:53 +00:00
#endif
/*
while (Serial.available())
2020-12-26 15:00:29 +00:00
Serial.read();
*/
}