ESP32 GCode Streamen zum Arduino Uno (GRBL)

Hallo, ich bin soweit GCode Daten vom ESP32 zu meinem Arduino der mit GRBL 0.9 läuft zu Streamen. Hier soweit meine verkabelung von der Serial Kommunikation:

Ich habe mir die GRBL Docs angeschaut und die stream.py gefunden was ein beispiel zeigt Daten zu GRBL zu streamen darauf hin hatte ich versucht das in C nach zu machen hier mein Sketch:

#include <WiFi.h>
#include <LITTLEFS.h>
#include <ESPAsyncWebServer.h>
#include <WebSocketsServer.h>
#include <queue>
#include <vector>

#define FORMAT_LITTLEFS_IF_FAILED false
#define RXD2 16
#define TXD2 17

// Constants
const char *ssid = "Admin";
const char *password = "123456789";
const int http_port = 80;
const int led_pin = 2;

// Globals
AsyncWebServer server(http_port);
WebSocketsServer webSocket = WebSocketsServer(81);

// Gcode Queue
std::queue<char *> gcodeQueue;
bool waitingForOk = false;

/***********************************************************
   Functions
*/

// Callback: receiving any WebSocket message
void onWebSocketEvent(uint8_t client_num,
                      WStype_t type,
                      uint8_t *payload,
                      size_t length)
{

  // Figure out the type of WebSocket event
  switch (type)
  {

  // Client has disconnected
  case WStype_DISCONNECTED:
    Serial.printf("[%u] Disconnected!\n", client_num);
    break;

  // New client has connected
  case WStype_CONNECTED:
  {
    IPAddress ip = webSocket.remoteIP(client_num);
    Serial.printf("[%u] Connection from ", client_num);
    Serial.println(ip.toString());
  }
  break;

  // For everything else: do nothing
  case WStype_TEXT:
  case WStype_BIN:
  case WStype_ERROR:
  case WStype_FRAGMENT_TEXT_START:
  case WStype_FRAGMENT_BIN_START:
  case WStype_FRAGMENT:
  case WStype_FRAGMENT_FIN:
  default:
    break;
  }
}

// Callback: send 404 if requested file does not exist
void onPageNotFound(AsyncWebServerRequest *request)
{
  IPAddress remote_ip = request->client()->remoteIP();
  Serial.println("[" + remote_ip.toString() +
                 "] HTTP GET request of " + request->url());
  request->send(404, "text/plain", "Not found");
}

/***********************************************************
   Main
*/

