Closed Witgang closed 6 years ago
marlin_main.cpp
#if HAS_KILL
// Check if the kill button was pressed and wait just in case it was an accidental
// key kill key press
// -------------------------------------------------------------------------------
static int killCount = 0; // make the inactivity button a bit less responsive
const int KILL_DELAY = 750;
if (!READ(KILL_PIN))
killCount++;
else if (killCount > 0)
killCount--;
// Exceeded threshold and we can confirm that it was not accidental
// KILL the machine
// ----------------------------------------------------------------
if (killCount >= KILL_DELAY) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
kill(PSTR(MSG_KILLED));
}
/* KILL KEY= RESET */
if (!READ(KILL_PIN))
{
wdt_enable(WDTO_60MS);
while(1) {}
}
/*********************************************/**
#endif
I think what @Witgang is getting at is the kill pin doesn't actually reset the Arduino. It basically causes Marlin to shut everything down and then go into an infinite loop.
It may be possible to reset the Arduino via reset command, but it'd take some research. An alternate approach is to simply disconnect and reconnect the host software that's being used to control the printer. This should cause the Arduino to reset. Here's some info on the Auruino auto reset, if you're interested:
http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection
yes you are right @tcm0116 , i don't know exactly why the kill pin behaves like that instead of a reset. it's probably an unfinished feature and this works as a placeholder until they have time to revise it and make it work as a reset button. or if some desire it's current function too maybe make it so you have to press it another time after it goes into the loop
after some research the code @cjsoong provided should work the same way although i do pray that after reset the wdt is not enabled. i'll put that in and see how it goes for a while. thank you for help!
If you use Octoprint, you can use the ACTION_ON_KILL feature to send action to OP then have OP perform the operation via plugin @benlye wrote: https://plugins.octoprint.org/plugins/actioncommands/
-=dave
i had the time to implement and test the code provided by @cjsoong and it seems to work ok, as soon as i press the kill button it will reset which is what i wanted , don't think i will need to mess up with the timings to trigger that since it's a really small button i have on my case and quite hard to trigger accidentally . so thank you @cjsoong for your help on this:)
I tried the code and it did not work 🤷‍♂️ - I wonder if it may be due to me being on AT90USB ?
I think this is something a lot of others may also want. Maybe submit a PR once you have it nailed down ?
@fiveangle it may have something to do with the watchdog using internal clock timer on your chip, i really have no clue quite new into this thing myself:)
@fiveangle If your watchdog can not work, try this code to force jump to the beginning of the program.
marlin_main.cpp
#if HAS_KILL
// Check if the kill button was pressed and wait just in case it was an accidental
// key kill key press
// -------------------------------------------------------------------------------
static int killCount = 0; // make the inactivity button a bit less responsive
const int KILL_DELAY = 750;
if (!READ(KILL_PIN))
killCount++;
else if (killCount > 0)
killCount--;
// Exceeded threshold and we can confirm that it was not accidental
// KILL the machine
// ----------------------------------------------------------------
if (killCount >= KILL_DELAY) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
kill(PSTR(MSG_KILLED));
}
/* KILL KEY= RESET */
if (!READ(KILL_PIN))
{
//wdt_enable(WDTO_60MS);
asm volatile (" jmp 0"); //RESET
while(1) {}
}
/******************************************/
#endif
Hello, I'd like to try this, but I don't know where to put that piece of code into marlin_main.cpp. Sorry, but I'm rather new to C.
@luwi66
You need to install arduino ide
https://www.arduino.cc/en/Main/Donate
@cjsoong That's not my question. I use arduino ide and have flashed Marlin several times. No, what i'd like to know is where to insert your code into the marlin.cpp code. After which line of code?
@luwi66 code file is "marlin_main.cpp". You can search for "#if HAS_KILL" related words. Add this code (#line 14085)
/ * KILL KEY = RESET /
if (! READ (KILL_PIN))
{
// wdt_enable (WDTO_60MS);
asm volatile ("jmp 0"); // RESET
while (1) {}
}
/ ****************************************** /
OK, got it. Sorry for not understanding at once. I uploaded it to my arduino; the effect is, that now the Kill Button does not cause a Kill anymore. But it also does not reset the arduino. When pressing the button, nothing happens.
@luwi66 I'm sorry .. my mistake There is one less "" / KILL KEY = RESET / -----> / KILL KEY = RESET /
I already did this decommenting; but tried again. Same result: The Kill/Reset button now has no effect at all.
A similar method to make the KILL_PIN
cause a reset. First restore your KILL_PIN
value and make these changes to Marlin_main.cpp
.
Add this line just before the manage_inactivity
function. This is just a different way to do what is described above.
void(* resetFunc) (void) = 0; // Declare reset function as address 0
Then in manage_inactivity
find these lines and make the indicated change:
if (killCount >= KILL_DELAY) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
- kill(PSTR(MSG_KILLED));
+ resetFunc();
}
This should turn your KILL_PIN
into a reset button.
Sorry, doesn't work. Kill button now again causes Kill - not a reset.
Hmm, well I've got nothing then. Anyone else in the gallery have some ideas?
Well, the solution is somewhere in the code. I have a Tevo Tarantula printer and got Marlin (bugfix version 1.1.8) from the Marlin EasyConfig-1.1x branch. The Tevo has a MKS Base 1.5 motherboard and a 2004 LCD Display. This display has a reset button - and it works as reset.
How about not connecting the button to an io-pin, but to the reset line?
Well, I simply wanted a solderless solution, as this works with Marlin at the Tevo display. An easy solution would be to solder another button in parallel to the reset button on the Ramps board. And place this button near the display so that I have a kill button and a reset button there.
If you don't mind waiting 4 seconds this should do it with USE_WATCHDOG
turned on:
if (killCount >= KILL_DELAY) {
- SERIAL_ERROR_START();
- SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
- kill(PSTR(MSG_KILLED));
+ delay(8000);
}
@thinkyhead is is possible to change the period of the watchdog timer prior to the delay? If so, you could lower it to a very small value, which would make the reset more instantaneous.
Aha! Something like this?
if (killCount >= KILL_DELAY) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM("RESET");
- kill(PSTR(MSG_KILLED));
+ wdt_enable(WDTO_15MS);
+ while(1);
}
Seems like it should work. However, keep in mind that this won't work for 32-bit boards that use Smoothieware bootloader, since it will hang in the bootloader if it detects that a watchdog reset occurred.
Well, this isn't going into Marlin proper. It's just for this motley crew.
Beide Vorschläge von thinkyhead bringen keinen Erfolg. Nach wie vor kommt nur der Kill.
Sorry, fell into German. Both code snippets didn't succeed. Again only the Kill effect.
Good luck. This issue is being closed, and we will soon be locking down the repository to deal with troll behavior.
The minimal change to 'reset' instead of 'kill' when pressing the button at the display is
@@ -13424,10 +13424,11 @@ void manage_inactivity(bool ignore_stepper_queue/*=false*/) {
// KILL the machine
// ----------------------------------------------------------------
if (killCount >= KILL_DELAY) {
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_KILL_BUTTON);
+ asm volatile ("jmp 0"); // RESET
kill(PSTR(MSG_KILLED));
}
#endif
#if HAS_HOME
Tested and working at todays bugfix-1.1.x
branch.
If you want always a 'reset' instead of a 'kill' try:
@@ -13581,10 +13581,11 @@ void idle(
/**
* Kill all activity and lock the machine.
* After this the machine will need to be reset.
*/
void kill(const char* lcd_msg) {
+ asm volatile ("jmp 0"); // RESET
SERIAL_ERROR_START();
SERIAL_ERRORLNPGM(MSG_ERR_KILLED);
thermalManager.disable_all_heaters();
disable_all_steppers();
Be aware we do a kill
by purpose!
After a reset, not realized by the host, it will continue to send data. That can be disastrous.
It's only a 'software' reset. Pins not properly initialised by Marlin will have the state before the reset. They will not have the default hardware state. If things go really wrong, a heater may be on.
A physical reset button is safer than this software reset. The button is not tested if the program hangs in an interrupt. The kill function is likely safer than the hardware reset.
The watchdog reset is a real hardware reset and has the advantage of hanging on some boars in the bootloader. (As far as i know this is not a good idea for a RAMPS-FD V1.x. The heaters will be on. This is why RAMPS-FD V1.x is called "unsave".)
@AnHardt Thanks. Your first solution works. Didn't try the second. Bye Ludwig
Thanks @cjsoong ! I'm converting my CNC in a 3D printer, and need no endstops, so I was looking to hard reset my board after making some negative movements. The only way to reset machine position in Marlin 1.1.8 is reseting the board; G92 has no efect in machine position anymore. Your modifications to Marlin_main.cpp worked great for me!
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
I just finished printing a box for my ramps board and LCD and if i put it all together the reset button on the arduino board will be out of reach, but the one on the LCD is already incorporated in the design https://www.thingiverse.com/thing:1874156
so from now on when thermal runaway is triggered i'm only left with the power button to work as a reset which i don't quite like to trigger since it turns the whole PSU off then on.
is there a way to make the stop button on the lcd act as the rest on the arduino trough software? or do i have make "changes" to the hardware?