From 7cb84d1660780000a23063c05a27524dbb0e3272 Mon Sep 17 00:00:00 2001 From: Matthias Mitscherlich Date: Wed, 18 Jan 2023 14:54:23 +0100 Subject: [PATCH] Added clock and wordclock - functional the matrix needs an update, though. Not all words are well put --- code/main/CMakeLists.txt | 2 + code/main/inc/clock.h | 105 ++++++++++++++++++ code/main/inc/ledmatrix.h | 9 +- code/main/inc/wordclock.h | 130 ++++++++++++++++++++++ code/main/main.cpp | 33 +++--- code/main/src/clock.cpp | 213 ++++++++++++++++++++++++++++++++++++ code/main/src/ledmatrix.cpp | 9 +- code/main/src/wordclock.cpp | 191 ++++++++++++++++++++++++++++++++ 8 files changed, 667 insertions(+), 25 deletions(-) create mode 100644 code/main/inc/clock.h create mode 100644 code/main/inc/wordclock.h create mode 100644 code/main/src/clock.cpp create mode 100644 code/main/src/wordclock.cpp diff --git a/code/main/CMakeLists.txt b/code/main/CMakeLists.txt index c8c9896..d9827e0 100644 --- a/code/main/CMakeLists.txt +++ b/code/main/CMakeLists.txt @@ -9,6 +9,8 @@ idf_component_register( "src/logger.cpp" "src/led_strip_encoder.c" "src/ledmatrix.cpp" + "src/clock.cpp" + "src/wordclock.cpp" INCLUDE_DIRS # optional, add here public include directories "inc" PRIV_INCLUDE_DIRS # optional, add here private include directories diff --git a/code/main/inc/clock.h b/code/main/inc/clock.h new file mode 100644 index 0000000..0d77506 --- /dev/null +++ b/code/main/inc/clock.h @@ -0,0 +1,105 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file clock.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_INC_CLOCK_H_ +#define MAIN_INC_CLOCK_H_ + +/** + * clock implementation + * \defgroup clock + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly + + + +// ProjectIncludes +// All include files that are provided by the project +#include "time.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + +class Clock +{ + public: + + enum FifthsIndication + { + None_FifthIndication = 0, + Five, + Ten, + Quarter + }; + + enum BeforeAfterIndication + { + None_BeforeAfter = 0, + Before, + After + }; + + struct TimeStructure + { + bool prefix; + bool almost; + FifthsIndication fifths; + BeforeAfterIndication beforeAfter; + bool half; + int hours; + bool hourPostfix; + }; + + Clock(); + + TimeStructure updateTime(void); + + private: + time_t currentTime; + + void toString(TimeStructure* timestructure); + int calculateHours(int hour); +}; + + +/** @} */ + +#endif /* MAIN_INC_CLOCK_H_ */ diff --git a/code/main/inc/ledmatrix.h b/code/main/inc/ledmatrix.h index 9126b9f..a1c5880 100644 --- a/code/main/inc/ledmatrix.h +++ b/code/main/inc/ledmatrix.h @@ -103,9 +103,16 @@ typedef struct class LEDMatrix { public: + + struct coordinate + { + int x; + int y; + }; + LEDMatrix(LEDMatrix_Parameters_t* parameters); - bool setPixelValue(unsigned int row, unsigned int colum, bool value); + bool setPixelValue(unsigned int colum, unsigned int row, bool value); void setGlobalColour(uint8_t red, uint8_t green, uint8_t blue); void clear(void); diff --git a/code/main/inc/wordclock.h b/code/main/inc/wordclock.h new file mode 100644 index 0000000..6b70984 --- /dev/null +++ b/code/main/inc/wordclock.h @@ -0,0 +1,130 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file wordclock.h +/// \brief File description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +#ifndef MAIN_INC_WORDCLOCK_H_ +#define MAIN_INC_WORDCLOCK_H_ + +/** + * wordclock implementation + * \defgroup wordclock + * \brief {group_description} + * \addtogroup {Layer} + * + * Detailed description + * @{ + */ + + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +// CompilerIncludes +// All include files that are provided by the compiler directly + + + +// ProjectIncludes +// All include files that are provided by the project +#include "ledmatrix.h" +#include "clock.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions. +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + +class Wordclock +{ + public: + enum language + { + NL = 0, + EN, + NumberOfLanguages + }; + + Wordclock(LEDMatrix* matrix); + + void update(Clock::TimeStructure* timestructure); + + private: + + LEDMatrix* matrix; + language language; + + struct word + { + LEDMatrix::coordinate position; + int length; + }; + + struct wordmap + { + struct word prefix; + struct word prefix_additional; + struct word almost; + struct word five; + struct word ten; + struct word quarter; + struct word before; + struct word after; + struct word half; + struct word hour[12]; + struct word hourPostfix; + + }; + + struct wordmap languagemaps[NumberOfLanguages] + { + { + // prefix + {0,0,3}, {4,0,2}, + // almost + {0,0,0}, + // five/ten/quarter + {7,0,4}, {0,1,4}, {6,2,5}, + // before/after + {7,1,4}, {0,2,4}, +// {0,4,4}, {7,3,4}, + // half + {0,3,4}, + // hours + {{7,4,3},{0,5,4},{7,5,4},{0,6,4},{4,6,4},{6,8,3},{0,7,5},{0,8,4},{6,7,5},{4,8,4},{8,8,3},{0,9,6}}, + // hour postfix + {8,9,3} + } + }; + + + +}; + + +/** @} */ + +#endif /* MAIN_INC_WORDCLOCK_H_ */ diff --git a/code/main/main.cpp b/code/main/main.cpp index 3f11aab..3ddb403 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -1,11 +1,11 @@ +#include "string.h" + #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_event.h" #include "esp_log.h" -#include "esp_sntp.h" #include "esp_wifi.h" -#include "time.h" #include "nvs_flash.h" @@ -19,12 +19,14 @@ #include "inc/logger.h" #include "inc/wifi.h" +#include "clock.h" +#include "wordclock.h" + static const uart_port_t uartPort = UART_NUM_0; static TaskHandle_t devTaskHandle = NULL; static void devTask(void* parameters); static GPIO gpio0(4, GPIO_DIRECTION_OUTPUT); static GPIO gpio1(18, GPIO_DIRECTION_OUTPUT); -static time_t currentTime; static rmt_channel_handle_t led_chan = NULL; static rmt_transmit_config_t tx_config; @@ -113,6 +115,8 @@ extern "C" void app_main(void) ledmatrix_parameters.width = 11; LEDMatrix LEDMatrix(&ledmatrix_parameters); + // Set an initial colour map + LEDMatrix.setGlobalColour(0x10, 0, 0x04); // Create the development task if(xTaskCreate(devTask, "DevTask", 2048, NULL, 3, &devTaskHandle) != pdPASS) @@ -123,28 +127,17 @@ extern "C" void app_main(void) Wifi wifi; wifi.start_client(); - // Start NTP - setenv("TZ", "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", 1); - tzset(); - sntp_setoperatingmode(SNTP_OPMODE_POLL); - sntp_setservername(0, "pool.ntp.org"); - sntp_init(); + Clock clock; + Clock::TimeStructure time; - - unsigned int row = 0; - unsigned int colum = 0; + Wordclock wordclock(&LEDMatrix); while (true) { + time = clock.updateTime(); + wordclock.update(&time); - struct tm tm; - time(¤tTime); - localtime_r(¤tTime, &tm); - - LOGGER_INFO("%lld\n\r", currentTime); - LOGGER_INFO("%02i:%02i:%02i\n\r", tm.tm_hour, tm.tm_min, tm.tm_sec); - - vTaskDelay(300); + vTaskDelay(1000); } } diff --git a/code/main/src/clock.cpp b/code/main/src/clock.cpp new file mode 100644 index 0000000..36a556e --- /dev/null +++ b/code/main/src/clock.cpp @@ -0,0 +1,213 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file clock.cpp +/// \brief Description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +#include "clock.h" + +#include "esp_sntp.h" +#include "esp_wifi.h" + +#include "logger.h" +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// File-scope variables +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +Clock::Clock() +{ + Clock::currentTime = 0; + + // Start NTP + setenv("TZ", "CET-1CEST-2,M3.5.0/02:00:00,M10.5.0/03:00:00", 1); + tzset(); + sntp_setoperatingmode(SNTP_OPMODE_POLL); + sntp_setservername(0, "pool.ntp.org"); + sntp_init(); +} + +Clock::TimeStructure Clock::updateTime(void) +{ + struct tm tm; + time(¤tTime); +// currentTime += 10; + localtime_r(¤tTime, &tm); + + LOGGER_INFO("%lld\n\r", currentTime); + LOGGER_INFO("%02i:%02i:%02i\n\r", tm.tm_hour, tm.tm_min, tm.tm_sec); + + // Construct the time structure + TimeStructure timeStructure; + // Show the prefix + timeStructure.prefix = true; + + if (tm.tm_min < 4) + { + timeStructure.fifths = None_FifthIndication; + timeStructure.beforeAfter = None_BeforeAfter; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour); + timeStructure.hourPostfix = true; + } + else if (tm.tm_min < 9) + { + timeStructure.fifths = Five; + timeStructure.beforeAfter = After; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 14) + { + timeStructure.fifths = Ten; + timeStructure.beforeAfter = After; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 19) + { + timeStructure.fifths = Quarter; + timeStructure.beforeAfter = After; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 24) + { + timeStructure.fifths = Ten; + timeStructure.beforeAfter = Before; + timeStructure.half = true; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 29) + { + timeStructure.fifths = Five; + timeStructure.beforeAfter = Before; + timeStructure.half = true; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 34) + { + timeStructure.fifths = None_FifthIndication; + timeStructure.beforeAfter = None_BeforeAfter; + timeStructure.half = true; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 39) + { + timeStructure.fifths = Five; + timeStructure.beforeAfter = After; + timeStructure.half = true; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 44) + { + timeStructure.fifths = Ten; + timeStructure.beforeAfter = After; + timeStructure.half = true; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 49) + { + timeStructure.fifths = Quarter; + timeStructure.beforeAfter = Before; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 54) + { + timeStructure.fifths = Ten; + timeStructure.beforeAfter = Before; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + else if (tm.tm_min < 59) + { + timeStructure.fifths = Five; + timeStructure.beforeAfter = Before; + timeStructure.half = false; + timeStructure.hours = calculateHours(tm.tm_hour + 1); + timeStructure.hourPostfix = false; + } + + toString(&timeStructure); + + return timeStructure; +} + + +int Clock::calculateHours(int hour) +{ + int hours; + // Calculate hours to 12hour system + if (hour > 12) + { + hours = hour - 12; + } + else + { + hours = hour; + } + return hours; +} + +void Clock::toString(TimeStructure* timestructure) +{ + LOGGER_SUCCESS("%s%s%s%s%d%s", timestructure->prefix ? "Het is " : "", + timestructure->fifths == Five ? "Vijf " : + timestructure->fifths == Ten ? "Tien " : + timestructure->fifths == Quarter ? "kwart ": "", + timestructure->beforeAfter == Before ? "voor " : + timestructure->beforeAfter == After ? "over " : "", + timestructure->half ? "half " : "", + timestructure->hours, + timestructure->hourPostfix ? " uur" : "" + ); +} + diff --git a/code/main/src/ledmatrix.cpp b/code/main/src/ledmatrix.cpp index c0f025b..bd8b7a7 100644 --- a/code/main/src/ledmatrix.cpp +++ b/code/main/src/ledmatrix.cpp @@ -72,7 +72,7 @@ LEDMatrix::LEDMatrix(LEDMatrix_Parameters_t* parameters) LEDMatrix::clear(); } -bool LEDMatrix::setPixelValue(unsigned int row, unsigned int colum, bool value) +bool LEDMatrix::setPixelValue(unsigned int colum, unsigned int row, bool value) { bool returnValue = true; @@ -146,9 +146,9 @@ void LEDMatrix::clear(void) for (int i = 0; i < numberOfPixels; i++) { matrix[i].on = false; - matrix[i].red = 0; - matrix[i].green = 0; - matrix[i].blue = 0; +// matrix[i].red = 0; +// matrix[i].green = 0; +// matrix[i].blue = 0; } // Release the semaphore to trigger an matrix update xSemaphoreGive(LEDMatrix::taskSemaphore); @@ -167,6 +167,7 @@ void LEDMatrix::matrixTask(void* parameters) xSemaphoreTake(ledmatrix->taskSemaphore, 1000); for (int i = 0; i < ledmatrix->numberOfPixels; i++) { + if (ledmatrix->matrix[i].on) { matrix[i * 3 + LEDMATRIX_RED_INDEX] = ledmatrix->matrix[i].red; diff --git a/code/main/src/wordclock.cpp b/code/main/src/wordclock.cpp new file mode 100644 index 0000000..c19d2cb --- /dev/null +++ b/code/main/src/wordclock.cpp @@ -0,0 +1,191 @@ +// -------------------------------------------------------------------------------------------------------------------- +/// \file wordclock.cpp +/// \brief Description +// -------------------------------------------------------------------------------------------------------------------- +// +// vbchaos software design +// +// -------------------------------------------------------------------------------------------------------------------- +/// $Revision: $ +/// $Author: $ +/// $Date: $ +// (c) 2023 vbchaos +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// Include files +// -------------------------------------------------------------------------------------------------------------------- + +#include "wordclock.h" + +// -------------------------------------------------------------------------------------------------------------------- +// Constant and macro definitions +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Type definitions +// -------------------------------------------------------------------------------------------------------------------- + + +// -------------------------------------------------------------------------------------------------------------------- +// File-scope variables +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function declarations +// -------------------------------------------------------------------------------------------------------------------- + + + +// -------------------------------------------------------------------------------------------------------------------- +// Function definitions +// -------------------------------------------------------------------------------------------------------------------- + +Wordclock::Wordclock(LEDMatrix* matrix) +{ + Wordclock::matrix = matrix; + // Initial language set + Wordclock::language = NL; +} + + +void Wordclock::update(Clock::TimeStructure* time) +{ + // Clear the matrix before setting a new time + matrix->clear(); + + if (time->prefix) + { + if (languagemaps[language].prefix.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].prefix.length; i++) + { + matrix->setPixelValue(languagemaps[language].prefix.position.x + i, languagemaps[language].prefix.position.y, true); + } + } + + if (languagemaps[language].prefix_additional.length > 0) + { + // Enable Prefix addition on the matrix + for (int i = 0; i < languagemaps[language].prefix_additional.length; i++) + { + matrix->setPixelValue(languagemaps[language].prefix_additional.position.x + i, languagemaps[language].prefix_additional.position.y, true); + } + } + } + + if (time->almost) + { + if (languagemaps[language].almost.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].almost.length; i++) + { + matrix->setPixelValue(languagemaps[language].almost.position.x + i, languagemaps[language].almost.position.y, true); + } + } + } + + if (time->fifths == Clock::Five) + { + if (languagemaps[language].five.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].five.length; i++) + { + matrix->setPixelValue(languagemaps[language].five.position.x + i, languagemaps[language].five.position.y, true); + } + } + } + else if (time->fifths == Clock::Ten) + { + if (languagemaps[language].ten.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].ten.length; i++) + { + matrix->setPixelValue(languagemaps[language].ten.position.x + i, languagemaps[language].ten.position.y, true); + } + } + } + else if (time->fifths == Clock::Quarter) + { + if (languagemaps[language].quarter.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].quarter.length; i++) + { + matrix->setPixelValue(languagemaps[language].quarter.position.x + i, languagemaps[language].quarter.position.y, true); + } + } + } + + if (time->beforeAfter == Clock::Before) + { + if (languagemaps[language].before.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].before.length; i++) + { + matrix->setPixelValue(languagemaps[language].before.position.x + i, languagemaps[language].before.position.y, true); + } + } + } + else if (time->beforeAfter == Clock::After) + { + if (languagemaps[language].after.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].after.length; i++) + { + matrix->setPixelValue(languagemaps[language].after.position.x + i, languagemaps[language].after.position.y, true); + } + } + } + + if (time->half) + { + if (languagemaps[language].half.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].half.length; i++) + { + matrix->setPixelValue(languagemaps[language].half.position.x + i, languagemaps[language].half.position.y, true); + } + } + } + + if ((time->hours > 0) && (time->hours < 12)) + { + if (languagemaps[language].hour[time->hours - 1].length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].hour[time->hours - 1].length; i++) + { + matrix->setPixelValue(languagemaps[language].hour[time->hours - 1].position.x + i, languagemaps[language].hour[time->hours - 1].position.y, true); + } + } + } + + + if (time->hourPostfix) + { + if (languagemaps[language].hourPostfix.length > 0) + { + // Enable Prefix on the matrix + for (int i = 0; i < languagemaps[language].hourPostfix.length; i++) + { + matrix->setPixelValue(languagemaps[language].hourPostfix.position.x + i, languagemaps[language].hourPostfix.position.y, true); + } + } + } + + +} +