void setup()
{

  // Start Serial port
  Serial.begin(115200);
  Serial2.begin(115200, SERIAL_8N1, RXD2, TXD2);

  // Make sure we can read the file system
  if (!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED))
  {
    Serial.println("Error mounting SPIFFS");
    return;
  }

  int tBytes = LITTLEFS.totalBytes();
  int uBytes = LITTLEFS.usedBytes();
  Serial.println("File system info");
  Serial.print("Total bytes: ");
  Serial.println(tBytes);
  Serial.print("Used bytes: ");
  Serial.println(uBytes);

  // Start access point
  WiFi.softAP(ssid, password);

  // Print our IP address
  Serial.println();
  Serial.println("AP running");
  Serial.print("My IP address: ");
  Serial.println(WiFi.softAPIP());

  server.serveStatic("/", LITTLEFS, "/");

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request)
            {
        AsyncWebServerResponse* response = request->beginResponse(LITTLEFS, "/index.html", "text/html");
        response->addHeader("Content-Encoding", "gzip");
        request->send(response); });

  server.on(
      "/upload", HTTP_POST, [](AsyncWebServerRequest *request)
      { request->send(200); },
      handleUpload);

  server.on(
      "/gcode", HTTP_POST, [](AsyncWebServerRequest *request)
      { request->send(200); },
      handleGcode);

  // Handle file delete
  server.on("/delete", HTTP_DELETE, [](AsyncWebServerRequest *request)
            {
    if (request->hasParam("filename")) { // if the request has a parameter named "filename"
        String filename = request->getParam("filename")->value(); // get the value of the "filename" parameter
        if (LITTLEFS.remove("/" + filename)) { // attempt to delete the file
            request->send(200, "text/plain", "Successfull deleted file: " + filename); // if successful, send a 200 OK response
        } else {
            request->send(500, "text/plain", "Failed to delete file"); // if unsuccessful, send a 500 Internal Server Error response
        }
    } else {
        request->send(400, "text/plain", "Bad request"); // if the request does not have a "filename" parameter, send a 400 Bad Request response
    } });

  // Handle GET request for file list
  server.on("/files", HTTP_GET, [](AsyncWebServerRequest *request)
            {
    if (request->hasParam("directory")) {
        String directory = request->getParam("directory")->value();
        String fileList = "";
        File root = LITTLEFS.open(directory);

        if (root && root.isDirectory()) {
            File file = root.openNextFile();
            while (file) {
                String fileNameWithPath = file.name();
                String fileName = fileNameWithPath.substring(directory.length());
                fileList += fileName;
                fileList += "\n";
                file = root.openNextFile();
            }
        }

        Serial.println(fileList);
        request->send(200, "text/plain", fileList);
    } else {
        request->send(400, "text/plain", "Bad request");
    } });

  // Handle bytes check
  server.on("/space", HTTP_GET, [](AsyncWebServerRequest *request)
            { request->send(200, "text/plain", String(LITTLEFS.totalBytes()) + "," + String(LITTLEFS.usedBytes())); });

  // Handle requests for pages that do not exist
  server.onNotFound(onPageNotFound);

  // Start web server
  server.begin();

  // Start WebSocket server and assign callback
  webSocket.begin();

  // enable heartbeat for websocket
  webSocket.enableHeartbeat(15000, 3000, 2);

  webSocket.onEvent(onWebSocketEvent);
}
#define RX_BUFFER_SIZE 128   // adjust this to your needs
#define MAX_GCODE_LENGTH 128 // adjust this to your needs

int g_count = 0;
int l_count = 0;
int error_count = 0;
bool verbose = true;

int len = 0;
char l_block[MAX_GCODE_LENGTH];

void loop()
{
  webSocket.loop();

  if (!gcodeQueue.empty())
  {
    bool okReceived = false;
    char *l_block = gcodeQueue.front();
    gcodeQueue.pop();
    len = strlen(l_block) + 1;
    while (len >= RX_BUFFER_SIZE - 1 || Serial2.available())
    {
      char out_temp[RX_BUFFER_SIZE];
      Serial2.readBytesUntil('\n', out_temp, RX_BUFFER_SIZE);
      if (strstr(out_temp, "ok") == NULL && strstr(out_temp, "error") == NULL)
      {
        Serial.println("    MSG: \"" + String(out_temp) + "\""); // Debug response
      }
      else
      {
        if (!okReceived && strstr(out_temp, "ok") != NULL)
        {
          okReceived = true;
          g_count += 1;
          len -= strlen(l_block) + 1;
          if (verbose)
            Serial.println("  REC<" + String(g_count) + ": \"" + String(out_temp) + "\"");
        }
        if (strstr(out_temp, "error") != NULL)
          error_count += 1;
      }
    }
    Serial2.println(l_block); // Send g-code block to grbl
    if (verbose)
      Serial.println("SND>" + String(l_count) + ": \"" + String(l_block) + "\"");
    l_count += 1;
    delete[] l_block; // delete the gcode line when done with it
  }

  // Wait until all responses have been received.
  while (l_count > g_count)
  {
    bool okReceived = false;
    char out_temp[RX_BUFFER_SIZE];
    Serial2.readBytesUntil('\n', out_temp, RX_BUFFER_SIZE);
    if (strstr(out_temp, "ok") == NULL && strstr(out_temp, "error") == NULL)
    {
      Serial.println("    MSG: \"" + String(out_temp) + "\""); // Debug response
    }
    else
    {
      if (!okReceived && strstr(out_temp, "ok") != NULL)
      {
        okReceived = true;
        g_count += 1;
        len -= strlen(l_block) + 1;
        if (verbose)
          Serial.println("  REC<" + String(g_count) + ": \"" + String(out_temp) + "\"");
      }
      if (strstr(out_temp, "error") != NULL)
        error_count += 1;
    }
  }
}

