From dc6c04b1b0ed42c0e31d7e4f77a2a677f29712a7 Mon Sep 17 00:00:00 2001
From: Jan Grewe <jan@faked.org>
Date: Thu, 1 Jun 2023 02:48:35 +0200
Subject: [PATCH] switch to LittleFS add TwoTick to run gameLoop/displayLoop at
 50ms intervals (speed control later) don't copy display layer buffers when
 swapping buffers clean up webserver

---
 data/favicon.ico    | Bin 0 -> 1150 bytes
 data/index.htm      |  58 ++++++++++++++++++++++++++++++++++++++++++++
 platformio.ini      |   2 ++
 src/config.h.sample |   2 --
 src/display.cpp     |   8 +++---
 src/main.cpp        |  15 +++++++++---
 src/network.cpp     |  38 +++++++++++++++++------------
 src/network.h       |   4 ++-
 8 files changed, 101 insertions(+), 26 deletions(-)
 create mode 100644 data/favicon.ico
 create mode 100644 data/index.htm

diff --git a/data/favicon.ico b/data/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..71b25fe6ee6012a4c26602977262d217af885520
GIT binary patch
literal 1150
zcmZQzU}Ruq5D);-3Je)63=Con3=A3!3=9Gc3=9ek5OD?&U}0bo;)Y-lcQD|#wl=Uc
zoSmHotgWpLEG#Uv?d<G$f`WpWH8eDI6crUym6VjKrKF_d<>loSr%ai`;O6EA)&nDK
zY-}724Gj-!Yiqw%S66?jqN1`_Nl9sul$6wCQBl!<f`Wqo`S|$$^78Ut7ZVc;`S|f8
zql1G3Si8Nwy}Y5J;aM#$t^ca3s{a)f6#mP|$ov-<7ymCRD*7L!m!F^iKQ}k`e`aRp
z|E#R6kA;PWEjc+k!TQb3&BL{|wZAJXEC2WM^7`M=(edBN$mqYJq2YfqF)^?{kU2Ry
zIsZdLL&0`vYHBVF4i4sj@!|!8k&#ignwr`_MMcH`Q>IM$|M>Ca|CN=M|M%|Q``_H$
z{C_||z<*6m&Hvrq-T&|0x%2<jsZ;-V?AY;R(V|5=N=r+%EG#Tmf!u6iVe$Xu$&>%D
zT)Fap*REavZ{EE5-`Cgo|Lobb!R~2qZ~s4Q)~x>*E?oHk^5x6_7cXA?vwZpTYz+;K
z)zZ?^|I5nC{+~E;;{UpJ>;9iTd-ngHJ$wGArKSDv>+1u%dCi(N{|gEVz~*h=z8xh0
z<G_IfahjT%QPR@VA0s0p|Hs6{{7+6!{-2kZ_rI~R5v(30W@l#yc2h+~#sAHlH-qun
zvuAIuS+hpf$jFF8R#vu3NJ!{84-d~@P&jjNaQx@t;rTBoC->jj*!aJXj}JIJwrtq~
zviJX?Lx=t!J9caWKR-XSxw$!my}dn)f`WpMprBwVA0J;K2M5PfP+Wn+-PF_+tiQOp
z807ZP+qZ9Dzj^cKx=E8JNz9u!4;+UuLSJ8>p}xMJQCwU+R8ms%f~l$LPahwjf02=q
zKN1oWE+!`@CxnEAux;MF8Kwn;E-o%+`1<uLgS)%Cl)t~fZ+LikQfg|dM`2;1<c%9Q
w7^Y93j-h8D1^)kMU;yC*><kPI%nS?+Ak2u}MGcG$3?JAT7=G|W^nmmM07-a6+5i9m

literal 0
HcmV?d00001

diff --git a/data/index.htm b/data/index.htm
new file mode 100644
index 0000000..25b3efd
--- /dev/null
+++ b/data/index.htm
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
+    <title>Events Log</title>
+    <style type="text/css" media="screen">
+    body {
+      margin:0;
+      padding:0;
+      background-color: black;
+    }
+
+    #dbg {
+      font-family: monaco;
+      font-size: 12px;
+      line-height: 13px;
+      color: #AAA;
+      margin:0;
+      padding:0;
+      padding-left:4px;
+    }
+    </style>
+    <script type="text/javascript">
+    function ge(s){ return document.getElementById(s);}
+    function ce(s){ return document.createElement(s);}
+    function stb(){ window.scrollTo(0, document.body.scrollHeight || document.documentElement.scrollHeight); }
+    function addMessage(m){
+      var msg = ce("div");
+      msg.innerText = m;
+      ge("dbg").appendChild(msg);
+      stb();
+    }
+    function startEvents(){
+      var es = new EventSource('/events');
+      es.onopen = function(e) {
+        addMessage("Events Opened");
+      };
+      es.onerror = function(e) {
+        if (e.target.readyState != EventSource.OPEN) {
+          addMessage("Events Closed");
+        }
+      };
+      es.onmessage = function(e) {
+        addMessage("Event: " + e.data);
+      };
+      es.addEventListener('ota', function(e) {
+        addMessage("Event[ota]: " + e.data);
+      }, false);
+    }
+    function onBodyLoad(){
+      startEvents();
+    }
+    </script>
+  </head>
+  <body id="body" onload="onBodyLoad()">
+    <pre id="dbg"></pre>
+  </body>
+</html>
diff --git a/platformio.ini b/platformio.ini
index 97270c2..7d72a23 100644
--- a/platformio.ini
+++ b/platformio.ini
@@ -15,11 +15,13 @@ framework = arduino
 upload_port = COM8
 monitor_port = COM8
 monitor_speed = 115200
+board_build.filesystem = littlefs
 lib_deps = 
     https://github.com/ayushsharma82/ESPConnect.git
 	https://github.com/me-no-dev/AsyncTCP.git
 	https://github.com/me-no-dev/ESPAsyncWebServer.git
     https://github.com/PlummersSoftwareLLC/SmartMatrix.git
+    https://github.com/sstaub/TickTwo.git
 
 [env:esp32dev_ota]
 extends = env:esp32dev
diff --git a/src/config.h.sample b/src/config.h.sample
index 6bc7a59..8fb35b7 100644
--- a/src/config.h.sample
+++ b/src/config.h.sample
@@ -1,3 +1 @@
-#define WIFI_SSID "YourSSID"
-#define WIFI_PSK  "YourPSK"
 #define HOSTNAME  "MatrixOfLife"
diff --git a/src/display.cpp b/src/display.cpp
index 66b6da2..856ff89 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -42,7 +42,7 @@ void displayLoop()
         backgroundLayer.drawPixel(j, i, g[i][j] ? colorWhite : colorBlack);
       }
     }
-    backgroundLayer.swapBuffers();
+    backgroundLayer.swapBuffers(false);
   }
 }
 
