From 8427289b97a6505174ec40a1e70d6898a1bbaf30 Mon Sep 17 00:00:00 2001
From: egorguslyan <egorguslyan@gmail.com>
Date: Thu, 23 Dec 2021 10:09:27 +0300
Subject: [PATCH] comments and first screens

---
 Dashboard/Dashboard.ino | 68 +++++++++++++++++++++++-------
 Dashboard/config.h      | 29 +++++++++++++
 Dashboard/screens.h     | 16 +++++++
 Dashboard/strings.h     |  5 +++
 Dashboard/textbox.h     | 92 +++++++++++++++++++++++++++++------------
 5 files changed, 167 insertions(+), 43 deletions(-)
 create mode 100644 Dashboard/config.h
 create mode 100644 Dashboard/screens.h
 create mode 100644 Dashboard/strings.h

diff --git a/Dashboard/Dashboard.ino b/Dashboard/Dashboard.ino
index 303914c..d7e135e 100644
--- a/Dashboard/Dashboard.ino
+++ b/Dashboard/Dashboard.ino
@@ -23,26 +23,55 @@
 #include <microLED.h>
 /********************************/
 
-/*******microLED library*********/
+/*******MHZ19 CO2 library********/
 #include <MHZ19_uart.h>
 /********************************/
 
-/************Marcos**************/
+#include <EEPROM.h>
+
+/*************Marcos*************/
 #define timer(tim, del) if(millis() - (tim) > (del))
+#define numLeds (WIDTH * HEIGHT)
 /********************************/
 
-#define LANG_RU_RU
-#define LEDsPin 2
-#define CO2RX A0
-#define CO2TX A1
-#define LBTN 10
-#define RBTN 8
+// Unified arguments for screen functions
+typedef union
+{
+  int8_t i8;
+  uint8_t ui8;
+  const void *v;
+} Arg;
 
-#define WIDTH 16
-#define HEIGHT 9
-#define numLeds (WIDTH * HEIGHT)
-#define COLOR1 mHEX(0x9aa100)
-#define COLOR2 mHEX(0x000aa0)
+// Screen entity with transition table
+typedef struct
+{
+  void (*func)(const Arg *);
+  const Arg arg;
+  const uint8_t nextFunc0;
+  const uint8_t nextFunc1;
+  const uint8_t nextFunc2;
+} Screen;
+
+// It will be stored in EEPROM with a special key
+enum PANEL_ORIENTATION
+{
+  PANEL_UNKNOWN = 0,
+  PANEL_NORMAL,
+  PANEL_REVERSE,
+};
+const uint8_t special_key = 0b11011100; // Just a random number (it's actually the voltage from the outlet)
+
+// Structure for all global variables
+struct
+{
+  uint8_t panelOrientation : 2; // Swipe panel orientation
+  uint8_t currentScreen;
+  uint8_t currentState;
+  uint64_t timer;
+} globalVars;
+
+#include "screens.h"
+#include "config.h"
 
 microLED<numLeds, LEDsPin, MLED_NO_CLOCK, LED_WS2812, ORDER_GRB, CLI_AVER/*, SAVE_MILLIS*/> matrix(WIDTH, HEIGHT, ZIGZAG, RIGHT_TOP, DIR_LEFT);
 #include "textbox.h"
@@ -51,18 +80,25 @@ MHZ19_uart co2;
 
 void setup()
 {
+  // Hardware init
   matrix.setBrightness(100);
   matrix.clear();
   matrix.show();
+  co2.begin(CO2TX, CO2RX);
+  co2.setAutoCalibration(false);
   Serial.begin(9600);
+  // For safe debugging
   while (!Serial.available()) {}
   Serial.println("Hello");
   
+  // Reading settings from nonvolatile memory
+  uint8_t eepromData;
+  eepromData = EEPROM.read(0);
+  if((eepromData & 0b11111100 == special_key) && (eepromData & 0b00000011 < 3))
+    globalVars.panelOrientation = eepromData & 0b00000011;
+  else globalVars.panelOrientation = PANEL_UNKNOWN;
 
-  co2.begin(CO2TX, CO2RX);
-  co2.setAutoCalibration(false);
   delay(500);
-  tb.setup("Ghbdtn vbh!", 0xFFFF, COLOR1, TB_LOOP_WITH_DELAY, 1, 1, 14, 100, 2000);
 }
 
 void loop()
