From 586c335896e8dd196b0f4950680421e29186cf8e Mon Sep 17 00:00:00 2001
From: jonny_ji7 <jonny@wwad.de>
Date: Mon, 22 Aug 2022 16:28:42 +0200
Subject: [PATCH] Create 'handledDisplay' class

To abstract rather complex functions for 7 segment displays e.g. blink text, scroll
text... a class was created.

This makes it possible to have 2 instances for displayTop and
displayBottom resulting in no duplicate code
---
 main/control.cpp |  15 ++--
 main/control.hpp |   2 +
 main/display.cpp | 179 +++++++++++++++++++++--------------------------
 main/display.hpp |  46 +++++++++---
 4 files changed, 129 insertions(+), 113 deletions(-)

diff --git a/main/control.cpp b/main/control.cpp
index 1de6edc..3441bb7 100644
--- a/main/control.cpp
+++ b/main/control.cpp
@@ -145,12 +145,15 @@ void task_control(void *pvParameter)
     encoder_queue = init_encoder(&encoder);
 
     //initialize display
-    display_init(); //outsourced in display.c
+    max7219_t two7SegDisplays = display_init();
+    //create two separate handled display instances
+    handledDisplay displayTop(two7SegDisplays, 0);
+    handledDisplay displayBot(two7SegDisplays, 8);
 
     //--- display welcome msg ---
     //display welcome message on two 7 segment displays
     //currently show name and date and scrolling 'hello'
-    display_ShowWelcomeMsg();
+    display_ShowWelcomeMsg(two7SegDisplays);
 
 
     //================
@@ -338,7 +341,7 @@ void task_control(void *pvParameter)
         //                123456789
         //limit length to 8 digits + decimal point (drop decimal places when it does not fit)
         sprintf(buf_disp1, "%.9s", buf_tmp);
-        display1_showString(buf_disp1);
+        displayTop.showString(buf_disp1);
 
 
         //--------------------------
@@ -347,18 +350,18 @@ void task_control(void *pvParameter)
         //setting target length: blink target length
         if (SW_SET.state == true){
             sprintf(buf_tmp, "S0LL%5.3f", (float)lengthTarget/1000);
-            display2_blinkStrings(buf_tmp, "        ", 400, 100);
+            displayBot.blinkStrings(buf_tmp, "        ", 300, 100);
         }
         //manual state: blink "manual"
         else if (controlState == MANUAL) {
-            display2_blinkStrings(" MANUAL ", "        ", 1000, 500);
+            displayBot.blinkStrings(" MANUAL ", "        ", 1000, 800);
         }
         //otherwise show target length
         else {
             //sprintf(buf_disp2, "%06.1f cm", (float)lengthTarget/10); //cm
             sprintf(buf_tmp, "S0LL%5.3f", (float)lengthTarget/1000); //m
             //                1234  5678
-            display2_showString(buf_tmp);
+            displayBot.showString(buf_tmp);
         }
 
 
diff --git a/main/control.hpp b/main/control.hpp
index 9e11f13..921a021 100644
--- a/main/control.hpp
+++ b/main/control.hpp
@@ -11,6 +11,8 @@ extern "C"
 #include "driver/adc.h"
 
 #include "rotary_encoder.h"
+#include "max7219.h"
+
 }
 #include <cmath>
 
diff --git a/main/display.cpp b/main/display.cpp
index 152e410..ad7639f 100644
--- a/main/display.cpp
+++ b/main/display.cpp
@@ -3,23 +3,15 @@
 
 //=== variables ===
 static const char *TAG = "display"; //tag for logging
-max7219_t display;
 
-bool disp1_blinkMode = false;
 
-char disp2_strOn[20];
-char disp2_strOff[20];
-bool disp2_state = false;
-bool disp2_blinkMode = false;
-uint32_t disp2_timestampOn;
-uint32_t disp2_timestampOff;
-uint32_t disp2_msOn;
-uint32_t disp2_msOff;
 
