eeprom config
This commit is contained in:
parent
88ee6fa91c
commit
8483963b92
83
src/config.cpp
Normal file
83
src/config.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include <EEPROM.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
uint32_t calculateChecksum(Config *ptr);
|
||||||
|
|
||||||
|
void config_defaults();
|
||||||
|
|
||||||
|
bool validateChecksum(uint32_t checksumEEPROM, Config &tmp);
|
||||||
|
|
||||||
|
Config config;
|
||||||
|
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
unsigned long lastDirtyMillis = 0;
|
||||||
|
|
||||||
|
void config_setup() {
|
||||||
|
if (!config_load()) {
|
||||||
|
config_defaults();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_set_dirty() {
|
||||||
|
dirty = true;
|
||||||
|
lastDirtyMillis = millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_loop() {
|
||||||
|
if (!dirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (millis() - lastDirtyMillis <= 30000) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dirty = false;
|
||||||
|
|
||||||
|
uint32_t checksum = calculateChecksum(&config);
|
||||||
|
|
||||||
|
EEPROM.begin(512);
|
||||||
|
EEPROM.writeBytes(0, &config, sizeof(Config));
|
||||||
|
EEPROM.writeUInt(sizeof(Config), checksum);
|
||||||
|
EEPROM.end();
|
||||||
|
|
||||||
|
Serial.printf("Config saved to EEPROM.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool config_load() {
|
||||||
|
Config tmp{};
|
||||||
|
|
||||||
|
EEPROM.begin(512);
|
||||||
|
EEPROM.readBytes(0, &tmp, sizeof(Config));
|
||||||
|
uint32_t checksum = EEPROM.readUInt(sizeof(Config));
|
||||||
|
EEPROM.end();
|
||||||
|
|
||||||
|
bool success = validateChecksum(checksum, tmp);
|
||||||
|
if (success) {
|
||||||
|
memcpy(&config, &tmp, sizeof(Config));
|
||||||
|
Serial.printf("Config loaded from EEPROM.\n");
|
||||||
|
} else {
|
||||||
|
Serial.printf("Failed to load config from EEPROM.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateChecksum(uint32_t checksumEEPROM, Config &tmp) {
|
||||||
|
uint32_t calculated = calculateChecksum(&tmp);
|
||||||
|
return checksumEEPROM == calculated;
|
||||||
|
}
|
||||||
|
|
||||||
|
void config_defaults() {
|
||||||
|
config.mode = GAME_OF_LIFE_GRAYSCALE;
|
||||||
|
config.speed = 1.0;
|
||||||
|
config.brightness = 16;
|
||||||
|
Serial.printf("Config DEFAULTS loaded.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t calculateChecksum(Config *ptr) {
|
||||||
|
uint32_t checksum = 0;
|
||||||
|
for (auto *b = (uint8_t *) ptr; b < (uint8_t *) ptr + sizeof(Config); b++) {
|
||||||
|
checksum += *b;
|
||||||
|
}
|
||||||
|
return checksum;
|
||||||
|
}
|
||||||
22
src/config.h
Normal file
22
src/config.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef MEDIATABLE_CONFIG_H
|
||||||
|
#define MEDIATABLE_CONFIG_H
|
||||||
|
|
||||||
|
#include "mode/Mode.h"
|
||||||
|
|
||||||
|
struct Config {
|
||||||
|
ModeId mode;
|
||||||
|
double speed;
|
||||||
|
uint8_t brightness;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Config config;
|
||||||
|
|
||||||
|
void config_setup();
|
||||||
|
|
||||||
|
void config_loop();
|
||||||
|
|
||||||
|
bool config_load();
|
||||||
|
|
||||||
|
void config_set_dirty();
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -40,9 +40,9 @@ private:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
Display(uint8_t width, uint8_t height) :
|
Display(uint8_t width, uint8_t height) :
|
||||||
width(width), height(height),
|
width(width), height(height),
|
||||||
pixelCount(width * height),
|
pixelCount(width * height),
|
||||||
leds(pixelCount, GPIO_NUM_13) {
|
leds(pixelCount, GPIO_NUM_13) {
|
||||||
// nothing
|
// nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setBrightness(int brightness) {
|
void setBrightness(int brightness) {
|
||||||
leds.setBrightness(min(255, max(0, brightness)));
|
leds.setBrightness(max(0, min(brightness, 255)));
|
||||||
}
|
}
|
||||||
|
|
||||||
int getBrightness() {
|
int getBrightness() {
|
||||||
|
|||||||
100
src/main.cpp
100
src/main.cpp
@ -6,6 +6,7 @@
|
|||||||
#include "display/Display.h"
|
#include "display/Display.h"
|
||||||
#include <WebServer.h>
|
#include <WebServer.h>
|
||||||
#include <esp_sntp.h>
|
#include <esp_sntp.h>
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
#include "mode/GameOfLife/GameOfLife.h"
|
#include "mode/GameOfLife/GameOfLife.h"
|
||||||
#include "mode/Pong/Pong.h"
|
#include "mode/Pong/Pong.h"
|
||||||
@ -13,34 +14,18 @@
|
|||||||
#include "mode/SpaceInvaders/SpaceInvaders.h"
|
#include "mode/SpaceInvaders/SpaceInvaders.h"
|
||||||
#include "mode/NewYear/NewYear.h"
|
#include "mode/NewYear/NewYear.h"
|
||||||
#include "mode/Border/Border.h"
|
#include "mode/Border/Border.h"
|
||||||
|
#include "config.h"
|
||||||
enum ModeId {
|
|
||||||
NONE,
|
|
||||||
BORDER,
|
|
||||||
CLOCK,
|
|
||||||
GAME_OF_LIFE_BLACK_WHITE,
|
|
||||||
GAME_OF_LIFE_GRAYSCALE,
|
|
||||||
GAME_OF_LIFE_COLOR_FADE,
|
|
||||||
GAME_OF_LIFE_RANDOM_COLOR,
|
|
||||||
PONG,
|
|
||||||
SPACE_INVADERS,
|
|
||||||
NEW_YEAR,
|
|
||||||
};
|
|
||||||
|
|
||||||
WebServer server(80);
|
WebServer server(80);
|
||||||
|
|
||||||
Display display(32, 8);
|
Display display(32, 8);
|
||||||
|
|
||||||
ModeId newModeId = NEW_YEAR;
|
|
||||||
|
|
||||||
ModeId currentModeId = NONE;
|
ModeId currentModeId = NONE;
|
||||||
|
|
||||||
microseconds_t lastMicros = 0;
|
microseconds_t lastMicros = 0;
|
||||||
|
|
||||||
ModeBase *mode = nullptr;
|
ModeBase *mode = nullptr;
|
||||||
|
|
||||||
double speed = 1.0;
|
|
||||||
|
|
||||||
bool connected = false;
|
bool connected = false;
|
||||||
|
|
||||||
void mode_check();
|
void mode_check();
|
||||||
@ -51,9 +36,9 @@ void unloadOldMode();
|
|||||||
|
|
||||||
void loadNewMode();
|
void loadNewMode();
|
||||||
|
|
||||||
void setBrightness(int value);
|
void setBrightness(int brightness);
|
||||||
|
|
||||||
void setSpeed(double value);
|
void setSpeed(double speed);
|
||||||
|
|
||||||
void serial_read();
|
void serial_read();
|
||||||
|
|
||||||
@ -63,6 +48,8 @@ void ntp_setup();
|
|||||||
|
|
||||||
uint32_t ip2int(const IPAddress &ip);
|
uint32_t ip2int(const IPAddress &ip);
|
||||||
|
|
||||||
|
void setMode(ModeId value);
|
||||||
|
|
||||||
void web_index() {
|
void web_index() {
|
||||||
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
server.send(200, "text/html", "");
|
server.send(200, "text/html", "");
|
||||||
@ -77,6 +64,7 @@ void web_index() {
|
|||||||
server.sendContent("<a href='/mode?mode=8'>SPACE_INVADERS</a><br>");
|
server.sendContent("<a href='/mode?mode=8'>SPACE_INVADERS</a><br>");
|
||||||
server.sendContent("<a href='/mode?mode=9'>NEW_YEAR</a><br>");
|
server.sendContent("<a href='/mode?mode=9'>NEW_YEAR</a><br>");
|
||||||
server.sendContent("Helligkeit: <a href='/brighter'>+</a> / <a href='/darker'>-</a><br>");
|
server.sendContent("Helligkeit: <a href='/brighter'>+</a> / <a href='/darker'>-</a><br>");
|
||||||
|
server.sendContent("Geschwindigkeit: <a href='/faster'>+</a> / <a href='/slower'>-</a><br>");
|
||||||
server.client().flush();
|
server.client().flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,11 +78,19 @@ void web_setMode() {
|
|||||||
server.send(400, "text/plain", "'mode' not a number");
|
server.send(400, "text/plain", "'mode' not a number");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
newModeId = (ModeId) value;
|
setMode((ModeId) value);
|
||||||
server.sendHeader("location", "/");
|
server.sendHeader("location", "/");
|
||||||
server.send(301, "text/plain", "ok");
|
server.send(301, "text/plain", "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setMode(ModeId value) {
|
||||||
|
if (config.mode == value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.mode = value;
|
||||||
|
config_set_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
void web_brighter() {
|
void web_brighter() {
|
||||||
setBrightness(display.getBrightness() + 10);
|
setBrightness(display.getBrightness() + 10);
|
||||||
server.sendHeader("location", "/");
|
server.sendHeader("location", "/");
|
||||||
@ -107,6 +103,18 @@ void web_darker() {
|
|||||||
server.send(301, "text/plain", "ok");
|
server.send(301, "text/plain", "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void web_faster() {
|
||||||
|
setSpeed(config.speed * 1.1);
|
||||||
|
server.sendHeader("location", "/");
|
||||||
|
server.send(301, "text/plain", "ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
void web_slower() {
|
||||||
|
setSpeed(config.speed / 1.1);
|
||||||
|
server.sendHeader("location", "/");
|
||||||
|
server.send(301, "text/plain", "ok");
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
delay(500);
|
delay(500);
|
||||||
Serial.begin(115200);
|
Serial.begin(115200);
|
||||||
@ -142,8 +150,11 @@ void setup() {
|
|||||||
ArduinoOTA.begin();
|
ArduinoOTA.begin();
|
||||||
yield();
|
yield();
|
||||||
|
|
||||||
|
config_setup();
|
||||||
|
|
||||||
display.setup();
|
display.setup();
|
||||||
yield();
|
yield();
|
||||||
|
display.setBrightness(config.brightness);
|
||||||
|
|
||||||
server.on("", web_index);
|
server.on("", web_index);
|
||||||
server.on("/", web_index);
|
server.on("/", web_index);
|
||||||
@ -153,15 +164,20 @@ void setup() {
|
|||||||
server.on("/brighter/", web_brighter);
|
server.on("/brighter/", web_brighter);
|
||||||
server.on("/darker", web_darker);
|
server.on("/darker", web_darker);
|
||||||
server.on("/darker/", web_darker);
|
server.on("/darker/", web_darker);
|
||||||
|
server.on("/faster", web_faster);
|
||||||
|
server.on("/faster/", web_faster);
|
||||||
|
server.on("/slower", web_slower);
|
||||||
|
server.on("/slower/", web_slower);
|
||||||
server.begin();
|
server.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
yield();
|
yield();
|
||||||
ArduinoOTA.handle();
|
ArduinoOTA.handle();
|
||||||
server.handleClient();
|
|
||||||
wifi_loop();
|
|
||||||
serial_read();
|
serial_read();
|
||||||
|
server.handleClient();
|
||||||
|
config_loop();
|
||||||
|
wifi_loop();
|
||||||
mode_check();
|
mode_check();
|
||||||
display.loop();
|
display.loop();
|
||||||
mode_step();
|
mode_step();
|
||||||
@ -225,7 +241,7 @@ void serial_read() {
|
|||||||
case '7':
|
case '7':
|
||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
newModeId = (ModeId) (input - '0');
|
setMode((ModeId) (input - '0'));
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
setBrightness(display.getBrightness() + 10);
|
setBrightness(display.getBrightness() + 10);
|
||||||
@ -234,10 +250,10 @@ void serial_read() {
|
|||||||
setBrightness(max(1, display.getBrightness() - 10));
|
setBrightness(max(1, display.getBrightness() - 10));
|
||||||
break;
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
setSpeed(speed / 1.1);
|
setSpeed(config.speed / 1.1);
|
||||||
break;
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
setSpeed(speed * 1.1);
|
setSpeed(config.speed * 1.1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Serial.printf("Unknown command: %c\n", input);
|
Serial.printf("Unknown command: %c\n", input);
|
||||||
@ -246,18 +262,29 @@ void serial_read() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setBrightness(int value) {
|
void setBrightness(int brightness) {
|
||||||
display.setBrightness(value);
|
brightness = max(0, min(brightness, 255));
|
||||||
Serial.printf("Setting brightness to %5.1f%%\n", value / 2.55);
|
if (display.getBrightness() == brightness) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.brightness = brightness;
|
||||||
|
display.setBrightness(brightness);
|
||||||
|
config_set_dirty();
|
||||||
|
Serial.printf("Setting brightness to %5.1f%%\n", brightness / 2.55);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSpeed(double value) {
|
void setSpeed(double speed) {
|
||||||
speed = value;
|
speed = min(max(0.01, speed), 10000.0);
|
||||||
Serial.printf("Setting speed to %6.2fx\n", value);
|
if (config.speed == speed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config.speed = speed;
|
||||||
|
config_set_dirty();
|
||||||
|
Serial.printf("Setting speed to %6.2fx\n", config.speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mode_check() {
|
void mode_check() {
|
||||||
if (currentModeId != newModeId) {
|
if (currentModeId != config.mode) {
|
||||||
unloadOldMode();
|
unloadOldMode();
|
||||||
loadNewMode();
|
loadNewMode();
|
||||||
}
|
}
|
||||||
@ -272,11 +299,9 @@ void unloadOldMode() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loadNewMode() {
|
void loadNewMode() {
|
||||||
currentModeId = newModeId;
|
currentModeId = config.mode;
|
||||||
lastMicros = 0;
|
lastMicros = 0;
|
||||||
switch (currentModeId) {
|
switch (currentModeId) {
|
||||||
case NONE:
|
|
||||||
break;
|
|
||||||
case BORDER:
|
case BORDER:
|
||||||
mode = new Border(&display);
|
mode = new Border(&display);
|
||||||
break;
|
break;
|
||||||
@ -304,6 +329,9 @@ void loadNewMode() {
|
|||||||
case NEW_YEAR:
|
case NEW_YEAR:
|
||||||
mode = new NewYear(&display);
|
mode = new NewYear(&display);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
Serial.print("No mode loaded.\n");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Serial.printf("Mode: %s\n", mode == nullptr ? "None" : mode->getName());
|
Serial.printf("Mode: %s\n", mode == nullptr ? "None" : mode->getName());
|
||||||
}
|
}
|
||||||
@ -313,7 +341,7 @@ void mode_step() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto currentMicros = (int64_t) micros();
|
auto currentMicros = (int64_t) micros();
|
||||||
microseconds_t dt = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * speed));
|
microseconds_t dt = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * config.speed));
|
||||||
lastMicros = currentMicros;
|
lastMicros = currentMicros;
|
||||||
mode->step(dt);
|
mode->step(dt);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,19 @@
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "ModeBase.h"
|
#include "ModeBase.h"
|
||||||
|
|
||||||
|
enum ModeId {
|
||||||
|
NONE,
|
||||||
|
BORDER,
|
||||||
|
CLOCK,
|
||||||
|
GAME_OF_LIFE_BLACK_WHITE,
|
||||||
|
GAME_OF_LIFE_GRAYSCALE,
|
||||||
|
GAME_OF_LIFE_COLOR_FADE,
|
||||||
|
GAME_OF_LIFE_RANDOM_COLOR,
|
||||||
|
PONG,
|
||||||
|
SPACE_INVADERS,
|
||||||
|
NEW_YEAR,
|
||||||
|
};
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class Mode : public ModeBase {
|
class Mode : public ModeBase {
|
||||||
|
|
||||||
|
|||||||
@ -36,7 +36,6 @@ class NewYear : public Mode<NewYear> {
|
|||||||
display->clear();
|
display->clear();
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
drawNoTime();
|
drawNoTime();
|
||||||
drawSubSecondsBar(info.tm_sec);
|
|
||||||
} else if (info.tm_mon == 1 && info.tm_mday == 1 && info.tm_hour == 0) {
|
} else if (info.tm_mon == 1 && info.tm_mday == 1 && info.tm_hour == 0) {
|
||||||
drawYear(counter, info.tm_year + 1900);
|
drawYear(counter, info.tm_year + 1900);
|
||||||
drawFirework(timer->interval);
|
drawFirework(timer->interval);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user