diff --git a/Dashboard/config.h b/Dashboard/config.h
new file mode 100644
index 0000000..af8a6c4
--- /dev/null
+++ b/Dashboard/config.h
@@ -0,0 +1,29 @@
+#define LANG_RU_RU
+#define LEDsPin 2
+#define CO2RX A0
+#define CO2TX A1
+#define LBTN 10
+#define RBTN 8
+
+#define WIDTH 16
+#define HEIGHT 9
+
+#define COLOR1 mHEX(0x9aa100)
+#define COLOR2 mHEX(0x000aa0)
+
+#define startWith SCREEN_WELCOME
+
+// Links
+enum SCREENS
+{
+    NONE = 255,
+    SCREEN_WELCOME = 0,
+    SCREEN_DASHBOARD,
+    SCREEN_GRAPH,
+    SCREEN_POMODORO,
+};
+
+const Screen screens[] = {
+    { welcome,      {.ui8 = globalVars.panelOrientation},       SCREEN_DASHBOARD,      NONE,                NONE },
+    { dashboard,    {.ui8 = globalVars.panelOrientation},       SCREEN_DASHBOARD,      NONE,                NONE },
+};
\ No newline at end of file
diff --git a/Dashboard/screens.h b/Dashboard/screens.h
new file mode 100644
index 0000000..346268f
--- /dev/null
+++ b/Dashboard/screens.h
@@ -0,0 +1,16 @@
+void welcome(Arg *arg);
+void dashboard(Arg *arg);
+
+void welcome(Arg *arg)
+{
+    const uint8_t delayMap[] = {50};
+    if(millis() - globalVars.timer > delayMap[globalVars.currentState])
+        digitalWrite(13, 1);
+}
+
+void dashboard(Arg *arg)
+{
+    const uint8_t delayMap[] = {50};
+    if(millis() - globalVars.timer > delayMap[globalVars.currentState])
+        digitalWrite(13, 1);
+}
\ No newline at end of file
diff --git a/Dashboard/strings.h b/Dashboard/strings.h
new file mode 100644
index 0000000..6a6c4f0
--- /dev/null
+++ b/Dashboard/strings.h
@@ -0,0 +1,5 @@
+#if LANG_RU_RU
+char* strings[] = {};
+#else
+char* strings[] = {"Hello", "<- Swipe left"};
+#endif
\ No newline at end of file
diff --git a/Dashboard/textbox.h b/Dashboard/textbox.h
index b817e16..6506c33 100644
--- a/Dashboard/textbox.h
+++ b/Dashboard/textbox.h
@@ -2,8 +2,9 @@
 
 #include "font.h"
 