void ReceivedGCodeData(uint8_t *payload, size_t length)
{
  // Tokenize the payload into lines
  char *token;
  char *saveptr;
  token = strtok_r((char *)payload, ",", &saveptr);
  while (token != NULL)
  {
    byte mode = 0;
    if (strcmp(token, "M7") == 0)
    {
      mode = 1;
    }
    if (strcmp(token, "M8") == 0)
    {
      mode = 1;
    }
    if (strcmp(token, "M2") == 0)
    {
      mode = 1;
    }
    if (strncmp(token, "G1", 2) == 0)
    {
      mode = 1;
    }
    if (strncmp(token, "G0", 2) == 0)
    {
      mode = 1;
    }
    if (strcmp(token, "G21") == 0)
    {
      mode = 1;
    }
    if (strcmp(token, "G90") == 0)
    {
      mode = 1;
    }
    if (strncmp(token, "G92", 3) == 0)
    {
      mode = 1;
    }
    if (strcmp(token, "F1250") == 0)
    {
      mode = 1;
    }
    if (mode == 1)
    {
      char *gcodeLine = new char[strlen(token) + 1];
      strcpy(gcodeLine, token);
      gcodeQueue.push(gcodeLine);
    }
    token = strtok_r(NULL, ",", &saveptr);
 }
  // Flush the Serial2 buffer
  Serial2.flush();
}

// handles uploads
void handleUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
{
  String logmessage = "Client:" + request->client()->remoteIP().toString() + " " + request->url();
  Serial.println(logmessage);

  if (!index)
  {
    logmessage = "Upload Start: " + String(filename);
    // open the file on first call and store the file handle in the request object
    request->_tempFile = LITTLEFS.open("/" + filename, "w");
    Serial.println(logmessage);
  }

  if (len)
  {
    // stream the incoming chunk to the opened file
    request->_tempFile.write(data, len);
    logmessage = "Writing file: " + String(filename) + " index=" + String(index) + " len=" + String(len);
    Serial.println(logmessage);
  }

  if (final)
  {
    logmessage = "Upload Complete: " + String(filename) + ",size: " + String(index + len);
    // close the file handle as the upload is now done
    request->_tempFile.close();
    Serial.println(logmessage);
  }
}

// handles gcode file uploads
void handleGcode(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final)
{
  static std::vector<uint8_t> buffer;

  if (!index)
  {
    Serial.println("Gcode received");

    // Wake up Grbl in the time between uploads
    Serial2.println("\r\n\r\n");

    // Clear the buffer
    buffer.clear();
  }

  if (len)
  {
    // Append the incoming data to the buffer
    buffer.insert(buffer.end(), data, data + len);
  }

  if (final)
  {
    Serial.println("Gcode upload complete");

    // Send the buffer to ReceivedGCodeData
    ReceivedGCodeData(buffer.data(), buffer.size());

    // Clear the buffer
    buffer.clear();
  }
}

Die Daten also handleGcode kommt vom Client (Auf dem ESP32 läuft ein Webserver) aber das scheint alles normal zu funktionieren, jetzt das Problem: Das Sketch so funktioniert bedeutet ich lade den Gcode hoch und er wird auch sehr effizient abgefahren, jedoch bei manchen GCodes gehen Daten am ende verloren also so sieht ein Beispiel von Daten aus:

G21
G90
F1250
M8
G92 X0 Y0
G0 X19.58 Y7.75
M7
G1 X19.48 Y7.75
G1 X17.27 Y7.75
G1 X15.58 Y8.18
G1 X14.10 Y9.23
G1 X12.84 Y10.71
G1 X11.68 Y12.18
G1 X10.84 Y13.66
G1 X10.10 Y15.03
G1 X9.47 Y16.82
G1 X9.25 Y18.93
G1 X9.36 Y21.46
G1 X10.10 Y22.93
G1 X11.05 Y24.20
G1 X12.21 Y25.46
G1 X13.47 Y26.41
G1 X15.26 Y27.15
G1 X17.27 Y27.68
G1 X19.27 Y27.89
G1 X21.48 Y27.89
G1 X23.80 Y27.68
G1 X25.80 Y27.36
G1 X27.49 Y26.62
G1 X28.75 Y25.67
G1 X29.70 Y24.51
G1 X30.55 Y23.04
G1 X31.07 Y21.25
G1 X31.39 Y19.56
G1 X31.39 Y17.35
G1 X31.18 Y15.34
G1 X30.34 Y13.66
G1 X29.39 Y12.29
G1 X28.02 Y11.13
G1 X26.54 Y10.39
G1 X24.85 Y9.65
G1 X23.17 Y9.12
G1 X21.48 Y8.49
G1 X19.90 Y7.86
M8
M2
G0 X0 Y0
GCODE

Das GCODE am ende hat keinen wirklichen einfluss außer das es das "G0 X0 Y0" noch in die gcodeQueue macht aber ist ja egal die Daten kommen aufjedenfall an also ich bekomme für jede Zeile ein SND Debug Response, aber wie gesagt bei manchen GCode Kombinationen kommt zum beispiel das "M8" am ende nicht durch oder auch "G0 X0 Y0" ich weiß nicht woran es liegt, vielleicht der Code sendet zu schnell, der Code kriegt das Ok für ein ganz anderen GCode vorher kein plan, so sieht das erste Protokol während des verarbeiten aus (Also vom GCode den ich da oben reingepackt habe):

Gcode received
Gcode upload complete
  REC<1: "ok"
SND>0: "G21"
SND>1: "G90"
  REC<2: "ok"
  REC<3: "ok"
SND>2: "F1250"
  REC<4: "ok"
SND>3: "M8"
SND>4: "G92 X0 Y0"
  REC<5: "ok"
  REC<6: "ok"
SND>5: "G0 X19.58 Y7.75"
SND>6: "M7"
  REC<7: "ok"
  REC<8: "ok"
SND>7: "G1 X19.48 Y7.75"
  REC<9: "ok"
SND>8: "G1 X17.27 Y7.75"
  REC<10: "ok"
SND>9: "G1 X15.58 Y8.18"
SND>10: "G1 X14.10 Y9.23"
    MSG: ""
  REC<11: "ok"
  REC<12: "ok"
SND>11: "G1 X12.84 Y10.71"
  REC<13: "ok"
SND>12: "G1 X11.68 Y12.18"
SND>13: "G1 X10.84 Y13.66"
  REC<14: "ok"
  REC<15: "ok"
SND>14: "G1 X10.10 Y15.03"
  REC<16: "ok"
SND>15: "G1 X9.47 Y16.82"
  REC<17: "ok"
SND>16: "G1 X9.25 Y18.93"
SND>17: "G1 X9.36 Y21.46"
  REC<18: "ok"
  REC<19: "ok"
SND>18: "G1 X10.10 Y22.93"
SND>19: "G1 X11.05 Y24.20"
  REC<20: "ok"
  REC<21: "ok"
SND>20: "G1 X12.21 Y25.46"
SND>21: "G1 X13.47 Y26.41"
  REC<22: "ok"
  REC<23: "ok"
SND>22: "G1 X15.26 Y27.15"
SND>23: "G1 X17.27 Y27.68"
  REC<24: "ok"
  REC<25: "ok"
SND>24: "G1 X19.27 Y27.89"
SND>25: "G1 X21.48 Y27.89"
  REC<26: "ok"
  REC<27: "ok"
SND>26: "G1 X23.80 Y27.68"
SND>27: "G1 X25.80 Y27.36"
  REC<28: "ok"
  REC<29: "ok"
SND>28: "G1 X27.49 Y26.62"
SND>29: "G1 X28.75 Y25.67"
  REC<30: "ok"
  REC<31: "ok"
SND>30: "G1 X29.70 Y24.51"
SND>31: "G1 X30.55 Y23.04"
  REC<32: "ok"
  REC<33: "ok"
