From 9319221fa0e1039857817138d7dcbfdf44d7112c Mon Sep 17 00:00:00 2001 From: Jan Grewe <jan@faked.org> Date: Mon, 29 May 2023 23:23:47 +0200 Subject: [PATCH] split code OTA working GoL working --- platformio.ini | 12 ++------ platformio_upload.py | 53 ---------------------------------- src/display.cpp | 35 ++++++++++++----------- src/display.h | 3 ++ src/gameoflife.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++ src/gameoflife.h | 17 +++++++++++ src/main.cpp | 5 ++++ src/network.cpp | 36 +++++++++++++++++------ src/network.h | 6 +++- 9 files changed, 147 insertions(+), 88 deletions(-) delete mode 100644 platformio_upload.py create mode 100644 src/gameoflife.cpp create mode 100644 src/gameoflife.h diff --git a/platformio.ini b/platformio.ini index 94002fa..97270c2 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,17 +19,9 @@ 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/ayushsharma82/AsyncElegantOTA.git https://github.com/PlummersSoftwareLLC/SmartMatrix.git - https://github.com/adafruit/Adafruit-GFX-Library.git - https://github.com/marcmerlin/Framebuffer_GFX.git - https://github.com/FastLED/FastLED.git - https://github.com/marcmerlin/SmartMatrix_GFX.git [env:esp32dev_ota] extends = env:esp32dev -#upload_port = matrixoflife.local -#upload_protocol = espota -upload_protocol = custom -upload_url = http://matrixoflife.local/update -extra_scripts = platformio_upload.py +upload_port = matrixoflife.local +upload_protocol = espota diff --git a/platformio_upload.py b/platformio_upload.py deleted file mode 100644 index 1c5f0a6..0000000 --- a/platformio_upload.py +++ /dev/null @@ -1,53 +0,0 @@ -# Allows PlatformIO to upload directly to AsyncElegantOTA -# -# To use: -# - copy this script into the same folder as your platformio.ini -# - set the following for your project in platformio.ini: -# -# extra_scripts = platformio_upload.py -# upload_protocol = custom -# upload_url = <your upload URL> -# -# An example of an upload URL: -# upload_URL = http://192.168.1.123/update - -import requests -import hashlib -Import('env') - -try: - from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor - from tqdm import tqdm -except ImportError: - env.Execute("$PYTHONEXE -m pip install requests_toolbelt") - env.Execute("$PYTHONEXE -m pip install tqdm") - from requests_toolbelt import MultipartEncoder, MultipartEncoderMonitor - from tqdm import tqdm - -def on_upload(source, target, env): - firmware_path = str(source[0]) - upload_url = env.GetProjectOption('upload_url') - - with open(firmware_path, 'rb') as firmware: - md5 = hashlib.md5(firmware.read()).hexdigest() - firmware.seek(0) - encoder = MultipartEncoder(fields={ - 'MD5': md5, - 'firmware': ('firmware', firmware, 'application/octet-stream')} - ) - - bar = tqdm(desc='Upload Progress', - total=encoder.len, - dynamic_ncols=True, - unit='B', - unit_scale=True, - unit_divisor=1024 - ) - - monitor = MultipartEncoderMonitor(encoder, lambda monitor: bar.update(monitor.bytes_read - bar.n)) - - response = requests.post(upload_url, data=monitor, headers={'Content-Type': monitor.content_type}) - bar.close() - print(response,response.text) - -env.Replace(UPLOADCMD=on_upload) diff --git a/src/display.cpp b/src/display.cpp index d78aaf8..fac11d2 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -1,4 +1,5 @@ #include <Arduino.h> +#include "gameoflife.h" #include "display.h" #define COLOR_DEPTH 24 // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24 @@ -9,33 +10,35 @@ const uint8_t kDmaBufferRows = 2; // known working: 2-4, use 2 to save mem const uint8_t kPanelType = SMARTMATRIX_HUB75_64ROW_MOD32SCAN; // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_NONE); // see http://docs.pixelmatix.com/SmartMatrix for options const uint8_t kBackgroundLayerOptions = (SM_BACKGROUND_OPTIONS_NONE); -const uint8_t kScrollingLayerOptions = (SM_SCROLLING_OPTIONS_NONE); -const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE); -const int defaultBrightness = (25*255)/100; // (10%) brightness -const int defaultScrollOffset = 6; -const rgb24 defaultBackgroundColor = {0x40, 0, 0}; +const int defaultBrightness = (10*255)/100; + +rgb24 colorWhite = {0xff, 0xff, 0xff}; +rgb24 colorBlack = {0x00, 0x00, 0x00}; SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions); SMARTMATRIX_ALLOCATE_BACKGROUND_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kBackgroundLayerOptions); -SMARTMATRIX_ALLOCATE_SCROLLING_LAYER(scrollingLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kScrollingLayerOptions); -SMARTMATRIX_ALLOCATE_INDEXED_LAYER(indexedLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions); void setupDisplay() { matrix.addLayer(&backgroundLayer); - matrix.addLayer(&scrollingLayer); - matrix.addLayer(&indexedLayer); matrix.begin(); matrix.setBrightness(defaultBrightness); - scrollingLayer.setOffsetFromTop(defaultScrollOffset); backgroundLayer.enableColorCorrection(true); } void displayLoop() { - scrollingLayer.setColor({0xff, 0xff, 0xff}); - scrollingLayer.setMode(wrapForward); - scrollingLayer.setSpeed(40); - scrollingLayer.setFont(font6x10); - scrollingLayer.start("SmartMatrix Demo", 1); - delay(5000); + if (runGame) { + gameOfLife(g); + for (int i = 0; i < SCREEN_HEIGHT; i++) { + for (int j = 0; j < SCREEN_WIDTH; j++) { + backgroundLayer.drawPixel(j, i, g[i][j] ? colorWhite : colorBlack); + } + } + backgroundLayer.swapBuffers(); + } +} + +void clearDisplay() { + backgroundLayer.fillScreen({0,0,0}); + backgroundLayer.swapBuffers(); } diff --git a/src/display.h b/src/display.h index 803d624..9bfdd38 100644 --- a/src/display.h +++ b/src/display.h @@ -5,7 +5,10 @@ #include <MatrixHardware_ESP32_V0.h> #include <SmartMatrix.h> + extern bool runGame; + void setupDisplay(); void displayLoop(); + void clearDisplay(); #endif diff --git a/src/gameoflife.cpp b/src/gameoflife.cpp new file mode 100644 index 0000000..acb23ef --- /dev/null +++ b/src/gameoflife.cpp @@ -0,0 +1,68 @@ +#include <Arduino.h> +#include "display.h" +#include "gameoflife.h" + +// https://github.com/Stavrosfil/game-of-life-esp32 + +int g[SCREEN_HEIGHT][SCREEN_WIDTH]; +int arrayCopy[SCREEN_HEIGHT][SCREEN_WIDTH]; + +void setupGameOfLife() { + randomSeed(analogRead(34)); + createRandomMatrix(g); + for (int i = 0; i < 10; i++) + addGlider(random(SCREEN_HEIGHT), random(SCREEN_WIDTH), g); + clearDisplay(); +} + +void createRandomMatrix(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { + for (int i = 0; i < SCREEN_HEIGHT; i++) { + for (int j = 0; j < SCREEN_WIDTH; j++) { + a[i][j] = random(100) < 25 ? 1 : 0; + } + } +} + +void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { + for (int i = 0; i < SCREEN_HEIGHT; i++) { + for (int j = 0; j < SCREEN_WIDTH; j++) { + arrayCopy[i][j] = a[i][j]; + } + } + + for (int i = 0; i < SCREEN_HEIGHT; i++) { + for (int j = 0; j < SCREEN_WIDTH; j++) { + int total = (a[i][(j - 1) % SCREEN_WIDTH] + a[i][(j + 1) % SCREEN_WIDTH] + a[(i - 1) % SCREEN_HEIGHT][j] + + a[(i + 1) % SCREEN_HEIGHT][j] + a[(i - 1) % SCREEN_HEIGHT][(j - 1) % SCREEN_WIDTH] + + a[(i - 1) % SCREEN_HEIGHT][(j + 1) % SCREEN_WIDTH] + + a[(i + 1) % SCREEN_HEIGHT][(j - 1) % SCREEN_WIDTH] + + a[(i + 1) % SCREEN_HEIGHT][(j + 1) % SCREEN_WIDTH]); + + if (a[i][j] == 1) { + if (total < 2 || total > 3) { + arrayCopy[i][j] = 0; + } + } else if (total == 3) { + arrayCopy[i][j] = 1; + } + } + } + + for (int i = 0; i < SCREEN_HEIGHT; i++) { + for (int j = 0; j < SCREEN_WIDTH; j++) { + a[i][j] = arrayCopy[i][j]; + } + } +} + +void addGlider(int i1, int j1, int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]) { + // 010 + // 001 + // 111 + int glider[3][3] = {{0, 0, 1}, {1, 0, 1}, {0, 1, 1}}; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + a[i1 + i][j1 + j] = glider[i][j]; + } + } +} diff --git a/src/gameoflife.h b/src/gameoflife.h new file mode 100644 index 0000000..af7a0dd --- /dev/null +++ b/src/gameoflife.h @@ -0,0 +1,17 @@ +#ifndef GAMEOFLIFE_H + #define GAMEOFLIFE_H + + #include <Arduino.h> + + #define SCREEN_WIDTH 64 + #define SCREEN_HEIGHT 64 + + extern int g[SCREEN_HEIGHT][SCREEN_WIDTH]; + extern int arrayCopy[SCREEN_HEIGHT][SCREEN_WIDTH]; + + void setupGameOfLife(); + void createRandomMatrix(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]); + void gameOfLife(int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]); + void addGlider(int i1, int j1, int (&a)[SCREEN_HEIGHT][SCREEN_WIDTH]); + +#endif diff --git a/src/main.cpp b/src/main.cpp index 0478caa..f54fa70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,20 @@ #include <Arduino.h> #include "utils.h" #include "network.h" +#include "gameoflife.h" #include "display.h" +bool runGame = true; + void setup() { Serial.begin(115200); logLine("", true); setupNetwork(); setupDisplay(); + setupGameOfLife(); } void loop() { + networkLoop(); displayLoop(); } diff --git a/src/network.cpp b/src/network.cpp index ad2a339..1ac9cd0 100644 --- a/src/network.cpp +++ b/src/network.cpp @@ -9,7 +9,7 @@ MDNSResponder mdns; void setupNetwork() { setupWifi(); setupMDNS(); - setupWebserver(); + setupOTA(); } void setupWifi() { @@ -32,12 +32,32 @@ void setupMDNS() { } } -void setupWebserver() { - server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) { - request->send(200, "text/plain", "Hi! I am ESP32."); - }); +void setupOTA() { + ArduinoOTA.onStart([]() { + runGame = false; + logLine("OTA Update Start"); + }); + ArduinoOTA.onEnd([]() { + logLine("OTA Update End"); + runGame = true; + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + char p[32]; + sprintf(p, "Progress: %u%%\n", (progress/(total/100))); + logLine(p, false); + }); + 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; + }); + ArduinoOTA.setHostname(HOSTNAME); + ArduinoOTA.begin(); +} - AsyncElegantOTA.begin(&server); - server.begin(); - Serial.println("HTTP server started"); +void networkLoop() { + ArduinoOTA.handle(); } diff --git a/src/network.h b/src/network.h index 54c6ffd..a760da4 100644 --- a/src/network.h +++ b/src/network.h @@ -2,16 +2,20 @@ #define NETWORK_H #include <Arduino.h> + #include <ArduinoOTA.h> #include <ESPConnect.h> #include <Wifi.h> #include <ESPmDNS.h> #include <AsyncTCP.h> #include <ESPAsyncWebServer.h> - #include <AsyncElegantOTA.h> + + extern bool runGame; void setupNetwork(); void setupMDNS(); void setupWifi(); void setupWebserver(); + void setupOTA(); + void networkLoop(); #endif -- GitLab