From c1a12d93f0566426394fc477a9a4d165c840f0de Mon Sep 17 00:00:00 2001
From: jonny_ji7 <jonny@wwad.de>
Date: Tue, 23 Aug 2022 11:55:02 +0200
Subject: [PATCH] Add blink method to display class

- Add method to trigger blinking of the display for a certain count and durations
  also with a optional off-string

- Add 3x blinking after applying a new target length with preset or set
  buttons
---
 main/control.cpp |   8 ++++
 main/display.cpp | 107 +++++++++++++++++++++++++++++++++--------------
 main/display.hpp |  15 +++++--
 3 files changed, 95 insertions(+), 35 deletions(-)

diff --git a/main/control.cpp b/main/control.cpp
index 29e23ec..2557cf3 100644
--- a/main/control.cpp
+++ b/main/control.cpp
@@ -237,6 +237,7 @@ void task_control(void *pvParameter)
         }
         if (SW_SET.fallingEdge) {
             buzzer.beep(2, 70, 50);
+            displayBot.blink(3, 100, 100, "S0LL    ");
         }
 
 
@@ -245,14 +246,17 @@ void task_control(void *pvParameter)
             if (SW_PRESET1.risingEdge){
                 lengthTarget = 1000;
                 buzzer.beep(lengthTarget/1000, 25, 30);
+                displayBot.blink(3, 100, 100, "S0LL    ");
             }
             else if (SW_PRESET2.risingEdge) {
                 lengthTarget = 5000;
                 buzzer.beep(lengthTarget/1000, 25, 30);
+                displayBot.blink(3, 100, 100, "S0LL    ");
             }
             else if (SW_PRESET3.risingEdge) {
                 lengthTarget = 10000;
                 buzzer.beep(lengthTarget/1000, 25, 30);
+                displayBot.blink(3, 100, 100, "S0LL    ");
             }
         }
 
@@ -339,6 +343,8 @@ void task_control(void *pvParameter)
         //--------------------------
         //-------- display1 --------
         //--------------------------
+        //run handle function
+        displayTop.handle();
         //show current position on display
         sprintf(buf_tmp, "1ST %5.4f", (float)lengthNow/1000);
         //                123456789
@@ -350,6 +356,8 @@ void task_control(void *pvParameter)
         //--------------------------
         //-------- display2 --------
         //--------------------------