@@ -53,7 +53,7 @@ void showEndScreen(int ticks) {
 void fadeOutGame(int brightness) {
   brightness = lightPowerMap8bit[brightness];
   backgroundLayer.setBrightness(brightness);
-  backgroundLayer.swapBuffers();
+  //backgroundLayer.swapBuffers(false);
 }
 
 void showEvolutions(int ticks)
@@ -70,8 +70,8 @@ void showEvolutions(int ticks)
 
 void clearDisplay()
 {
-  indexedLayer.swapBuffers();
+  indexedLayer.swapBuffers(false);
   backgroundLayer.fillScreen({0, 0, 0});
   backgroundLayer.setBrightness(255);
-  backgroundLayer.swapBuffers();
+  backgroundLayer.swapBuffers(false);
 }
diff --git a/src/main.cpp b/src/main.cpp
index 7c915f0..1c9f642 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,24 +1,31 @@
 #include <Arduino.h>
+#include "TickTwo.h"
 #include "utils.h"
 #include "network.h"
 #include "display.h"
 #include "gameoflife.h"
 
 int noEvolutionTicksLimit = 100;
-int brightnessPercent = 100;
+int brightnessPercent = 50;
+int gameInterval = 50;
+
+TickTwo gameTimer(gameLoop, gameInterval);
+TickTwo displayTimer(displayLoop, gameInterval);
 
 void setup()
 {
   Serial.begin(115200);
   logLine("", true);
-  setupDisplay();
   setupNetwork();
+  setupDisplay();
   setupGameOfLife();
+  gameTimer.start();
+  displayTimer.start();
 }
 
 void loop()
 {
   networkLoop();
-  gameLoop();
-  displayLoop();
+  gameTimer.update();
+  displayTimer.update();
 }
diff --git a/src/network.cpp b/src/network.cpp
index 50440d9..5053e95 100644
--- a/src/network.cpp
+++ b/src/network.cpp
@@ -3,14 +3,16 @@
 #include "utils.h"
 #include "network.h"
 
-AsyncWebServer server(80);
 MDNSResponder mdns;
+AsyncWebServer server(80);
+AsyncEventSource events("/events");
 
 void setupNetwork()
 {
   setupWifi();
   setupMDNS();
   setupOTA();
+  setupWebserver();
 }
 
 void setupWifi()
@@ -33,7 +35,6 @@ void setupMDNS()
   {
     logLine("MDNS responder started");
     mdns.addService("http", "tcp", 80);
-    mdns.addService("ws", "tcp", 81);
   }
   else
   {
@@ -44,30 +45,37 @@ void setupMDNS()
 void setupOTA()
 {
   ArduinoOTA.onStart([]()
-                     { 
-    runGame = false;
-    logLine("OTA Update Start"); });
+                     { events.send("Update Start", "ota"); });
   ArduinoOTA.onEnd([]()
-                   { 
-    logLine("OTA Update End"); 
-    runGame = true; });
+                   { events.send("Update End", "ota"); });
   ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
                         {
     char p[32];
     sprintf(p, "Progress: %u%%\n", (progress/(total/100)));
-    logLine(p, false); });
+    events.send(p, "ota"); });
   ArduinoOTA.onError([](ota_error_t error)
                      {
-    if(error == OTA_AUTH_ERROR) logLine("OTA Auth Failed");
-    else if(error == OTA_BEGIN_ERROR) logLine("OTA Begin Failed");
-    else if(error == OTA_CONNECT_ERROR) logLine("OTA Connect Failed");
-    else if(error == OTA_RECEIVE_ERROR) logLine("OTA Receive Failed");
-    else if(error == OTA_END_ERROR) logLine("OTA End Failed");
-    runGame = true; });
+    if(error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota");
+    else if(error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota");
+    else if(error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota");
+    else if(error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota");
+    else if(error == OTA_END_ERROR) events.send("End Failed", "ota"); });
   ArduinoOTA.setHostname(HOSTNAME);
   ArduinoOTA.begin();
 }
 
+void setupWebserver()
+{
+  LittleFS.begin();
+  server.serveStatic("/", LittleFS, "/");
+  events.onConnect([](AsyncEventSourceClient *client)
+                   { client->send("hello!", NULL, millis(), 1000); });
+  server.addHandler(&events);
+  server.onNotFound([](AsyncWebServerRequest *request)
+                    { request->send(404); });
+  server.begin();
+}
+
 void networkLoop()
 {
   ArduinoOTA.handle();
diff --git a/src/network.h b/src/network.h
index 2475984..23ff9b0 100644
--- a/src/network.h
+++ b/src/network.h
@@ -2,6 +2,8 @@
 #define NETWORK_H
 
 #include <Arduino.h>
+#include <FS.h>
+#include <LittleFS.h>
 #include <ArduinoOTA.h>
 #include <ESPConnect.h>
 #include <Wifi.h>
@@ -14,8 +16,8 @@ extern bool runGame;
 void setupNetwork();
 void setupMDNS();
 void setupWifi();
-void setupWebserver();
 void setupOTA();
+void setupWebserver();
 void networkLoop();
 
 #endif
-- 
GitLab