diff --git a/include/EggDuino.h b/include/EggDuino.h index ce675ad..da7275c 100644 --- a/include/EggDuino.h +++ b/include/EggDuino.h @@ -114,5 +114,8 @@ String buildConfigJson(); bool applyConfigJson(const String &payload, String &errorMessage); void startWebInterface(); void handleWebInterface(); +void Log(const String &message); +void Log(const char *message); +String buildLogsJson(uint32_t sinceSeq); #endif diff --git a/platformio.ini b/platformio.ini index b059e7d..94d1dc8 100644 --- a/platformio.ini +++ b/platformio.ini @@ -12,7 +12,7 @@ platform = platformio/espressif32 board = esp32dev framework = arduino -monitor_speed = 115200 +monitor_speed = 9600 upload_speed = 576000 upload_port = /dev/ttyUSB* lib_deps = diff --git a/src/Config_Web.cpp b/src/Config_Web.cpp index ffe2a50..c89a8cb 100644 --- a/src/Config_Web.cpp +++ b/src/Config_Web.cpp @@ -1,16 +1,12 @@ #include "EggDuino.h" #include -#include namespace { const char *kConfigPath = "/config.json"; -const char *kApSsid = "EggDuino"; -const uint16_t kDnsPort = 53; -const IPAddress kApIp(192, 168, 4, 1); -const IPAddress kApSubnet(255, 255, 255, 0); +const char *kWifiSsid = "Sternenlabor"; +const char *kWifiPassword = "!Sternenlabor99!"; WebServer server(80); -DNSServer dnsServer; bool configStoreReady = false; ConfigParameter *findParameter(const String &key) { @@ -38,12 +34,14 @@ void handleRoot() { EggDuino Konfiguration @@ -52,8 +50,12 @@ button { margin-top: 18px; border: 0; background: #0b5ed7; color: white; padding
+
Logs
+
@@ -118,14 +138,6 @@ async function saveConfig() { server.send(200, "text/html", kPage); } -void redirectToPortal() { - server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.sendHeader("Location", String("http://") + WiFi.softAPIP().toString() + "/", true); - server.send(302, "text/plain", ""); -} - void handleGetConfig() { if (!configStoreReady && !initConfigStore()) { server.send(500, "text/plain", "Config storage not available"); @@ -160,6 +172,14 @@ void handlePostConfig() { // penServo.write(penState); server.send(200, "application/json", buildConfigJson()); } + +void handleGetLogs() { + uint32_t since = 0; + if (server.hasArg("since")) { + since = static_cast(server.arg("since").toInt()); + } + server.send(200, "application/json", buildLogsJson(since)); +} } // namespace ConfigParameter configParameters[] = { @@ -284,28 +304,30 @@ bool applyConfigJson(const String &payload, String &errorMessage) { } void startWebInterface() { - WiFi.mode(WIFI_AP); - WiFi.softAPConfig(kApIp, kApIp, kApSubnet); - WiFi.softAP(kApSsid); - dnsServer.start(kDnsPort, "*", WiFi.softAPIP()); + WiFi.mode(WIFI_STA); + WiFi.begin(kWifiSsid, kWifiPassword); + + const unsigned long connectStart = millis(); + const unsigned long connectTimeoutMs = 20000; + while (WiFi.status() != WL_CONNECTED && millis() - connectStart < connectTimeoutMs) { + delay(250); + } + initConfigStore(); - Serial.print("Config AP IP: "); - Serial.println(WiFi.softAPIP()); + if (WiFi.status() == WL_CONNECTED) { + Serial.println(String("WLAN verbunden, IP: ") + WiFi.localIP().toString()); + } else { + Serial.println("WLAN Verbindung fehlgeschlagen"); + } server.on("/", HTTP_GET, handleRoot); server.on("/api/config", HTTP_GET, handleGetConfig); server.on("/api/config", HTTP_POST, handlePostConfig); - server.on("/generate_204", HTTP_GET, redirectToPortal); - server.on("/gen_204", HTTP_GET, redirectToPortal); - server.on("/hotspot-detect.html", HTTP_GET, redirectToPortal); - server.on("/library/test/success.html", HTTP_GET, redirectToPortal); - server.on("/ncsi.txt", HTTP_GET, redirectToPortal); - server.on("/connecttest.txt", HTTP_GET, redirectToPortal); - server.onNotFound(redirectToPortal); + server.on("/api/logs", HTTP_GET, handleGetLogs); + server.onNotFound(handleRoot); server.begin(); } void handleWebInterface() { - dnsServer.processNextRequest(); server.handleClient(); } diff --git a/src/Helper_Functions.cpp b/src/Helper_Functions.cpp index 59e367a..0bae1bc 100644 --- a/src/Helper_Functions.cpp +++ b/src/Helper_Functions.cpp @@ -121,6 +121,22 @@ void prepareMove(uint16_t duration, int penStepsEBB, int rotStepsEBB) { motorsOn(); } + + if (duration == 0) + { + duration = 1; + } + + if (penStepCorrection == 0) + { + penStepCorrection = 1; + } + + if (rotStepCorrection == 0) + { + rotStepCorrection = 1; + } + if ((1 == rotStepCorrection) && (1 == penStepCorrection)) { // if coordinatessystems are identical // set Coordinates and Speed @@ -128,11 +144,11 @@ void prepareMove(uint16_t duration, int penStepsEBB, int rotStepsEBB) // rotMotor.setSpeed(abs((float)rotStepsEBB * (float)1000 / (float)duration)); g_pStepperRotate->move(rotStepsEBB); g_pStepperRotate->setSpeedInTicks(abs((float)rotStepsEBB * (float)1000 / (float)duration)); - + // penMotor.move(penStepsEBB); // penMotor.setSpeed(abs((float)penStepsEBB * (float)1000 / (float)duration)); g_pStepperPen->move(penStepsEBB); - g_pStepperRotate->setSpeedInTicks(abs((float)penStepsEBB * (float)1000 / (float)duration)); + g_pStepperPen->setSpeedInTicks(abs((float)penStepsEBB * (float)1000 / (float)duration)); } else { @@ -162,12 +178,14 @@ void prepareMove(uint16_t duration, int penStepsEBB, int rotStepsEBB) // penMotor.move(penStepsToGo); // penMotor.setSpeed(penSpeed); g_pStepperPen->move(penStepsToGo); - g_pStepperRotate->setSpeedInTicks(penSpeed); + g_pStepperPen->setSpeedInTicks(penSpeed); } } void moveOneStep() { + while (g_pStepperPen->isRunning() || g_pStepperRotate->isRunning()) + ; // if (penMotor.distanceToGo() || rotMotor.distanceToGo()) // { // penMotor.runSpeedToPosition(); // Moving.... moving... moving.... @@ -177,6 +195,8 @@ void moveOneStep() void moveToDestination() { + while (g_pStepperPen->isRunning() || g_pStepperRotate->isRunning()) + ; // while (penMotor.distanceToGo() || rotMotor.distanceToGo()) // { // penMotor.runSpeedToPosition(); // Moving.... moving... moving.... diff --git a/src/Logging.cpp b/src/Logging.cpp new file mode 100644 index 0000000..faec960 --- /dev/null +++ b/src/Logging.cpp @@ -0,0 +1,86 @@ +#include "EggDuino.h" + +namespace { +constexpr size_t kLogCapacity = 80; +constexpr size_t kLogLineLength = 160; + +char g_logLines[kLogCapacity][kLogLineLength]; +uint32_t g_logSeq[kLogCapacity]; +size_t g_logWritePos = 0; +uint32_t g_nextLogSeq = 1; + +void appendJsonEscaped(String &out, const char *text) { + out += "\""; + for (size_t i = 0; text[i] != '\0'; ++i) { + const char c = text[i]; + switch (c) { + case '\\': + out += "\\\\"; + break; + case '"': + out += "\\\""; + break; + case '\n': + out += "\\n"; + break; + case '\r': + out += "\\r"; + break; + case '\t': + out += "\\t"; + break; + default: + if (static_cast(c) < 0x20) { + out += '?'; + } else { + out += c; + } + break; + } + } + out += "\""; +} +} // namespace + +void Log(const String &message) { + const String trimmed = message.substring(0, kLogLineLength - 1); + trimmed.toCharArray(g_logLines[g_logWritePos], kLogLineLength); + g_logSeq[g_logWritePos] = g_nextLogSeq++; + g_logWritePos = (g_logWritePos + 1) % kLogCapacity; +} + +void Log(const char *message) { + Log(String(message)); +} + +String buildLogsJson(uint32_t sinceSeq) { + String output; + output.reserve(2048); + output += "{\"logs\":["; + uint32_t lastSeq = sinceSeq; + bool first = true; + + for (size_t i = 0; i < kLogCapacity; ++i) { + const size_t idx = (g_logWritePos + i) % kLogCapacity; + const uint32_t seq = g_logSeq[idx]; + if (seq == 0 || seq <= sinceSeq) { + continue; + } + + if (!first) { + output += ","; + } + first = false; + output += "{\"seq\":"; + output += String(seq); + output += ",\"text\":"; + appendJsonEscaped(output, g_logLines[idx]); + output += "}"; + lastSeq = seq; + } + + output += "],\"lastSeq\":"; + output += String(lastSeq); + output += "}"; + return output; +} diff --git a/src/main.cpp b/src/main.cpp index fe34992..580a9c1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,10 +77,10 @@ void setup() { Serial.begin(9600); Serial.println("Starting..."); + Log("Starting..."); makeComInterface(); initHardware(); startWebInterface(); - } uint8_t g_uiState = 0; @@ -88,18 +88,18 @@ unsigned long g_uiLastTim = millis(); void loop() { - #ifdef TEST + unsigned long uiNow = millis(); motorsOn(); - if (uiNow - g_uiLastTim > 500) + if (uiNow - g_uiLastTim > 5000) { g_uiLastTim = uiNow; switch (g_uiState) { case 0: - Serial.println(g_uiState); + Log(String(g_uiState)); g_pStepperRotate->setSpeedInUs(10); // the parameter is us/step !!! g_pStepperRotate->setAcceleration(10000); g_pStepperRotate->move(1000); @@ -107,7 +107,7 @@ void loop() break; case 1: - Serial.println(g_uiState); + Log(String(g_uiState)); g_pStepperRotate->setSpeedInUs(10); // the parameter is us/step !!! g_pStepperRotate->setAcceleration(10000); g_pStepperRotate->move(-1000); @@ -115,7 +115,7 @@ void loop() break; case 2: - Serial.println(g_uiState); + Log(String(g_uiState)); g_pStepperPen->setSpeedInUs(10); // the parameter is us/step !!! g_pStepperPen->setAcceleration(10000); g_pStepperPen->move(1000); @@ -123,7 +123,7 @@ void loop() break; case 3: - Serial.println(g_uiState); + Log(String(g_uiState)); g_pStepperPen->setSpeedInUs(10); // the parameter is us/step !!! g_pStepperPen->setAcceleration(10000); g_pStepperPen->move(-1000); @@ -133,9 +133,10 @@ void loop() default: break; } + Log("Alive"); } #endif - //moveOneStep(); + // moveOneStep(); SCmd.readSerial(); handleWebInterface();