Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Strange bug with a pause (irregular) #858

Closed
Goodfeat opened this issue Apr 8, 2019 · 10 comments
Closed

Strange bug with a pause (irregular) #858

Goodfeat opened this issue Apr 8, 2019 · 10 comments

Comments

@Goodfeat
Copy link

Goodfeat commented Apr 8, 2019

Hello, I found a firmware bug, it appears when pausing the printer while printing from SD

It is very difficult to catch, but because of it you can kill many hours printing

The point is this: when I try to pause the printer at a certain moment, the extruder parks,
But however starts to behave inadequately and begins to return to the starting position of the last command.
In this case the extruder starts to rotate strongly.
I could not fix it, but I found the following:
When I tried to catch the bug, I decided to duplicate the line "Commands :: waitUntilEndOfAllBuffers ();"

//--------SDCard.cpp-------String 163-----------------
void SDCard::pausePrint(bool intern) {
if (!sdactive)
return;
sdmode = 2; // finish running line
Printer::setMenuMode(MENU_MODE_PAUSED, true);
#if !defined(DISABLE_PRINTMODE_ON_PAUSE) || DISABLE_PRINTMODE_ON_PAUSE == 1
Printer::setPrinting(false);
#endif
#if NEW_COMMUNICATION
GCodeSource::removeSource(&sdSource);
#endif
if (EVENT_SD_PAUSE_START(intern)) {
if (intern) {
Commands::waitUntilEndOfAllBuffers(); //---------------------------------- wait until the buffer clears
// sdmode = 0; // why ?
Printer::MemoryPosition();
Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE,
IGNORE_COORDINATE,
Printer::memoryE - RETRACT_ON_PAUSE,
Printer::maxFeedrate[E_AXIS] / 2);
Printer::moveToParkPosition();
Commands::waitUntilEndOfAllBuffers(); //<---------------------------------------- (Buf: 3) ????, why are there still commands in the buffer at this point
Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS];
Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS];
Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS];
GCode::executeFString(PSTR(PAUSE_START_COMMANDS));
}
}
EVENT_SD_PAUSE_END(intern);
}
//--end Code-------------------------------

The added line in the normal mode does not interfere with printing to pause, however, in case of an emergency, the firmware “sticks” and it cannot finish pausing.
After a certain time interval the display of the printer returns to the main screen. The screen shows that the buffer is not empty (Buf: 3).
Consequently, several commands remain in the buffer and interfere with the normal pause.

Printer delta, firmware 1.04 dev

@Nibbels
Copy link

Nibbels commented Apr 14, 2019

This might absolutly not be related to your problem but on my side SD-Printing is buggy rightnow.
And to be straight: My guess is that my problem might be connected with the new SD-Lib.

I maintain some very old repetier fork for some special brand printer using repetier firmware and ATMEGA2560.
And I update all the stuff I like from the original repetier into my printers firmware. So it might be my fault, but only when some prints from SD-Card I get problem reports.

What bug?
Sometimes within the print random axis like X or Y do some sort of homing sporadically. The homing has the speed of the last move and I might be guessing that a cut gcode might produce such an result. "G1 X234 Y|" The time of the bug seems random but some rumors are there that the bug happens more often if temperatures change or people use the menu. Nothing confirmed.
-> This does not happen when people print from USB.

My first try was to check the code all the way down from gcode to move_cache. Then I made an output of all variables order to see if arrays are in close vincinity of the movecache or coordinate variables.
https://github.com/Nibbels/Repetier-Firmware/blob/community_development/Repetier/overflow_decompile.txt
But I guess that was always ok. Then others told me they printed from SD when it happened and I found noone who printed from USB when it happend. I always print from USB and did not know this problem.
Thatwhy I adopted NEW_COMMUNICATION but the behaviour was still the same. So the lib was all that was left to check.
So I checked the config for options and found
Nibbels@ec34e2b#diff-492b507f4b8402886ae4c4ea4aaa2028L195
#define USE_MULTI_BLOCK_IO 0
In order to try to save ram. But It didnt help.

Rightnow I disabled SD-Support by default.

I would need more time to try to reproduce the bug. I know that I would need drymode tests, gcodes echoing, probably a simple test with the old sd-lib ...
Rightnow it is the free time that prevents me from more research.

Sadly no solution from me, but I wanted to share my experience after reading your problem. I liked that someone else debugged into kind of the same code. Maybe it is connected in the end.
What is your type of processor? DUE? ATMEGA2560?

Greetings

@Goodfeat
Copy link
Author

Hello, I understood why it arises: I am sure that this is due to the kinematics of the delta. it occurs if you interrupt printing between processing lines with long distances.

In fact, I solved the problem: I had to rewrite a little pause logic, as well as the extruder behavior logic during a pause. I added a couple of new features to Printer.cpp for an extruder and modified part of the SDCard.cpp code. The pause is now processed after the cache is empty to zero. At least it works fine on my printer.

P.S. I found some more bugs in the firmware. They are associated with printing through a card.I fixed them and are testing now. Also added a couple of its functionality.

Printer delta, arduino due + ruramps4d, dev 1.0.4 (downloaded from github)

@repetier
Copy link
Owner

Sorry, but I do not understand what you mean with "interrupting between lines with long distances".
User actions are handled in main thread so they do not interfere with prints from buffer. So how can that interfere during pause.