SND>32: "G1 X31.07 Y21.25"
SND>33: "G1 X31.39 Y19.56"
  REC<34: "ok"
  REC<35: "ok"
SND>34: "G1 X31.39 Y17.35"
SND>35: "G1 X31.18 Y15.34"
  REC<36: "ok"
  REC<37: "ok"
SND>36: "G1 X30.34 Y13.66"
SND>37: "G1 X29.39 Y12.29"
  REC<38: "ok"
  REC<39: "ok"
SND>38: "G1 X28.02 Y11.13"
SND>39: "G1 X26.54 Y10.39"
  REC<40: "ok"
  REC<41: "ok"
SND>40: "G1 X24.85 Y9.65"
SND>41: "G1 X23.17 Y9.12"
  REC<42: "ok"
  REC<43: "ok"
SND>42: "G1 X21.48 Y8.49"
SND>43: "G1 X19.90 Y7.86"
  REC<44: "ok"
  REC<45: "ok"
SND>44: "M8"
SND>45: "M2"
  REC<46: "ok"
  REC<47: "ok"
SND>46: "G0 X0 Y0"

Beim Zweiten mal senden vom exakt selbem Gcode sieht das schon wieder anders (Das Protokol):

Gcode received
Gcode upload complete
  REC<48: "ok"
    MSG: "[Pgm End] number format�n2>�n2/"
SND>47: "G21"
SND>48: "G90"
  REC<49: "ok"
  REC<50: "ok"
SND>49: "F1250"
  REC<51: "ok"
SND>50: "M8"
  REC<52: "ok"
SND>51: "G92 X0 Y0"
SND>52: "G0 X19.58 Y7.75"
  REC<53: "ok"
  REC<54: "ok"
SND>53: "M7"
  REC<55: "ok"
SND>54: "G1 X19.48 Y7.75"
  REC<56: "ok"
SND>55: "G1 X17.27 Y7.75"
SND>56: "G1 X15.58 Y8.18"
    MSG: ""
  REC<57: "ok"
  REC<58: "ok"
SND>57: "G1 X14.10 Y9.23"
  REC<59: "ok"
SND>58: "G1 X12.84 Y10.71"
SND>59: "G1 X11.68 Y12.18"
  REC<60: "ok"
  REC<61: "ok"
SND>60: "G1 X10.84 Y13.66"
  REC<62: "ok"
SND>61: "G1 X10.10 Y15.03"
  REC<63: "ok"
SND>62: "G1 X9.47 Y16.82"
  REC<64: "ok"
SND>63: "G1 X9.25 Y18.93"
SND>64: "G1 X9.36 Y21.46"
  REC<65: "ok"
  REC<66: "ok"
SND>65: "G1 X10.10 Y22.93"
SND>66: "G1 X11.05 Y24.20"
  REC<67: "ok"
  REC<68: "ok"
SND>67: "G1 X12.21 Y25.46"
SND>68: "G1 X13.47 Y26.41"
  REC<69: "ok"
  REC<70: "ok"
SND>69: "G1 X15.26 Y27.15"
SND>70: "G1 X17.27 Y27.68"
  REC<71: "ok"
  REC<72: "ok"
SND>71: "G1 X19.27 Y27.89"
SND>72: "G1 X21.48 Y27.89"
  REC<73: "ok"
  REC<74: "ok"
SND>73: "G1 X23.80 Y27.68"
SND>74: "G1 X25.80 Y27.36"
  REC<75: "ok"
  REC<76: "ok"
SND>75: "G1 X27.49 Y26.62"
SND>76: "G1 X28.75 Y25.67"
  REC<77: "ok"
  REC<78: "ok"
SND>77: "G1 X29.70 Y24.51"
SND>78: "G1 X30.55 Y23.04"
  REC<79: "ok"
  REC<80: "ok"
SND>79: "G1 X31.07 Y21.25"
SND>80: "G1 X31.39 Y19.56"
  REC<81: "ok"
  REC<82: "ok"
SND>81: "G1 X31.39 Y17.35"
SND>82: "G1 X31.18 Y15.34"
  REC<83: "ok"
  REC<84: "ok"
SND>83: "G1 X30.34 Y13.66"
SND>84: "G1 X29.39 Y12.29"
  REC<85: "ok"
  REC<86: "ok"
SND>85: "G1 X28.02 Y11.13"
SND>86: "G1 X26.54 Y10.39"
  REC<87: "ok"
  REC<88: "ok"
SND>87: "G1 X24.85 Y9.65"
SND>88: "G1 X23.17 Y9.12"
  REC<89: "ok"
  REC<90: "ok"
SND>89: "G1 X21.48 Y8.49"
SND>90: "G1 X19.90 Y7.86"
  REC<91: "ok"
  REC<92: "ok"
SND>91: "M8"
SND>92: "M2"
  REC<93: "ok"
  REC<94: "ok"
SND>93: "G0 X0 Y0"

Die beiden Protokols sind aus dem exakt selbem GCode der eine war das erste mal der andere das zweite mal (Beide hatten das "M8" am ende verloren) warum auch immer, kein plan vielleicht hat ja jemand eine idee, Danke schonmal

Was ich noch vergessen hab zu sagen, das ich den Code von GRBL nur ein wenig geändert habe wirklich sehr wenig nähmlich also M7 und M8 ist ja eigentlich für die Kühlung hatte sich aber gut geeignet für mich weil ich ein Getriebe Motor für die (Z-Achse) benutze hierbei mit Z-Achse meine ich Stift Hoch, Stift Runter so das was ich geändert habe ist das einfach nach 100ms der Motor direkt aus geht das heißt normalerweise bleibt bei M7 der motor an im code habe ich aber geändert das nach jedem Kühlungs-Command der Motor direkt nach 100ms wieder ausgeht

/*
  coolant_control.c - coolant control methods
  Part of Grbl

  Copyright (c) 2012-2015 Sungeun K. Jeon

  Grbl is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  Grbl is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with Grbl.  If not, see <http://www.gnu.org/licenses/>.
*/  

#include "grbl.h"
#include <util/delay.h>

void coolant_init()
{
  COOLANT_FLOOD_DDR |= (1 << COOLANT_FLOOD_BIT);
  #ifdef ENABLE_M7
    COOLANT_MIST_DDR |= (1 << COOLANT_MIST_BIT);
  #endif
  coolant_stop();
}


void coolant_stop()
{
  COOLANT_FLOOD_PORT &= ~(1 << COOLANT_FLOOD_BIT);
  #ifdef ENABLE_M7
    COOLANT_MIST_PORT &= ~(1 << COOLANT_MIST_BIT);
  #endif
}


void coolant_set_state(uint8_t mode)
{
  if (mode == COOLANT_FLOOD_ENABLE) {
    COOLANT_FLOOD_PORT |= (1 << COOLANT_FLOOD_BIT);

  #ifdef ENABLE_M7  
    } else if (mode == COOLANT_MIST_ENABLE) {
      COOLANT_MIST_PORT |= (1 << COOLANT_MIST_BIT);
  #endif

  } else {
    coolant_stop();
  }
}


void coolant_run(uint8_t mode)
{
  if (sys.state == STATE_CHECK_MODE) { return; }
  protocol_buffer_synchronize(); // Ensure coolant turns on when specified in the program.

  coolant_set_state(mode);

  // Introduce a delay (adjust the value as needed)
  _delay_ms(100);  // This delays for 500 milliseconds (0.5 seconds)

  coolant_stop();  // Turn off the motor after the delay
}

Aber das funktioniert, da ich das auch schon mit einem ganz normalen GCode Sender getestet habe (LaserGRBL) da funktioniert auch die GCode datei die ich oben angehangen habe

Tatsächlich habe ich die lösung schon gefunden hier das ist ja der code wo es nicht funktioniert hat

#define RX_BUFFER_SIZE 128   // adjust this to your needs
#define MAX_GCODE_LENGTH 128 // adjust this to your needs

int g_count = 0;
int l_count = 0;
int error_count = 0;
bool verbose = true;