+        //run handle function
+        displayBot.handle();
         //setting target length: blink target length
         if (SW_SET.state == true){
             sprintf(buf_tmp, "S0LL%5.3f", (float)lengthTarget/1000);
diff --git a/main/display.cpp b/main/display.cpp
index 9e8d493..d5b5fa0 100644
--- a/main/display.cpp
+++ b/main/display.cpp
@@ -34,7 +34,7 @@ max7219_t display_init(){
     ESP_ERROR_CHECK(max7219_init_desc(&dev, HOST, MAX7219_MAX_CLOCK_SPEED_HZ, DISPLAY_PIN_NUM_CS));
     ESP_ERROR_CHECK(max7219_init(&dev));
     //0...15
-    ESP_ERROR_CHECK(max7219_set_brightness(&dev, 9));
+    ESP_ERROR_CHECK(max7219_set_brightness(&dev, 8));
     return dev;
     //display = dev;
     ESP_LOGI(TAG, "initializing display - done");
@@ -84,15 +84,21 @@ handledDisplay::handledDisplay(max7219_t displayDevice, uint8_t posStart_f) {
 //function that displays a given string on the display
 void handledDisplay::showString(const char * buf, uint8_t pos_f){
     //calculate actual absolute position
-    uint8_t pos = posStart + pos_f;
-    //draw string on display
-    max7219_draw_text_7seg(&dev, pos, buf);
-    //disable blinking mode
-    blinkMode = false;
+    posCurrent = posStart + pos_f;
+    //copy the desired string
+    strcpy(strOn, buf);
+    //exit blinking mode
+    if (mode == displayMode::BLINK_STRINGS){
+        mode = displayMode::NORMAL;
+    }
+    handle(); //draws the text depending on mode
 }
 
 
 
+//TODO: blinkStrings() and blink() are very similar - can be optimized?
+//only difficulty currently is the reset behaivor of blinkStrings through showString (blink does not reset)
+
 //----------------------------------
 //---------- blinkStrings ----------
 //----------------------------------
@@ -103,10 +109,11 @@ void handledDisplay::blinkStrings(const char * strOn_f, const char * strOff_f, u
     strcpy(strOff, strOff_f);
     msOn = msOn_f;
     msOff = msOff_f;
-    //if changed to blink mode just now
-    if (blinkMode == false) {
+    //if changed to blink mode just now:
+    if (mode != displayMode::BLINK_STRINGS) {
+        //switch mode
         ESP_LOGI(TAG, "pos:%i changing to blink mode", posStart);
-        blinkMode = true;
+        mode = displayMode::BLINK_STRINGS;
         //start with on state
         state = true;
         timestampOn = esp_log_timestamp();
@@ -117,33 +124,71 @@ void handledDisplay::blinkStrings(const char * strOn_f, const char * strOff_f, u
 
 
 
+//-------------------------------
+//------------ blink ------------
+//-------------------------------
+//function triggers certain count and interval of off durations
+void handledDisplay::blink(uint8_t count_f, uint32_t msOn_f, uint32_t msOff_f, const char * strOff_f) {
+    //set to blink mode
+    mode = displayMode::BLINK;
+    //copy parameters
+    count = count_f;
+    msOn = msOn_f;
+    msOff = msOff_f;
+    strcpy(strOff, strOff_f);
+    //FIXME this strings length must be dynamic depending on display size (posEnd - posStart) -> otherwise overwrites next segments if other display size or start pos
+    ESP_LOGI(TAG, "start blinking: count=%i  on/off=%d/%d", count, msOn, msOff);
+    //start with off state
+    state = false;
+    timestampOff = esp_log_timestamp();
+    //run handle function for display update
+    handle();
+}
+
+
+
 //--------------------------------
 //------------ handle ------------
 //--------------------------------
-//function that handles blinking of display2
+//function that handles time based modes
+//writes text to the 7 segment display depending on the current mode
 void handledDisplay::handle() {
-    if (blinkMode == false){
-        return; //not in blinking mode - nothing todo 
-    }
+    switch (mode){
+        case displayMode::NORMAL:
+            //daw given string
+            max7219_draw_text_7seg(&dev, posCurrent, strOn);
+            break;
 
-    //--- define state on/off ---
-    if (state == true){ //display in ON state
-        if (esp_log_timestamp() - timestampOn > msOn){
-            state = false;
-            timestampOff = esp_log_timestamp();
-        }
-    } else { //display in OFF state
-        if (esp_log_timestamp() - timestampOff > msOff) {
-            state = true;
-            timestampOn = esp_log_timestamp();
-        }
-    }
+        case displayMode::BLINK:
+        case displayMode::BLINK_STRINGS:
+            //--- define state on/off ---
+            if (state == true){ //display in ON state
+                if (esp_log_timestamp() - timestampOn > msOn){
+                    state = false;
+                    timestampOff = esp_log_timestamp();
+                    //decrement remaining counts in BLINK mode each cycle
+                    if (mode == displayMode::BLINK) count--;
+                }
+            } else { //display in OFF state
+                if (esp_log_timestamp() - timestampOff > msOff) {
+                    state = true;
+                    timestampOn = esp_log_timestamp();
+                }
+            }
+            //--- draw text of current state ---
+            if (state) {
+                max7219_draw_text_7seg(&dev, posStart, strOn);
+            } else {
+                max7219_draw_text_7seg(&dev, posStart, strOff);
+            }
 
-    //--- draw text of current state ---
-    if (state) {
-        max7219_draw_text_7seg(&dev, posStart, strOn);
-    } else {
-        max7219_draw_text_7seg(&dev, posStart, strOff);
+            //--- check finished condition in BLINK mode ---
+            if (mode == displayMode::BLINK){
+                if (count == 0) {
+                    mode = displayMode::NORMAL;
+                    ESP_LOGI(TAG, "finished blinking -> normal mode");
+                }
+            }
+            break;
     }
 }
-
diff --git a/main/display.hpp b/main/display.hpp
index b3a916a..d62e684 100644
--- a/main/display.hpp
+++ b/main/display.hpp
@@ -24,6 +24,7 @@ max7219_t display_init();
 //show welcome message on the entire display
 void display_ShowWelcomeMsg(max7219_t displayDevice);
 
+enum class displayMode {NORMAL, BLINK_STRINGS, BLINK};
 
 class handledDisplay {
     public:
@@ -35,9 +36,13 @@ class handledDisplay {
         void showString(const char * buf, uint8_t pos = 0);
         //function switches between two strings in a given interval
         void blinkStrings(const char * strOn, const char * strOff, uint32_t msOn, uint32_t msOff);
+        //triggers certain count of blinking between currently shown string and off or optional certain string
+        void blink(uint8_t count, uint32_t msOn, uint32_t msOff, const char * strOff = "        ");
+        //function that handles time based modes and writes text to display
+        void handle(); //has to be run regularly when blink method is used
+
+        //TODO: blinkStrings and blink are very similar - optimize?
         //TODO: add 'scroll string' method
-        //function that handles blinking of display
-        void handle();
 
     private:
 
@@ -45,12 +50,14 @@ class handledDisplay {
         //config
         max7219_t dev;
         uint8_t posStart; //absolute position this display instance starts (e.g. multiple or very long 7 segment display)
+        uint8_t posCurrent;
 
-        //blink mode
+        displayMode mode = displayMode::NORMAL;
+        //blink modes
+        uint8_t count = 0;
         char strOn[20];
         char strOff[20];
         bool state = false;
-        bool blinkMode = false;
         uint32_t msOn;
         uint32_t msOff;
         uint32_t timestampOn;