Did you check in eeprom if the new park position was defined with good values. If you have nan there it might be a move that never ends or is very slow... Especially since you said the wait never returns and buffer is 3.

@Goodfeat
Copy link
Author

I mean the G code commands that go in series. If you put a pause while the next command is processed and there is a big waiting time (> 1 sec) between the commands, a failure occurs.
I can attach the files showing how I fixed it, but I suppose it is only a temporary solution.

@repetier
Copy link
Owner

You mean if you are called inside a waiting queue to get a place where lcd commands gets added in between I guess. Then the commands get inserted and then the next move will be inserted. Need to check but that would in deed a bad position. So maybe your solution might be a good point to see what worked and see if that is good or if there is a better alternative. In any case it is not trivial I guess. Maybe with sd commands we should only execute a command if buffer has at least one position free. Still leaves homing for example which is also bad to interrupt.

@Goodfeat
Copy link
Author

that's how i fixed it

SDCard.cpp

void SDCard::pausePrint(bool intern) {
  if (!sdactive)
    return;
    
  sdmode = 2; // finish running line
  Printer::setMenuMode(MENU_MODE_PAUSED, true);
#if !defined(DISABLE_PRINTMODE_ON_PAUSE) || DISABLE_PRINTMODE_ON_PAUSE == 1
  Printer::setPrinting(false);
#endif
#if NEW_COMMUNICATION
  GCodeSource::removeSource(&sdSource);
#endif
/*
  if (EVENT_SD_PAUSE_START(intern)) {
    if (intern) {
     // Commands::waitUntilEndOfAllBuffers();
      //Commands::waitUntilEndOfAllMoves();

      // sdmode = 0; // why ?
      Printer::MemoryPosition();
      Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE,
                          IGNORE_COORDINATE,
                          Printer::memoryE - RETRACT_ON_PAUSE,
                          Printer::maxFeedrate[E_AXIS] / 2);
      Printer::moveToParkPosition();
     // if(code != NULL){
      ///Commands::waitUntilEndOfAllBuffers();
      //}
      Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS];
      Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS];
      Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS];
      GCode::executeFString(PSTR(PAUSE_START_COMMANDS));
    }
  }
  */
  EVENT_SD_PAUSE_END(intern);
  BEEP_LONG;
}
//------------------------- Mod pause ----------------------
//Now the pause is made only after clearing the cache to zero.
void SDCard::PausePrintAfter(bool intern) {
   if (EVENT_SD_PAUSE_START(intern)) {
    if (intern) {
      Commands::waitUntilEndOfAllBuffers();
      Printer::MemoryPositionR();
      //Printer::moveToReal(IGNORE_COORDINATE, IGNORE_COORDINATE,
       //                   IGNORE_COORDINATE,
       //                   Printer::memoryE - RETRACT_ON_PAUSE,
        //                  Printer::maxFeedrate[E_AXIS] / 2);
      Printer::moveToParkPosition();
      Printer::lastCmdPos[X_AXIS] = Printer::currentPosition[X_AXIS];
      Printer::lastCmdPos[Y_AXIS] = Printer::currentPosition[Y_AXIS];
      Printer::lastCmdPos[Z_AXIS] = Printer::currentPosition[Z_AXIS];
      GCode::executeFString(PSTR(PAUSE_START_COMMANDS));
    }
  }
}
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void SDCard::continuePrint(bool intern) {
  if (!sd.sdactive)
    return;
  if (EVENT_SD_CONTINUE_START(intern)) {
    if (intern) {
      GCode::executeFString(PSTR(PAUSE_END_COMMANDS));
      Printer::GoToMemoryPosition(true, true, false, false,
                                  Printer::maxFeedrate[X_AXIS]);
      Printer::GoToMemoryPosition(false, false, true, false,
                                  Printer::maxFeedrate[Z_AXIS] / 2.0f);
      Printer::GoToMemoryPositionR(false, false, false, true,
                                  Printer::maxFeedrate[E_AXIS] / 2.0f);
    }
  }
  EVENT_SD_CONTINUE_END(intern);
#if NEW_COMMUNICATION
  GCodeSource::registerSource(&sdSource);
#endif
  Printer::setPrinting(true);
  Printer::setMenuMode(MENU_MODE_PAUSED, false);
  sdmode = 1;
}

in Command.cpp

void Commands::commandLoop() {
  //---------------------- Mod command pause
  if(PrintLine::linesCount<1 && sd.sdmode == 2){
  sd.PausePrintAfter(true);
  BEEP_LONG;
  sd.sdmode = 3;
  }
  //-------------------------------------------

thus, the pause is performed only after the buffer is cleared.

@repetier
Copy link
Owner

Looks in deed a bit like a solution similar to what I understood. Difference is that you just wait for the moves to finish to run the pause. I think that is a better solution that what I had in mind. You cut the source for new commands and simply wait for them to finish before running the pause script. I think that is a elegant solution to the problem that I will copy. Thanks for it.

@Goodfeat
Copy link
Author

Goodfeat commented Apr 15, 2019

I found some more bugs. I can share a few more fixes

@repetier
Copy link
Owner

Any fix is welcome:-)

@Goodfeat
Copy link
Author

I will send it to you via my work email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants