diff --git a/usermods/usermod_v2_ping_pong_clock/readme.md b/usermods/usermod_v2_ping_pong_clock/readme.md new file mode 100644 index 00000000..8731222f --- /dev/null +++ b/usermods/usermod_v2_ping_pong_clock/readme.md @@ -0,0 +1,8 @@ +# Ping Pong LED Clock + +This Usermod File contains a modification to use WLED in combination with the Ping Pong Ball LED Clock as built in [Instructables](https://www.instructables.com/Ping-Pong-Ball-LED-Clock/). + +## Installation + +To install this Usermod you instruct PlatformIO to compile the Projekt with the USERMOD_PING_PONG_CLOCK flag. WLED then automatically provides you with various settings in the Usermod Page to configure this Usermod. +Note: If your clock is bigger or smaller then mine, you may have to update the led indices for the indivdual numbers and the base indices. diff --git a/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.h b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.h new file mode 100644 index 00000000..a690c1b1 --- /dev/null +++ b/usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.h @@ -0,0 +1,119 @@ +#pragma once + +#include "wled.h" + +class PingPongClockUsermod : public Usermod +{ +private: + // Private class members. You can declare variables and functions only accessible to your usermod here + unsigned long lastTime = 0; + bool colonOn = true; + + // ---- Variables modified by settings below ----- + // set your config variables to their boot default value (this can also be done in readFromConfig() or a constructor if you prefer) + bool pingPongClockEnabled = true; + int colorR = 0xFF; + int colorG = 0xFF; + int colorB = 0xFF; + + // ---- Variables for correct LED numbering below, edit only if your clock is built different ---- + + int baseH = 43; // Adress for the one place of the hours + int baseHH = 7; // Adress for the tens place of the hours + int baseM = 133; // Adress for the one place of the minutes + int baseMM = 97; // Adress for the tens place of the minutes + int colon1 = 79; // Adress for the first colon led + int colon2 = 80; // Adress for the second colon led + + // Matrix for the illumination of the numbers + // Note: These only define the increments of the base adress. e.g. to define the second Minute you have to add the baseMM to every led position + const int numbers[10][10] = + { + { 0, 1, 4, 6, 13, 15, 18, 19, -1, -1 }, // 0: null + { 13, 14, 15, 18, 19, -1, -1, -1, -1, -1 }, // 1: eins + { 0, 4, 5, 6, 13, 14, 15, 19, -1, -1 }, // 2: zwei + { 4, 5, 6, 13, 14, 15, 18, 19, -1, -1 }, // 3: drei + { 1, 4, 5, 14, 15, 18, 19, -1, -1, -1 }, // 4: vier + { 1, 4, 5, 6, 13, 14, 15, 18, -1, -1 }, // 5: fünf + { 0, 5, 6, 10, 13, 14, 15, 18, -1, -1 }, // 6: sechs + { 4, 6, 9, 13, 14, 19, -1, -1, -1, -1 }, // 7: sieben + { 0, 1, 4, 5, 6, 13, 14, 15, 18, 19 }, // 8: acht + { 1, 4, 5, 6, 9, 13, 14, 19, -1, -1 } // 9: neun + }; + +public: + void setup() + { } + + void loop() + { + if (millis() - lastTime > 1000) + { + lastTime = millis(); + colonOn = !colonOn; + } + } + + void addToJsonInfo(JsonObject& root) + { + JsonObject user = root["u"]; + if (user.isNull()) user = root.createNestedObject("u"); + + JsonArray lightArr = user.createNestedArray("Uhrzeit-Anzeige"); //name + lightArr.add(pingPongClockEnabled ? "aktiv" : "inaktiv"); //value + lightArr.add(""); //unit + } + + void addToConfig(JsonObject &root) + { + JsonObject top = root.createNestedObject("Ping Pong Clock"); + top["enabled"] = pingPongClockEnabled; + top["colorR"] = colorR; + top["colorG"] = colorG; + top["colorB"] = colorB; + } + + bool readFromConfig(JsonObject &root) + { + JsonObject top = root["Ping Pong Clock"]; + + bool configComplete = !top.isNull(); + + configComplete &= getJsonValue(top["enabled"], pingPongClockEnabled); + configComplete &= getJsonValue(top["colorR"], colorR); + configComplete &= getJsonValue(top["colorG"], colorG); + configComplete &= getJsonValue(top["colorB"], colorB); + + return configComplete; + } + + void drawNumber(int base, int number) + { + for(int i = 0; i < 10; i++) + { + if(numbers[number][i] > -1) + strip.setPixelColor(numbers[number][i] + base, RGBW32(colorR, colorG, colorB, 0)); + } + } + + void handleOverlayDraw() + { + if(pingPongClockEnabled){ + if(colonOn) + { + strip.setPixelColor(colon1, RGBW32(colorR, colorG, colorB, 0)); + strip.setPixelColor(colon2, RGBW32(colorR, colorG, colorB, 0)); + } + drawNumber(baseHH, (hour(localTime) / 10) % 10); + drawNumber(baseH, hour(localTime) % 10); + drawNumber(baseM, (minute(localTime) / 10) % 10); + drawNumber(baseMM, minute(localTime) % 10); + } + } + + uint16_t getId() + { + return USERMOD_ID_PING_PONG_CLOCK; + } + +}; diff --git a/wled00/const.h b/wled00/const.h index 502986c4..874776e3 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -94,6 +94,7 @@ #define USERMOD_ID_SMARTNEST 31 //Usermod "usermod_smartnest.h" #define USERMOD_ID_AUDIOREACTIVE 32 //Usermod "audioreactive.h" #define USERMOD_ID_ANALOG_CLOCK 33 //Usermod "Analog_Clock.h" +#define USERMOD_ID_PING_PONG_CLOCK 34 //Usermod "usermod_v2_ping_pong_clock.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot diff --git a/wled00/usermods_list.cpp b/wled00/usermods_list.cpp index 51c7fcd6..ed2a919a 100644 --- a/wled00/usermods_list.cpp +++ b/wled00/usermods_list.cpp @@ -143,6 +143,10 @@ #include "../usermods/Analog_Clock/Analog_Clock.h" #endif +#ifdef USERMOD_PING_PONG_CLOCK +#include "../usermods/usermod_v2_ping_pong_clock/usermod_v2_ping_pong_clock.h" +#endif + void registerUsermods() { /* @@ -262,7 +266,7 @@ void registerUsermods() #ifdef USERMOD_SI7021_MQTT_HA usermods.add(new Si7021_MQTT_HA()); #endif - + #ifdef USERMOD_SMARTNEST usermods.add(new Smartnest()); #endif @@ -274,4 +278,8 @@ void registerUsermods() #ifdef USERMOD_ANALOG_CLOCK usermods.add(new AnalogClockUsermod()); #endif + + #ifdef USERMOD_PING_PONG_CLOCK + usermods.add(new PingPongClockUsermod()); + #endif }