From 8a2c39869a1c44d41fb6298303e2fa989a707d85 Mon Sep 17 00:00:00 2001 From: Luc Date: Fri, 2 Nov 2018 11:21:56 +0100 Subject: [PATCH] Implement check sum for Serial upload as mandatory for Marlin Add 2 new [ESPXXX] command as check sum helper * Send GCode with check sum caching right line numbering [ESP600] * Send line checksum [ESP601] Implemented only for Sync WebServer at this moment, so Async is disabled in Travis --- .travis.yml | 12 +-- docs/Commands.txt | 6 ++ src/command.cpp | 44 +++++++++ src/config.h | 10 +- src/syncwebserver.cpp | 171 +++++++++++++++++------------------ src/webinterface.cpp | 206 ++++++++++++++++++++++++++++++++++-------- 6 files changed, 310 insertions(+), 139 deletions(-) diff --git a/.travis.yml b/.travis.yml index bc99c384..6de0ee3a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,12 +62,12 @@ script: - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino - arduino --board esp32:esp32:esp32 --save-prefs - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino - - sed -i "s/\/\/#define ASYNCWEBSERVER /#define ASYNCWEBSERVER/g" $HOME/arduino_ide/libraries/ESP3D/src/config.h - - arduino --board esp8266com:esp8266:generic --save-prefs - - arduino --get-pref sketchbook.path - - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino - - arduino --board esp32:esp32:esp32 --save-prefs - - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino +# - sed -i "s/\/\/#define ASYNCWEBSERVER /#define ASYNCWEBSERVER/g" $HOME/arduino_ide/libraries/ESP3D/src/config.h +# - arduino --board esp8266com:esp8266:generic --save-prefs +# - arduino --get-pref sketchbook.path +# - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino +# - arduino --board esp32:esp32:esp32 --save-prefs +# - build_sketch $TRAVIS_BUILD_DIR/examples/basicesp3d/basicesp3d.ino notifications: email: diff --git a/docs/Commands.txt b/docs/Commands.txt index f5c860f2..96c8d4d4 100644 --- a/docs/Commands.txt +++ b/docs/Commands.txt @@ -136,6 +136,12 @@ if authentication is on, need admin password for RESET, RESTART and SAFEMODE [ESP555]pwd= if no password set it use default one +* Send GCode with check sum caching right line numbering +[ESP600] + +* Send line checksum +[ESP601] + * Read SPIFFS file and send each line to serial [ESP700] diff --git a/src/command.cpp b/src/command.cpp index df809a69..64dd0b59 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -49,6 +49,9 @@ String COMMAND::buffer_tcp; #define INCORRECT_CMD_MSG (output == WEB_PIPE)?F("Error: Incorrect Command"):F("Incorrect Cmd") #define OK_CMD_MSG (output == WEB_PIPE)?F("ok"):F("Cmd Ok") +extern uint8_t Checksum(const char * line, uint16_t lineSize); +extern bool sendLine2Serial (String & line, int32_t linenb, int32_t* newlinenb); + String COMMAND::get_param (String & cmd_params, const char * id, bool withspace) { static String parameter; @@ -1403,6 +1406,47 @@ bool COMMAND::execute_command (int cmd, String cmd_params, tpipe output, level_a break; } #endif + //[ESP600] + case 600: { //send GCode with check sum caching right line numbering + //be sure serial is locked + if ( (web_interface->blockserial) ) { + break; + } + int32_t linenb = 1; + cmd_params.trim() ; + if (sendLine2Serial (cmd_params, linenb, &linenb))ESPCOM::println (OK_CMD_MSG, output, espresponse); + else { //it may failed because of skip if repetier so let's reset numbering first + if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) { + //reset numbering + String cmd = "M110 N0"; + if (sendLine2Serial (cmd, -1, NULL)){ + linenb = 1; + //if success let's try again to send the command + if (sendLine2Serial (cmd_params, linenb, &linenb))ESPCOM::println (OK_CMD_MSG, output, espresponse); + else { + ESPCOM::println (ERROR_CMD_MSG, output, espresponse); + response = false; + } + } else { + ESPCOM::println (ERROR_CMD_MSG, output, espresponse); + response = false; + } + } else { + + ESPCOM::println (ERROR_CMD_MSG, output, espresponse); + response = false; + } + } + } + break; + //[ESP601] + case 601: { //send line checksum + cmd_params.trim(); + int8_t chk = Checksum(cmd_params.c_str(),cmd_params.length()); + String schecksum = "Checksum: " + String(chk); + ESPCOM::println (schecksum, output, espresponse); + } + break; //[ESP700] case 700: { //read local file //be sure serial is locked diff --git a/src/config.h b/src/config.h index af57dc4b..b78b9a4b 100644 --- a/src/config.h +++ b/src/config.h @@ -19,7 +19,7 @@ */ //version and sources location -#define FW_VERSION "2.0.0.c20" +#define FW_VERSION "2.0.0.c21" #define REPOSITORY "https://github.com/luc-github/ESP3D" //Customize ESP3D //////////////////////////////////////////////////////////////////////// @@ -71,10 +71,10 @@ #define DIRECT_PIN_FEATURE //ESP_OLED_FEATURE: allow oled screen output -#define ESP_OLED_FEATURE +//#define ESP_OLED_FEATURE //DHT_FEATURE: send update of temperature / humidity based on DHT 11/22 -#define DHT_FEATURE +//#define DHT_FEATURE //AUTHENTICATION_FEATURE: protect pages by login password //#define AUTHENTICATION_FEATURE @@ -83,7 +83,7 @@ #define WS_DATA_FEATURE //TIMESTAMP_FEATURE: Time stamp feature on direct SD files -#define TIMESTAMP_FEATURE +//#define TIMESTAMP_FEATURE //Extra features ///////////////////////////////////////////////////////////////////////// @@ -216,7 +216,7 @@ using fs::File; #endif #ifdef DEBUG_OUTPUT_TCP #include "espcom.h" -#define LOG(string) {ESPCOM::send2TCP(string, true);} +#define LOG(string) {ESPCOM::send2TCP(string, false);} #define DEBUG_PIPE TCP_PIPE #endif #else diff --git a/src/syncwebserver.cpp b/src/syncwebserver.cpp index ae38d8a0..7c5cfb57 100644 --- a/src/syncwebserver.cpp +++ b/src/syncwebserver.cpp @@ -101,9 +101,9 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length extern bool deleteRecursive(String path); -extern void CloseSerialUpload (bool iserror, String & filename); -extern bool sendLine2Serial (String & line); - +extern void CloseSerialUpload (bool iserror, String & filename, int32_t linenb); +extern bool sendLine2Serial (String & line, int32_t linenb, int32_t* newlinenb); +extern bool purge_serial(); const uint8_t PAGE_404 [] PROGMEM = "\n\nRedirecting... \n\n\n
Unknown page : $QUERY$- you will be redirected...\n