-enum TB_MODES {
-    TB_DISABLED,
+enum TB_MODES
+{
+    TB_DISABLED = 0,
     TB_STATIC,
     TB_REPEAT,
     TB_LOOP,
@@ -11,7 +12,8 @@ enum TB_MODES {
     TB_BOUNCE,
 };
 
-class textbox {
+class textbox
+{
 private:
     /* data */
     uint8_t cord_x;
@@ -42,6 +44,7 @@ public:
         uint8_t _reciprocal_speed = 0, uint16_t _delay = 0);
     uint8_t render(void);
     void disable(void);
+    void changeCords(uint8_t newx, uint8_t newy);
 };
 
 textbox::textbox(void)
@@ -64,23 +67,29 @@ void textbox::setup(char _text[], uint64_t _langMask,
     uint8_t _x, uint8_t _y, uint8_t _w,
     uint8_t _reciprocal_speed = 0, uint16_t _delay = 0)
 {
+    // Copy string
     memset(text, NULL, 64 * sizeof(char));
     strcpy(text, _text);
+    // Calculating width
     textlen = strlen(text);
     langMask = _langMask;
     textwidth = 0;
-    for (uint16_t i = 0; i < textlen; i++) {
+    for (uint16_t i = 0; i < textlen; i++)
+    {
         getLetter(i, true);
         textwidth += letter[0] + 1;
     }
     textwidth--;
+
+    // Defining other vars
     color = _color;
     mode = _mode;
     cord_x = _x;
     cord_y = _y;
     w = _w;
     offset = 0;
-    switch (mode) {
+    switch (mode)
+    {
     case TB_LOOP:
         delay = 0;
         goto NO_DELAY;
@@ -98,41 +107,56 @@ void textbox::setup(char _text[], uint64_t _langMask,
         delay = 0;
         break;
     }
+
+    // Reset timer and render
     timer0 = 0;
     render();
 }
 
 uint8_t textbox::render(void)
 {
-    // Do nothing if disabled
-    if (mode != TB_DISABLED) {
-        if (timer0 == 0) {
+    if (mode != TB_DISABLED)
+    {
+        // If static or kickstart
+        if (timer0 == 0 || mode == TB_STATIC)
+        {
             offset = 0 + (mode == TB_REPEAT) * w + 1 * (mode == TB_LOOP);
             direction = 0;
             timer0 = millis();
-        } else {
-            if ((millis() - timer0) > (((mode != TB_LOOP) && !state) ? delay : speed)) {
+        }
+        else
+        {
+            if ((millis() - timer0) > (((mode != TB_LOOP) && !state) ? delay : speed))
+            {
                 state = 1;
                 timer0 = millis();
-                if (mode == TB_BOUNCE) {
-                    if ((!direction && offset == -textwidth + w) || (direction && offset == 0)) {
+                if (mode == TB_BOUNCE)
+                {
+                    if ((!direction && offset == -textwidth + w) || (direction && offset == 0))
+                    {
                         direction = !direction;
                         state = 0;
-                    } else
+                    }
+                    else
                         offset += direction ? 1 : -1;
-                } else {
+                }
+                else
+                {
                     offset += -1;
-                    if (offset < ((int16_t)-textwidth - 2 * (mode == TB_LOOP || mode == TB_LOOP_WITH_DELAY) - w * (mode == TB_REPEAT))) {
+                    if (offset < ((int16_t)-textwidth - 2 * (mode == TB_LOOP || mode == TB_LOOP_WITH_DELAY) - w * (mode == TB_REPEAT)))
+                    {
                         offset = 0 + (mode == TB_REPEAT) * w;
                         state = 0;
                     }
                 }
-
-            } else
+            }
+            else
+                // Draw if kickstart
                 if(state != 0) return 0;
         }
-    } else
-        return 0;
+    }
+    // Do nothing if disabled
+    else return 0;
     // Clear spot
     for (uint8_t i = cord_x; (i < cord_x + w) && (i < WIDTH); i++)
         for (uint8_t j = cord_y; (j < cord_y + 7) && (j < HEIGHT); j++)
@@ -142,7 +166,8 @@ uint8_t textbox::render(void)
     int16_t positionX = cord_x + offset;
     int16_t positionY = cord_y;
     // Draw while in bounds
-    while ((positionX < cord_x + w) && (index < textlen)) {
+    while ((positionX < cord_x + w) && (index < textlen))
+    {
         // Recieve letter
         getLetter(index);
         // Relative X and Y
@@ -151,9 +176,11 @@ uint8_t textbox::render(void)
         // X bound
         uint8_t maxX = letter[0];
         // Run thougth bytes
-        for (uint8_t i = 0; (i < letter[2]) && (y < 7); i++) {
+        for (uint8_t i = 0; (i < letter[2]) && (y < 7); i++)
+        {
             // Run througth bits
-            for (int8_t j = 7; (j >= 0) && (y < 7); j--) {
+            for (int8_t j = 7; (j >= 0) && (y < 7); j--)
+            {
                 // Set pixel
                 bool state = bitRead(letter[i + 3], j);
                 int16_t mx = x + positionX;
@@ -162,7 +189,8 @@ uint8_t textbox::render(void)
                     matrix.set(mx, my, color);
                 // Next pixel
                 x++;
-                if (x >= maxX) {
+                if (x >= maxX)
+                {
                     x = 0;
                     y++;
                 }
@@ -171,6 +199,12 @@ uint8_t textbox::render(void)
         // Shift X and index
         positionX += maxX + 1;
         index++;
+        // Make a loop
+        if((mode == TB_LOOP || mode == TB_LOOP_WITH_DELAY) && index == textlen)
+        {
+            positionX++;
+            index = 0;
+        }
     }
     return 1;
 }
@@ -201,9 +235,13 @@ void textbox::getLetter(uint8_t i, bool skipBitmap = 0)
     letter[1] = readed % 7;      // offset
     letter[2] = readed / 7 % 7;  // bytes
     // Read bitmaps
-    if (!skipBitmap) {
-        for (uint8_t i = 0; i < letter[2]; i++) {
+    if (!skipBitmap)
+        for (uint8_t i = 0; i < letter[2]; i++)
             letter[i + 3] = pgm_read_byte(font[index] + (i + 1) * sizeof(uint8_t));
-        }
-    }
 }
+
+void textbox::changeCords(uint8_t newx, uint8_t newy)
+{
+    cord_x = newx;
+    cord_y = newy;
+}
\ No newline at end of file
-- 
GitLab