int len = 0;
char l_block[MAX_GCODE_LENGTH];

void loop()
{
  webSocket.loop();

  if (!gcodeQueue.empty())
  {
    bool okReceived = false;
    char *l_block = gcodeQueue.front();
    gcodeQueue.pop();
    len = strlen(l_block) + 1;
    while (len >= RX_BUFFER_SIZE - 1 || Serial2.available())
    {
      char out_temp[RX_BUFFER_SIZE];
      Serial2.readBytesUntil('\n', out_temp, RX_BUFFER_SIZE);
      if (strstr(out_temp, "ok") == NULL && strstr(out_temp, "error") == NULL)
      {
        Serial.println("    MSG: \"" + String(out_temp) + "\""); // Debug response
      }
      else
      {
        if (!okReceived && strstr(out_temp, "ok") != NULL)
        {
          okReceived = true;
          g_count += 1;
          len -= strlen(l_block) + 1;
          if (verbose)
            Serial.println("  REC<" + String(g_count) + ": \"" + String(out_temp) + "\"");
        }
        if (strstr(out_temp, "error") != NULL)
          error_count += 1;
      }
    }
    Serial2.println(l_block); // Send g-code block to grbl
    if (verbose)
      Serial.println("SND>" + String(l_count) + ": \"" + String(l_block) + "\"");
    l_count += 1;
    delete[] l_block; // delete the gcode line when done with it
  }

  // Wait until all responses have been received.
  while (l_count > g_count)
  {
    bool okReceived = false;
    char out_temp[RX_BUFFER_SIZE];
    Serial2.readBytesUntil('\n', out_temp, RX_BUFFER_SIZE);
    if (strstr(out_temp, "ok") == NULL && strstr(out_temp, "error") == NULL)
    {
      Serial.println("    MSG: \"" + String(out_temp) + "\""); // Debug response
    }
    else
    {
      if (!okReceived && strstr(out_temp, "ok") != NULL)
      {
        okReceived = true;
        g_count += 1;
        len -= strlen(l_block) + 1;
        if (verbose)
          Serial.println("  REC<" + String(g_count) + ": \"" + String(out_temp) + "\"");
      }
      if (strstr(out_temp, "error") != NULL)
        error_count += 1;
    }
  }
}

Jetzt habe ich gesehen das ich Serial2.readBytesUntil benutze das ist ja sehr schnell jedoch zum senden benutzte ich: Serial2.println das ist nicht besonders schnell also bin ich hingegangen und habe Serial2.write benutzt:

// Append newline character to currentBlock
    char currentBlockWithNewline[strlen(currentBlock) + 2];
    strcpy(currentBlockWithNewline, currentBlock);
    strcat(currentBlockWithNewline, "\n");

    // Convert currentBlockWithNewline to byte array and send it
    Serial2.write((const uint8_t *)currentBlockWithNewline, strlen(currentBlockWithNewline));

das ist viel schneller und jetzt wird auch alles richtig erkannt das problem lag also an println da es einfach zu langsam ist

Allein mir fehlt der Glaube, dass es die Geschwindigkeit war. (evtl. eher das ln)

Gruß Tommy

Naja ist ja egal funktioniert ja jetzt

Wenn Dir das egal ist, ist es für Dich ja ok.

Gruß Tommy

Wenn du schon zufällig hier bist, kennst du dich mit ESP32 LittleFS aus also Speichern von Daten im ESP32?

Ich kenne mich mit dem Speichern von Daten im LittleFS vom ESP8266 aus. ESP32 benutze ich nicht.

Gruß Tommy

Vielleicht kannst du mir ja die Frage beantworten wenn ich meine Dateien auf dem Spiffs hochlade sagt er mir

Auto-detected Flash size: 4MB
Compressed 1507328 bytes to 38644...
Writing at 0x00290000... (33 %)
Writing at 0x00294000... (66 %)
Writing at 0x00298000... (100 %)
Wrote 1507328 bytes (38644 compressed) at 0x00290000 in 6.7 seconds (effective 1796.8 kbit/s)...
Hash of data verified