\nif not redirected, click here\n

\n\n\n\n
\n\n\n\n"; const uint8_t PAGE_CAPTIVE [] PROGMEM = "\n\nCaptive Portal \n\n\n
Captive Portal page : $QUERY$- you will be redirected...\n

\nif not redirected, click here\n

\n\n\n\n
\n\n\n\n"; @@ -559,7 +559,6 @@ void SPIFFSFileupload() if(upload.status == UPLOAD_FILE_START) { String upload_filename = upload.filename; String sizeargname = upload_filename + "S"; - if (web_interface->web_server.hasArg ("plain") ) Serial.println("Yes"); if (upload_filename[0] != '/') filename = "/" + upload_filename; else filename = upload.filename; //according User or Admin the root is different as user is isolate to /user when admin has full access @@ -1152,6 +1151,7 @@ void handle_serial_SDFileList() //SD file upload by serial void SDFile_serial_upload() { + static int32_t lineNb =-1; static String current_line; static bool is_comment = false; static String current_filename; @@ -1174,93 +1174,70 @@ void SDFile_serial_upload() //Upload start //************** if(upload.status == UPLOAD_FILE_START) { + LOG("Upload Start\r\n") + String command = "M29"; + String resetcmd = "M110 N0"; + if (CONFIG::GetFirmwareTarget() == SMOOTHIEWARE)resetcmd = "N0 M110"; + lineNb=1; + //close any ongoing upload and get current line number + if(!sendLine2Serial (command,1, &lineNb)){ + //it can failed for repetier + if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) { + if(!sendLine2Serial (command,-1, NULL)){ + LOG("Start Upload failed") + web_interface->_upload_status= UPLOAD_STATUS_FAILED; + return; + } + } else { + LOG("Start Upload failed") + web_interface->_upload_status= UPLOAD_STATUS_FAILED; + return; + } + } + //Reset line numbering + if(!sendLine2Serial (resetcmd,-1, NULL)){ + LOG("Reset Numbering failed") + web_interface->_upload_status= UPLOAD_STATUS_FAILED; + return; + } + lineNb=1; //need to lock serial out to avoid garbage in file (web_interface->blockserial) = true; current_line =""; - is_comment = false; - String response; - web_interface->_upload_status= UPLOAD_STATUS_ONGOING; - ESPCOM::println (F ("Uploading..."), PRINTER_PIPE); - ESPCOM::flush (DEFAULT_PRINTER_PIPE); - LOG("Clear Serial\r\n"); - if(ESPCOM::available(DEFAULT_PRINTER_PIPE)) { - ESPCOM::bridge(); - CONFIG::wait(1); - } - //command to pritnter to start print - String command = "M28 " + upload.filename; - LOG(command); - LOG("\r\n"); - ESPCOM::println (command, DEFAULT_PRINTER_PIPE); - ESPCOM::flush (DEFAULT_PRINTER_PIPE); current_filename = upload.filename; - CONFIG::wait (500); - uint32_t timeout = millis(); - bool done = false; - while (!done) { //time out is 2000ms - CONFIG::wait(0); - //if there is something in serial buffer - size_t len = ESPCOM::available(DEFAULT_PRINTER_PIPE); - //get size of buffer - if (len > 0) { - CONFIG::wait(0); - uint8_t * sbuf = (uint8_t *)malloc(len+1); - if(!sbuf){ - ESPCOM::println (F ("SD upload rejected"), PRINTER_PIPE); - LOG("SD upload rejected\r\n"); - LOG("Need to stop"); -#if defined ( ARDUINO_ARCH_ESP8266) - web_interface->web_server.client().stopAll(); -#else - web_interface->web_server.client().stop(); -#endif - return ; - } - //read buffer - ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, sbuf, len); - //convert buffer to zero end array - sbuf[len] = '\0'; - //use string because easier to handle - response = (const char*) sbuf; - LOG (response); - //if there is a wait it means purge is done - if (response.indexOf ("wait") > -1) { - LOG ("Exit start writing\r\n"); - done = true; - free(sbuf); - break; - } - //it is first command if it is failed no need to continue - //and resend command won't help - if (response.indexOf ("Resend") > -1 || response.indexOf ("failed") > -1) { - web_interface->blockserial = false; - LOG ("Error start writing\r\n"); - web_interface->_upload_status = UPLOAD_STATUS_FAILED; -#if defined ( ARDUINO_ARCH_ESP8266) - web_interface->web_server.client().stopAll(); -#else - web_interface->web_server.client().stop(); -#endif - free(sbuf); - return; - } - free(sbuf); - } - if ( (millis() - timeout) > SERIAL_CHECK_TIMEOUT) { - done = true; - } + is_comment = false; + String response; + ESPCOM::println (F ("Uploading..."), PRINTER_PIPE); + //Clear all serial + ESPCOM::flush (DEFAULT_PRINTER_PIPE); + purge_serial(); + //besure nothing left again + purge_serial(); + command = "M28 " + upload.filename; + //send start upload + //no correction allowed because it means reset numbering was failed + if (sendLine2Serial(command, lineNb, NULL)){ + CONFIG::wait(1200); + //additional purge, in case it is slow to answer + purge_serial(); + web_interface->_upload_status= UPLOAD_STATUS_ONGOING; + LOG("Creation Ok\r\n") + + } else { + web_interface->_upload_status= UPLOAD_STATUS_FAILED; + LOG("Creation failed\r\n"); } //Upload write //************** //upload is on going with data coming by 2K blocks } else if(upload.status == UPLOAD_FILE_WRITE) { //if com error no need to send more data to serial - web_interface->_upload_status= UPLOAD_STATUS_ONGOING; + if (web_interface->_upload_status == UPLOAD_STATUS_ONGOING) { for (int pos = 0; pos < upload.currentSize; pos++) { //parse full post data //feed watchdog CONFIG::wait(0); //it is a comment if (upload.buf[pos] == ';') { - LOG ("Comment\n") + LOG ("Comment\r\n") is_comment = true; } //it is an end line @@ -1271,10 +1248,11 @@ void SDFile_serial_upload() if (current_line.length() < 126) { //do we have something in buffer ? if (current_line.length() > 0 ) { - current_line += "\r\n"; - if (!sendLine2Serial (current_line) ) { + lineNb++; + if (!sendLine2Serial (current_line, lineNb, NULL) ) { + //fup.println("[Log]Write Error"); LOG ("Error over buffer\n") - CloseSerialUpload (true, current_filename); + CloseSerialUpload (true, current_filename,lineNb); #if defined ( ARDUINO_ARCH_ESP8266) web_interface->web_server.client().stopAll(); #else @@ -1291,7 +1269,8 @@ void SDFile_serial_upload() } else { //error buffer overload LOG ("Error over buffer\n") - CloseSerialUpload (true, current_filename); + lineNb++; + CloseSerialUpload (true, current_filename, lineNb); #if defined ( ARDUINO_ARCH_ESP8266) web_interface->web_server.client().stopAll(); #else @@ -1304,7 +1283,8 @@ void SDFile_serial_upload() current_line += char (upload.buf[pos]); //copy current char to buffer to send/resend } else { LOG ("Error over buffer\n") - CloseSerialUpload (true, current_filename); + lineNb++; + CloseSerialUpload (true, current_filename, lineNb); #if defined ( ARDUINO_ARCH_ESP8266) web_interface->web_server.client().stopAll(); #else @@ -1314,15 +1294,28 @@ void SDFile_serial_upload() } } } + } else { + LOG ("Error upload\n") + web_interface->_upload_status = UPLOAD_STATUS_FAILED; + lineNb++; + CloseSerialUpload (true, current_filename, lineNb); +#if defined ( ARDUINO_ARCH_ESP8266) + web_interface->web_server.client().stopAll(); +#else + web_interface->web_server.client().stop(); +#endif + return; + } //Upload end //************** - } else if(upload.status == UPLOAD_FILE_END) { + } else if(upload.status == UPLOAD_FILE_END && web_interface->_upload_status == UPLOAD_STATUS_ONGOING) { //if last part does not have '\n' if (current_line.length() > 0) { - current_line += "\r\n"; - if (!sendLine2Serial (current_line) ) { + lineNb++; + if (!sendLine2Serial (current_line, lineNb, NULL) ) { LOG ("Error sending buffer\n") - CloseSerialUpload (true, current_filename); + lineNb++; + CloseSerialUpload (true, current_filename, lineNb); #if defined ( ARDUINO_ARCH_ESP8266) web_interface->web_server.client().stopAll(); #else @@ -1332,12 +1325,14 @@ void SDFile_serial_upload() } } LOG ("Upload finished "); - CloseSerialUpload (false, current_filename); + lineNb++; + CloseSerialUpload (false, current_filename, lineNb); //Upload cancelled //************** } else { //UPLOAD_FILE_ABORTED LOG("Error, Something happened\r\n"); - CloseSerialUpload (true, current_filename); + lineNb++; + CloseSerialUpload (true, current_filename, lineNb); #if defined ( ARDUINO_ARCH_ESP8266) web_interface->web_server.client().stopAll(); #else diff --git a/src/webinterface.cpp b/src/webinterface.cpp index 0e54177e..3ce07169 100644 --- a/src/webinterface.cpp +++ b/src/webinterface.cpp @@ -73,78 +73,203 @@ long id_connection = 0; +uint8_t Checksum(const char * line, uint16_t lineSize) +{ + uint8_t checksum_val =0; + for (uint16_t i=0; i < lineSize; i++) checksum_val = checksum_val ^ ((uint8_t)line[i]); + return checksum_val; +} +String CheckSumLine(const char* line, uint32_t linenb){ + String linechecksum = "N" + String(linenb)+ " " + line; + uint8_t crc = Checksum(linechecksum.c_str(), linechecksum.length()); + linechecksum+="*"+String(crc); + return linechecksum; +} + +bool purge_serial(){ + uint32_t start = millis(); + uint8_t buf [51]; + ESPCOM::flush (DEFAULT_PRINTER_PIPE); + CONFIG::wait (5); + LOG("Purge Serial\r\n") + while (ESPCOM::available(DEFAULT_PRINTER_PIPE) > 0 ){ + if ((millis() - start ) > 2000) { + LOG("Purge timeout\r\n") + return false; + } + size_t len = ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, buf, 50); + buf[len] = '\0'; + LOG("Purge ") + LOG((const char *)buf) + LOG("\r\n") + if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) { + String s = (const char *)buf; + //repetier never stop sending data so no need to wait if have 'wait' or 'busy' + if((s.indexOf ("wait") > -1) || (s.indexOf ("busy") > -1))return true; + LOG("Purge interrupted\r\n") + } + CONFIG::wait (5); + } + CONFIG::wait (0); + LOG("Purge done\r\n") + return true; +} + +size_t wait_for_data(uint32_t timeout){ + uint32_t start = millis(); + while ((ESPCOM::available(DEFAULT_PRINTER_PIPE) < 2) && ((millis()-start) < timeout))CONFIG::wait (10); + return ESPCOM::available(DEFAULT_PRINTER_PIPE); +} + +uint32_t Get_lineNumber(String & response){ + int32_t l = 0; + String sresend = "Resend:"; + if ( CONFIG::GetFirmwareTarget() == SMOOTHIEWARE){ + sresend = "rs N"; + } + int pos = response.indexOf(sresend); + if (pos == -1 ) { + return -1; + } + pos+=sresend.length(); + int pos2 = response.indexOf("\n", pos); + String snum = response.substring(pos, pos2); + //remove potential unwished char + snum.replace("\r", ""); + l = snum.toInt(); + LOG("New number ") + LOG(String(l)) + LOG("\r\n") + return l; +} //function to send line to serial/////////////////////////////////////// -bool sendLine2Serial (String & line) +//if newlinenb is NULL no auto correction of line number in case of resend +bool sendLine2Serial (String & line, int32_t linenb, int32_t * newlinenb) { - LOG (line) - ESPCOM::println (line, DEFAULT_PRINTER_PIPE); + LOG ("Send line ") + LOG (line ) + LOG (" NB:") + LOG (String(linenb)) + LOG ("\r\n") + String line2send; + String sok = "ok"; + String sresend = "Resend"; + if (newlinenb) *newlinenb = linenb; + if ( CONFIG::GetFirmwareTarget() == SMOOTHIEWARE)sresend = "rs N"; + if (linenb != -1) { + if ( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) sok+=" " + String(linenb); + line2send = CheckSumLine(line.c_str(),linenb); + } else line2send = line; + //purge serial as nothing is supposed to interfere with upload + purge_serial(); + LOG ("Send line ") + LOG (line2send ) + LOG ("\r\n") + //send line + ESPCOM::println (line2send, DEFAULT_PRINTER_PIPE); ESPCOM::flush(DEFAULT_PRINTER_PIPE); -#ifdef ARDUINO_ARCH_ESP8266 - CONFIG::wait (5); -#else - CONFIG::wait (2); -#endif - if (ESPCOM::available(DEFAULT_PRINTER_PIPE) > 0 ) { + //check answer + if (wait_for_data(2000) > 0 ) { bool done = false; uint32_t timeout = millis(); uint8_t count = 0; + //got data check content + String response ; while (!done) { - CONFIG::wdtFeed(); size_t len = ESPCOM::available(DEFAULT_PRINTER_PIPE); //get size of buffer if (len > 0) { uint8_t * sbuf = (uint8_t *)malloc(len+1); - if(!sbuf){ - return false; - } + if(!sbuf){ + return false; + } //read buffer ESPCOM::readBytes (DEFAULT_PRINTER_PIPE, sbuf, len); //convert buffer to zero end array sbuf[len] = '\0'; - //use string because easier to handle - String response = (const char*) sbuf; - if ( (response.indexOf ("ok") > -1) || (response.indexOf ("wait") > -1) ) { - free(sbuf); - return true; + //use string because easier to handle and allow to re-assemble cutted answer + response += (const char*) sbuf; + LOG ("Response: ") + LOG (response) + LOG ("\r\n") + //in that case there is no way to know what is the right number to use and so send should be failed + if (( ( CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) && (response.indexOf ("skip") != -1)) { + LOG ("Wrong line requested\r\n") + count = 5; } - if (response.indexOf ("Resend") > -1) { + //it is resend ? + int pos = response.indexOf (sresend); + //be sure we get full line to be able to process properly + if (( pos > -1) && (response.lastIndexOf("\n") > pos)){ + LOG ("Resend detected\r\n") + uint32_t line_number = Get_lineNumber(response); + if (newlinenb){ + *newlinenb = line_number; + free(sbuf); + return sendLine2Serial (line, line_number, newlinenb); + } else { + //the line requested is not the current one so we stop + if (line_number !=linenb) { + LOG ("Wrong line requested\r\n") + count = 5; + } + } count++; if (count > 5) { - free(sbuf); + free(sbuf); + LOG ("Exit too many resend or wrong line\r\n") return false; } - LOG ("resend\r\n") - ESPCOM::println (line, DEFAULT_PRINTER_PIPE); + LOG ("Resend\r\n") + purge_serial(); + ESPCOM::println (line2send, DEFAULT_PRINTER_PIPE); ESPCOM::flush (DEFAULT_PRINTER_PIPE); - CONFIG::wait (5); + wait_for_data(1000); timeout = millis(); + + } else { + if ( (response.indexOf (sok) > -1) ) { //we have ok so it is done + free(sbuf); + LOG ("Got ok\r\n") + purge_serial(); + return true; + } } free(sbuf); } - //no answer so exit: no news = good news - if ( millis() - timeout > 500) { + //no answer or over buffer exit + if ( (millis() - timeout > 2000) || (response.length() >200)){ + LOG ("Time out\r\n") done = true; } + CONFIG::wait (50); + } + } + LOG ("Send line error\r\n") + return false; +} + + + +//send M29 / M30 command to close file on SD//////////////////////////// +void CloseSerialUpload (bool iserror, String & filename , int32_t linenb) +{ + purge_serial(); + String command = "M29"; + purge_serial(); + if (!sendLine2Serial (command,linenb, &linenb)) { + wait_for_data(2000); + if (!sendLine2Serial (command,linenb, &linenb)) { + if ((CONFIG::GetFirmwareTarget() == REPETIER4DV) || (CONFIG::GetFirmwareTarget() == REPETIER) ) { + sendLine2Serial (command,-1, NULL); + } } } - return true; -} - -//send M29 / M30 command to close file on SD//////////////////////////// - -void CloseSerialUpload (bool iserror, String & filename) -{ - - ESPCOM::println ("\r\nM29", DEFAULT_PRINTER_PIPE); - ESPCOM::flush (DEFAULT_PRINTER_PIPE); - CONFIG::wait (1000); - ESPCOM::println ("\r\nM29", DEFAULT_PRINTER_PIPE); - ESPCOM::flush (DEFAULT_PRINTER_PIPE); if (iserror) { String cmdfilename = "M30 " + filename; - ESPCOM::println (cmdfilename, DEFAULT_PRINTER_PIPE); + sendLine2Serial (cmdfilename,-1, NULL); ESPCOM::println (F ("SD upload failed"), PRINTER_PIPE); ESPCOM::flush (DEFAULT_PRINTER_PIPE); web_interface->_upload_status = UPLOAD_STATUS_FAILED; @@ -154,7 +279,8 @@ void CloseSerialUpload (bool iserror, String & filename) web_interface->_upload_status = UPLOAD_STATUS_SUCCESSFUL; } //lets give time to FW to proceed - CONFIG::wait (1000); + wait_for_data(2000); + purge_serial(); web_interface->blockserial = false; }