-//========================
-//===== init display =====
-//========================
-void display_init(){
+//==============================
+//======== init display ========
+//==============================
+//initialize display with parameters defined in config.hpp
+//TODO: dont use global variables/macros here
+max7219_t display_init(){
     
     ESP_LOGI(TAG, "initializing display...");
     // Configure SPI bus
@@ -43,124 +35,115 @@ void display_init(){
     ESP_ERROR_CHECK(max7219_init(&dev));
     //0...15
     ESP_ERROR_CHECK(max7219_set_brightness(&dev, 12));
-    //return dev;
-    display = dev;
+    return dev;
+    //display = dev;
     ESP_LOGI(TAG, "initializing display - done");
 }
 
 
 
-void display_ShowWelcomeMsg(){
-    //-----------------------------------
-    //------- display welcome msg -------
-    //-----------------------------------
+//===================================
+//======= display welcome msg =======
+//===================================
+void display_ShowWelcomeMsg(max7219_t dev){
     //display welcome message on two 7 segment displays
     //show name and date
     ESP_LOGI(TAG, "showing startup message...");
-    max7219_clear(&display);
-    max7219_draw_text_7seg(&display, 0, "CUTTER  20.08.2022");
+    max7219_clear(&dev);
+    max7219_draw_text_7seg(&dev, 0, "CUTTER  20.08.2022");
     //                                   1234567812 34 5678
     vTaskDelay(pdMS_TO_TICKS(700));
     //scroll "hello" over 2 displays
     for (int offset = 0; offset < 23; offset++) {
-        max7219_clear(&display);
+        max7219_clear(&dev);
         char hello[40] = "                HELL0                 ";
-        max7219_draw_text_7seg(&display, 0, hello + (22 - offset) );
+        max7219_draw_text_7seg(&dev, 0, hello + (22 - offset) );
         vTaskDelay(pdMS_TO_TICKS(50));
     }
 }
 
 
 
-void display1_showString(const char * buf){
-    max7219_draw_text_7seg(&display, 0, buf);
-    disp1_blinkMode = false;
-}
-void display2_showString(const char * buf){
-    max7219_draw_text_7seg(&display, 8, buf);
-    disp2_blinkMode = false;
-}
 
-void display_showString(uint8_t pos, const char * buf){
-    max7219_draw_text_7seg(&display, pos, buf);
+
+//---------------------------------
+//---------- constructor ----------
+//---------------------------------
+handledDisplay::handledDisplay(max7219_t displayDevice, uint8_t posStart_f) {
+    ESP_LOGI(TAG, "Creating handledDisplay instance with startPos at %i", posStart);
+    //copy variables
+    dev = displayDevice;
+    posStart = posStart_f;
 }
 
 
 
+//--------------------------------
+//---------- showString ----------
+//--------------------------------
+//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;
+}
 
-//function that handles blinking of display2
-void display2_handle(){
-    if (disp2_blinkMode == false){
-        return;
+
+
+//----------------------------------
+//---------- blinkStrings ----------
+//----------------------------------
+//function switches between two strings in a given interval
+void handledDisplay::blinkStrings(const char * strOn_f, const char * strOff_f, uint32_t msOn_f, uint32_t msOff_f){
+    //copy/update variables
+    strcpy(strOn, strOn_f);
+    strcpy(strOff, strOff_f);
+    msOn = msOn_f;
+    msOff = msOff_f;
+    //if changed to blink mode just now
+    if (blinkMode == false) {
+        ESP_LOGI(TAG, "pos:%i changing to blink mode", posStart);
+        blinkMode = true;
+        //start with on state
+        state = true;
+        timestampOn = esp_log_timestamp();
     }
+    //run handle function for display update
+    handle();
+}
+
+
+
+//--------------------------------
+//------------ handle ------------
+//--------------------------------
+//function that handles blinking of display2
+void handledDisplay::handle() {
+    if (blinkMode == false){
+        return; //not in blinking mode - nothing todo 
+    }
+
     //--- define state on/off ---
-    if (disp2_state == true){ //display in ON state
-        if (esp_log_timestamp() - disp2_timestampOn > disp2_msOn){
-            disp2_state = false;
-            disp2_timestampOff = esp_log_timestamp();
+    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() - disp2_timestampOff > disp2_msOff) {
-            disp2_state = true;
-            disp2_timestampOn = esp_log_timestamp();
+        if (esp_log_timestamp() - timestampOff > msOff) {
+            state = true;
+            timestampOn = esp_log_timestamp();
         }
     }
 
     //--- draw text of current state ---
-    if (disp2_state) {
-        max7219_draw_text_7seg(&display, 8, disp2_strOn);
+    if (state) {
+        max7219_draw_text_7seg(&dev, posStart, strOn);
     } else {
-        max7219_draw_text_7seg(&display, 8, disp2_strOff);
+        max7219_draw_text_7seg(&dev, posStart, strOff);
     }
 }
 
-
-
-//function switches between two strings in a given interval
-void display2_blinkStrings(const char * strOn, const char * strOff, uint32_t msOn, uint32_t msOff){
-    //copy variables
-    strcpy(disp2_strOn, strOn);
-    strcpy(disp2_strOff, strOff);
-    disp2_msOn = msOn;
-    disp2_msOff = msOff;
-    //set to blink mode
-    disp2_blinkMode = true;
-    //run handle function for display update
-    display2_handle();
-}
-
-
-
-    
-
-
-
-
-
-//        //---------------------------
-//        //--------- display ---------
-//        //---------------------------
-//        //-- show current position on display1 ---
-//        //sprintf(buf_tmp, "%06.1f cm", (float)lengthNow/10); //cm
-//        sprintf(buf_tmp, "1ST %5.4f", (float)lengthNow/1000); //m
-//        //                123456789
-//        //limit length to 8 digits + decimal point (drop decimal places when it does not fit)
-//        sprintf(buf_disp1, "%.9s", buf_tmp);
-//
-//        //--- show target length on display2 ---
-//        //sprintf(buf_disp2, "%06.1f cm", (float)lengthTarget/10); //cm
-//        sprintf(buf_disp2, "S0LL%5.3f", (float)lengthTarget/1000); //m
-//        //                  1234  5678
-//        
-//                //TODO: blink disp2 when set button pressed
-//        //TODO: blink disp2 when preset button pressed (exept manual mode)
-//        //TODO: write "MAN CTL" to disp2 when in manual mode
-//        //TODO: display or blink "REACHED" when reached state and start pressed
-//
-//        //--- write to display ---
-//        //max7219_clear(&display); //results in flickering display if same value anyways
-//        max7219_draw_text_7seg(&display, 0, buf_disp1);
-//        max7219_draw_text_7seg(&display, 8, buf_disp2);
-//
-//
-//
diff --git a/main/display.hpp b/main/display.hpp
index 722ca9a..b3a916a 100644
--- a/main/display.hpp
+++ b/main/display.hpp
@@ -18,13 +18,41 @@ extern "C"
 
 #include "config.hpp"
 
-void display_init();
-void display_ShowWelcomeMsg();
-void display1_showString(const char * buf);
-void display2_showString(const char * buf);
-void display_showString(uint8_t pos, const char * buf);
+//function for initializing the display using configuration from macros in config.hpp
+max7219_t display_init();
 
-//function that handles blinking of display2
-void display2_handle();
-//function switches between two strings in a given interval
-void display2_blinkStrings(const char * strOn, const char * strOff, uint32_t msOn, uint32_t msOff);
+//show welcome message on the entire display
+void display_ShowWelcomeMsg(max7219_t displayDevice);
+
+
+class handledDisplay {
+    public:
+        //--- constructor ---
+        //TODO add posMax to prevent writing in segments of other instance
+        handledDisplay(max7219_t displayDevice, uint8_t posStart);
+
+        //--- methods ---
+        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);
+        //TODO: add 'scroll string' method
+        //function that handles blinking of display
+        void handle();
+
+    private:
+
+        //--- variables ---
+        //config
+        max7219_t dev;
+        uint8_t posStart; //absolute position this display instance starts (e.g. multiple or very long 7 segment display)
+
+        //blink mode
+        char strOn[20];
+        char strOff[20];
+        bool state = false;
+        bool blinkMode = false;
+        uint32_t msOn;
+        uint32_t msOff;
+        uint32_t timestampOn;
+        uint32_t timestampOff;
+};