Ich verstehe also das er 38644 bytes drauf gepackt hat wenn ich jetzt aber die Used bytes nochmal anschaue also direkt danach mit LITTLEFS.usedBytes dann kommt auf einmal 409600 bytes warum auf einmal so viel?

Was ich hierzu sagen muss das dass ganz viele einzelne Dateien sind weil ich mache zurzeit eine Webapp die Text to Gcode macht bedeutet ich brauche alle Buchstaben im Alphabet wie z.B (a.gcode, b.gcode, c.gcode) du verstehst schon... das heißt meine Webapp (der Client) Fetched dann immer diese Buchstaben wenn er sie braucht also benutze ich den ESP32 nur als (Speicherort) für mein GCode Alphabet natürlich ist auf dem ESP32 meine Website gespeichert aber die ist komprimiert mit Gulp, aber das funktioniert Sehr gut.

Ich lade Files immer mit dem Dateimanager von Fips hoch. Da gibt es auch eine Variante für ESP32.

Gruß Tommy

also liegt es am File Upload?

Da ich die andere Variante nie benutzt habe, kann ich das nicht sagen. Aus Erfahrung der Diskettenzeit kann ich aber sagen, dass viele kleine Dateien unter Umständen sehr viel mehr Speicher blockieren, da immer ein Block belegt wird, auch wenn davon nur 1 Byte gebraucht wird.

Gruß Tommy

Genau daran dachte ich auch, was ist eine gute lösung hättest du eine?

Ich weiß nicht, warum Du für jeden Buchstaben eine Datei brauchst. Erkläre das mal.
Ansonsten versuche größere Dateieinheiten zu nutzen.

Gruß Tommy

also sagen wir im "Text to Gcode" program wird "Hallo" eingegeben das heißt der Server fetched sich "/uppercase/h.code", "lowercase/a.gcode", "lowercase/l.gcode"... etc diese tut er dann so zusammen das es aussieht wie "Hallo"

Sind die Codes pro Buchstaben immer gleich lang? Wenn ja/nein wie lang?

Gruß Tommy

so sieht z.B das "a" aus:

G0 X2.89 Y3.34,M7,G1 X2.77 Y3.31,G1 X2.28 Y3.25,G1 X1.77 Y3.23,G1 X1.34 Y3.23,G1 X1.08 Y3.37,G1 X0.91 Y3.68,G1 X0.74 Y4.03,G1 X0.62 Y4.32,G1 X0.54 Y4.83,G1 X0.54 Y5.38,G1 X0.71 Y5.63,G1 X1.02 Y5.78,G1 X1.37 Y5.86,G1 X1.85 Y5.86,G1 X2.11 Y5.69,G1 X2.28 Y5.40,G1 X2.51 Y5.03,G1 X2.66 Y4.66,G1 X2.74 Y4.34,G1 X2.74 Y3.86,G1 X2.74 Y3.40,G1 X2.74 Y3.83,G1 X2.74 Y4.29,G1 X2.74 Y4.69,G1 X2.74 Y5.18,G1 X2.86 Y5.49,G1 X3.14 Y5.69,G1 X3.40 Y5.86,M8

Und nein sie sind nicht gleich lang da z.B das "T" nur zwei striche sind und das "E" wieder rum 3 striche

Aber wie es aussieht, alles druckbare Zeichen.
Meine Lösung wäre eine Datenbank außerhalb des ESP. Hast Du keinen Server mit einer MySQL-Datenbank?

Ansonsten zur Not eine Datei mit einer Zeile pro Buchstaben, aber alle mit der gleichen Länge, wie das längste Zeichen+1, damit man den Anfang errechnen kann.
Das Zeichen wird mit binär 0 abgeschlossen.
Eine Datei für groß und eine für klein.

Gruß Tommy

Verstehe die MY-SQL Datenbank ist denke ich nicht möglich da das ganze Projekt offline sein muss, also wenn ich aber „Hallo“ schreibe dann muss ich aber beide Dateien für Groß und klein Fetchen um Hallo zu „Bauen“ oder?