266 lines
6.1 KiB
C++
266 lines
6.1 KiB
C++
#include <WiFi.h>
|
|
#include <ArduinoOTA.h>
|
|
#include "mode/Mode.h"
|
|
#include "display/Display.h"
|
|
#include <WebServer.h>
|
|
|
|
#if PROG_ALL
|
|
|
|
#include "mode/GameOfLife/GameOfLife.h"
|
|
#include "mode/Pong/Pong.h"
|
|
#include "mode/Test/Border.h"
|
|
#include "mode/Clock/Clock.h"
|
|
#include "mode/SpaceInvaders/SpaceInvaders.h"
|
|
|
|
#endif
|
|
|
|
#include "mode/NewYear/NewYear.h"
|
|
|
|
enum ModeId {
|
|
NONE,
|
|
#if PROG_ALL
|
|
BORDER,
|
|
CLOCK,
|
|
GAME_OF_LIFE_BLACK_WHITE,
|
|
GAME_OF_LIFE_GRAYSCALE,
|
|
GAME_OF_LIFE_COLOR_FADE,
|
|
GAME_OF_LIFE_RANDOM_COLOR,
|
|
PONG,
|
|
SPACE_INVADERS,
|
|
#endif
|
|
NEW_YEAR,
|
|
};
|
|
|
|
WebServer server(80);
|
|
|
|
Display display(32, 8);
|
|
|
|
ModeId newModeId = NEW_YEAR;
|
|
|
|
ModeId currentModeId = NONE;
|
|
|
|
microseconds_t lastMicros = 0;
|
|
|
|
Mode *mode = nullptr;
|
|
|
|
double speed = 1.0;
|
|
|
|
bool connected = false;
|
|
|
|
void checkMode();
|
|
|
|
void stepMode();
|
|
|
|
void unloadOldMode();
|
|
|
|
void loadNewMode();
|
|
|
|
void setBrightness(int value);
|
|
|
|
void web_index() {
|
|
server.setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
server.send(200, "text/html", "");
|
|
server.sendContent("<a href='/mode?mode=0'>NONE</a><br>");
|
|
server.sendContent("<a href='/mode?mode=1'>BORDER</a><br>");
|
|
server.sendContent("<a href='/mode?mode=2'>CLOCK</a><br>");
|
|
server.sendContent("<a href='/mode?mode=3'>GAME_OF_LIFE_BLACK_WHITE</a><br>");
|
|
server.sendContent("<a href='/mode?mode=4'>GAME_OF_LIFE_GRAYSCALE</a><br>");
|
|
server.sendContent("<a href='/mode?mode=5'>GAME_OF_LIFE_COLOR_FADE</a><br>");
|
|
server.sendContent("<a href='/mode?mode=6'>GAME_OF_LIFE_RANDOM_COLOR</a><br>");
|
|
server.sendContent("<a href='/mode?mode=7'>PONG</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("Helligkeit: <a href='/brighter'>+</a> / <a href='/darker'>-</a><br>");
|
|
server.client().flush();
|
|
}
|
|
|
|
void web_setMode() {
|
|
if (!server.hasArg("mode")) {
|
|
server.send(400, "text/plain", "Missing 'mode'");
|
|
return;
|
|
}
|
|
double value = strtod(server.arg("mode").c_str(), nullptr);
|
|
if (isnan(value)) {
|
|
server.send(400, "text/plain", "'mode' not a number");
|
|
return;
|
|
}
|
|
newModeId = (ModeId) value;
|
|
server.sendHeader("location", "/");
|
|
server.send(301, "text/plain", "ok");
|
|
}
|
|
|
|
void web_brighter() {
|
|
setBrightness(display.getBrightness() + 10);
|
|
}
|
|
|
|
void web_darker() {
|
|
setBrightness(max(1, display.getBrightness() - 10));
|
|
}
|
|
|
|
void setup() {
|
|
delay(500);
|
|
Serial.begin(115200);
|
|
Serial.println("\n\n\nStartup!");
|
|
|
|
WiFi.begin("HappyNet", "1Grausame!Sackratte7");
|
|
ArduinoOTA.onStart([]() {
|
|
display.clear();
|
|
display.loop();
|
|
});
|
|
ArduinoOTA.onProgress([](unsigned int total, unsigned int progress) {
|
|
double ratio = (double) progress / (double) total;
|
|
auto index = (uint16_t) round(ratio * (double) display.pixelCount);
|
|
auto color = (uint8_t) round(ratio * 255.0);
|
|
display.setIndex(index, 255 - color, color, 0);
|
|
display.loop();
|
|
});
|
|
ArduinoOTA.onEnd([]() {
|
|
display.clear();
|
|
display.loop();
|
|
});
|
|
ArduinoOTA.onError([](int error) {
|
|
display.clear();
|
|
display.loop();
|
|
});
|
|
ArduinoOTA.begin();
|
|
|
|
server.on("", web_index);
|
|
server.on("/", web_index);
|
|
server.on("/mode", web_setMode);
|
|
server.on("/mode/", web_setMode);
|
|
server.on("/brighter", web_brighter);
|
|
server.on("/brighter/", web_brighter);
|
|
server.on("/darker", web_darker);
|
|
server.on("/darker/", web_darker);
|
|
server.begin();
|
|
|
|
display.setup();
|
|
}
|
|
|
|
void setSpeed(double value);
|
|
|
|
void loop() {
|
|
ArduinoOTA.handle();
|
|
server.handleClient();
|
|
bool hasIp = (uint32_t) WiFi.localIP() != 0;
|
|
if (!connected) {
|
|
if (hasIp) {
|
|
connected = true;
|
|
Serial.printf("WiFi connected: %s\n", WiFi.localIP().toString().c_str());
|
|
configTime(3600, 3600, WiFi.gatewayIP().toString().c_str());
|
|
}
|
|
} else {
|
|
if (!hasIp) {
|
|
connected = false;
|
|
Serial.println("WiFi disconnected!");
|
|
}
|
|
}
|
|
|
|
if (Serial.available()) {
|
|
int input = Serial.read();
|
|
switch (input) {
|
|
case '0':
|
|
case '1':
|
|
case '2':
|
|
case '3':
|
|
case '4':
|
|
case '5':
|
|
case '6':
|
|
case '7':
|
|
case '8':
|
|
case '9':
|
|
newModeId = (ModeId) (input - '0');
|
|
break;
|
|
case '+':
|
|
setBrightness(display.getBrightness() + 10);
|
|
break;
|
|
case '-':
|
|
setBrightness(max(1, display.getBrightness() - 10));
|
|
break;
|
|
case ',':
|
|
setSpeed(speed / 1.1);
|
|
break;
|
|
case '.':
|
|
setSpeed(speed * 1.1);
|
|
break;
|
|
}
|
|
}
|
|
checkMode();
|
|
display.loop();
|
|
stepMode();
|
|
}
|
|
|
|
void setBrightness(int value) {
|
|
display.setBrightness(value);
|
|
Serial.printf("Setting brightness to %5.1f%%\n", value / 2.55);
|
|
}
|
|
|
|
void setSpeed(double value) {
|
|
speed = value;
|
|
Serial.printf("Setting speed to %6.2fx\n", value);
|
|
}
|
|
|
|
void checkMode() {
|
|
if (currentModeId != newModeId) {
|
|
unloadOldMode();
|
|
loadNewMode();
|
|
}
|
|
}
|
|
|
|
void unloadOldMode() {
|
|
if (mode != nullptr) {
|
|
delete mode;
|
|
mode = nullptr;
|
|
}
|
|
display.clear();
|
|
}
|
|
|
|
void loadNewMode() {
|
|
currentModeId = newModeId;
|
|
lastMicros = 0;
|
|
switch (currentModeId) {
|
|
case NONE:
|
|
break;
|
|
#if PROG_ALL
|
|
case BORDER:
|
|
mode = new Border(&display);
|
|
break;
|
|
case CLOCK:
|
|
mode = new Clock(&display);
|
|
break;
|
|
case GAME_OF_LIFE_BLACK_WHITE:
|
|
mode = new GameOfLife(&display, BLACK_WHITE);
|
|
break;
|
|
case GAME_OF_LIFE_GRAYSCALE:
|
|
mode = new GameOfLife(&display, GRAYSCALE);
|
|
break;
|
|
case GAME_OF_LIFE_COLOR_FADE:
|
|
mode = new GameOfLife(&display, COLOR_FADE);
|
|
break;
|
|
case GAME_OF_LIFE_RANDOM_COLOR:
|
|
mode = new GameOfLife(&display, RANDOM_COLOR);
|
|
break;
|
|
case PONG:
|
|
mode = new Pong(&display);
|
|
break;
|
|
case SPACE_INVADERS:
|
|
mode = new SpaceInvaders(&display);
|
|
break;
|
|
#endif
|
|
case NEW_YEAR:
|
|
mode = new NewYear(&display);
|
|
break;
|
|
}
|
|
Serial.printf("Mode: %s\n", mode == nullptr ? "None" : mode->getName());
|
|
}
|
|
|
|
void stepMode() {
|
|
if (mode == nullptr) {
|
|
return;
|
|
}
|
|
auto currentMicros = (int64_t) micros();
|
|
microseconds_t dt = (microseconds_t) min(1000000.0, max(1.0, (double) (currentMicros - lastMicros) * speed));
|
|
lastMicros = currentMicros;
|
|
mode->step(dt);
|
|
}
|