M104 with inactive tool puts heater in standby mode
-
As I understand it, in the situation that is causing you a problem, Cura is sending a M104 command with a T parameter referring to the tool that is already on standby in order to change its temperature. RRF implements that by calling StandbyTool on it. Granted, if the tool is already in standby, it could do it by setting the tool temperature directly instead. But that wouldn't solve your problem, would it? What you seem to be asking RRF to do is to ignore Cura's attempt to change the temperature of the standby tool - which would break the behaviour for users with dual-nozzle printers.
I'd really like to hear what @burtoogle has to say, he is the Cura expert round here.
-
@dc42 said in M104 with inactive tool puts heater in standby mode:
Granted, if the tool is already in standby, it could do it by setting the tool temperature directly instead.
Not quite. There is no instead here - M104 or M109 handling changes standby temperature already and I do not ask to touch or change it. This is existing functionality. I only ask not to standby tool that is already in standby state.
But that wouldn't solve your problem, would it?
The point is it actually would. Problem is this:
// code here T1 ; new tool activated, now T0 is in standby // some more code M104 T0 S123 ; cura sets standby temperature for T0 and RRF screws T1 state by reapplying standby to T0
So T0 is already in standby state here when M104 executed. For multiple hottend people it will change standby temperature heater for T0 and stanby temperature would be used. For shared hotend if M104 does not put T0 into standby again standby temperature for T0 would be updated but it will not affect heater as it will keep active state from T1. I hope I explained it clearly. So properly maintaining state here should not break functionality for multiple hotend and would fix for shared one.
What you seem to be asking RRF to do is to ignore Cura's attempt to change the temperature of the standby tool - which would break the behaviour for users with dual-nozzle printers.
No I do not. I am only asking to maintain state and do not standby tool that is already in standby mode. Everything else should be as it is.
-
@rglory One last shot.........
Given that you only have one heater, you can only have one temperature for both tools at any given time. So you can't use a lower standby temperature. Therefore, if you can't physically have a lower standby temperature (because both tools share the same heater), then why don't you simply set the standby temperature to be the same as the active temperature?
Then it won't matter what tool is in what state. Cura can send M104 Tn Snn and it won't change anything because Snn is equal to the active temperature. With a shared heater, active and standby temperatures will be the same in the physical world so why not simply configure them to be the same?
As I said before, I don't understand why you are trying to use a low standby temperature for two tools which share the same heater. If the heater drops to standby temperature, then the active tool will also be at standby temperature. Conversely, if the heater is at active temperature, then the tool which is on standby will also be at that active temperature.
-
@deckingman said in M104 with inactive tool puts heater in standby mode:
Therefore, if you can't physically have a lower standby temperature (because both tools share the same heater), then why don't you simply set the standby temperature to be the same as the active temperature? Then it won't matter what tool is in what state.
In theory yes, in practice this is very error prone method. First - Cura maintains that standby temperature as material property. So if I update material I need to remember to go to each extruder and fix that. Plus if I have another printer with separate nozzles I need to remember not to do that or to revert that back. Plus if I want to adjust temperature in fly trhough web interface in Duet to tune my printing this also will be screwed by incorrect state transition. On another side if firmware would fix state maintenance that would work for both variants of printers - shared nozzles or not, or even one that has both shared and not shared in the same hadrware uniformly without any issue.
I think it is pretty clear that state maintenance has a bug here there should be no transition from standby to standby mode. Otherwise logically we should have transition for active tool from active to active again. That would fix the issue as well, but I do not think that is necessary.
As I said before, I don't understand why you are trying to use a low standby temperature for two tools which share the same heater.
I am not trying to use standby temperature, I do not have a choice. Cura injects that code no matter what AND the worst possible way. I know that IT is Cura's problem, but why not to fix bug here and on a side effect it would eliminate this issue with Cura?
To repeat again I do not get confirmation yet but I think it is pretty clear that transition from standby to standby is a bug and fixing it should not break functionality for existing users and improve other people experience at the same time.
-
@rglory Your arguments don't make any sense at all, so I finally give up.
-
@deckingman said in M104 with inactive tool puts heater in standby mode:
Your arguments don't make any sense at all
If that arguments not good enough for you lets put it this way: almost every new user using Duet and Cura for shared hotend with multiple extruders is going to hit this issue and it takes quite long time and frustration to identify the cause and find solution. Either task is not simple. Yes we can blame Cura for that and give up, but there is a bug in firmware and fixing that will help those new users. Good enough for you now?
Thanks,
Slava -
I am sorry, you most definitely are asking for RRF to ignore Cura's attempt to change the current temperature of the tool that is on standby. Cura asks to do that when it expects to switch to that tool in the near future.
The problem is that Cura seems to be assuming that the tool on standby doesn't use the same heater(s) as the current tool. Are you certain that there isn't an option in Cura to leave the temperatures of tools alone when they are not active?
-
@dc42 said in M104 with inactive tool puts heater in standby mode:
I am sorry, you most definitely are asking for RRF to ignore Cura's attempt to change the current temperature of the tool that is on standby. Cura asks to do that when it expects to switch to that tool in the near future.
I am not sure we are on the same page here. I am referring to the current situation with RRF as represented in github on your branch and what Cura does. So M104 Tn Sxxx sets standby temperature for inactive tool first. Am I correct here? Setting standby temperature would affect temperature of heaters associated with that tool if they also in standby mode. And it works for multiple nozzles ie separate heaters. But if a heater is shared it would be in active state (deactivating one tool puts it in standby and activating another brings it back to active if I am not mistaken here). So changing standby temperature on inactive tool would not affect shared heater if not this bug that reapplies standby mode to that tool again which puts heater into standby mode.
The problem is that Cura seems to be assuming that the tool on standby doesn't use the same heater(s) as the current tool.
I think Cura is correct assuming that the tool in in standby. Problem is that M104 handling code in RRF blindly reapplies standby mode to the tool again which applies standby mode to all heaters associated with it and that breaks the logic - shared heater loosing active state from active tool. So making M104 to check if that tool already in standby and not to do that again (standby temperature applied before and would be handled properly if heater is in standby mode) would fix this issue for shared heater and should not break anything for not shared one.
Are you certain that there isn't an option in Cura to leave the temperatures of tools alone when they are not active?
Only option I found is to disable temperature control completely. And it is not simple - you have to create a json file defining your printer and disable temperature control completely. That what I have right now and I inject temperature commands into g-code but for me this is not a very good solution. And I spent long time and many prints cancelled to find cause and this solution.
-
@rglory Your arguments don't make sense for te following reasons.
You say that the standby temperature needs to be maintained as part of the material properties in Cura. That's all well and good. Then you say you need to change it for each extruder. Why? If it's set in materials properties why do you need to make changes for each extruder?
Then you say, if you have another printer you need to remember not to do that? Again why? For this printer, you can't have separate active and standby temperatures - they have to be the same because you have a shared heater for each tool. If you have another printer with separate nozzles, which allows you to use different active and standby temperatures then you'll have to do things differently in any case. No matter how or where the active and standby temperatures are set they will be different. What's to stop you creating filaments such as "PLAsingleHeater" and "PLAseparateHeaters" It doesn't matter how or where you set the active and standby temperature. If you have different machines with different temperature requirements, then you can't use the same filament temperature profile for both machines.
Then you say that if you want to adjust the temperature on the fly through the web interface, you won't be able to do it. Of course you will. Why on earth do you think you won't be able to? Hundreds if not thousands of us do that so why do you think it won't work for you?
-
@deckingman said in M104 with inactive tool puts heater in standby mode:
You say that the standby temperature needs to be maintained as part of the material properties in Cura. That's all well and good. Then you say you need to change it for each extruder. Why? If it's set in materials properties why do you need to make changes for each extruder?
Because I do not want to screw up material definition for particular workaround. And yes I see this solution for changing standby temperature for particular printer hardware configuration as a workaround and not proper solution. If you disagree with that I am totally fine, I just try to point again and again state maintenance has a bug here and it produces this behavior. If tool would not switch from standby to standby both parties would be happy - shared nozzle and not and we would not need to create different material per printer and I would not spent long time trying to fix this issue.
For this printer, you can't have separate active and standby temperatures - they have to be the same because you have a shared heater for each tool.
Yes I can, if state would be maintained then standby temperature would be happily ignored by my printer but would still work by printer that has separate heater and everybody is happy.
Then you say that if you want to adjust the temperature on the fly through the web interface, you won't be able to do it. Of course you will. Why on earth do you think you won't be able to? Hundreds if not thousands of us do that so why do you think it won't work for you?
Sorry maybe I did not make myself clear. I can change but next standby temperature command from Cura will screw it up again. And it will do that only for me - I mean shared heater. Different heater people are not affected.
-
@rglory said in M104 with inactive tool puts heater in standby mode:
I am not sure we are on the same page here. I am referring to the current situation with RRF as represented in github on your branch and what Cura does. So M104 Tn Sxxx sets standby temperature for inactive tool first. Am I correct here? Setting standby temperature would affect temperature of heaters associated with that tool if they also in standby mode. And it works for multiple nozzles ie separate heaters. But if a heater is shared it would be in active state (deactivating one tool puts it in standby and activating another brings it back to active if I am not mistaken here).
This is why I mentioned the possibility of ignoring the M104 request (at least in terms of not changing the current temperature) if the standby tool shares heaters with the active tool. This could be done in Tool::Standby. The current code copies the tool standby temperatures to the heater standby temperatures, and sets the heaters to standby. The change would be that if the active tool is not the same one that is being set to standby, omit these steps for any heaters that are also used by the active tool. So the code would become something like this:
void Tool::Standby() { for (size_t heater = 0; heater < heaterCount; heater++) { if (currentTool == nullptr || currentTool == this || !currentTool->UsesHeater(heater)) { reprap.GetHeat().SetStandbyTemperature(heaters[heater], standbyTemperatures[heater]); reprap.GetHeat().Standby(heaters[heater], this); } } state = ToolState::standby; }
BTW I didn't design the current active/standby scheme, and I'm not convinced that it makes any sense for heaters (as distinct from tools) to have separate states for active and standby.
I'll consider making these changes in the next 2.03beta release.
-
@dc42 said in M104 with inactive tool puts heater in standby mode:
This is why I mentioned the possibility of ignoring the M104 request (at least in terms of not changing the current temperature) if the standby tool shares heaters with the active tool.
It depends on what it means of ignoring M104 request. There are 2 actions - set active and standby temperature of the tool and switching tool into standby mode. I think it is enough to prevent only second part and it should be fine.
So the code would become something like this:
I see what you mean, looks like you are afraid that without this call temperatures on non shared heaters would not be set. But the point is it is not really necessary. M104/109 handling code sets temperatures first:
if (simulationMode == 0) { SetToolHeaters(applicableTool, temperature, true); }
which in order sets active and standby temperature for the tool:
tool->SetToolHeaterActiveTemperature(h, temperature); if (both) { tool->SetToolHeaterStandbyTemperature(h, temperature); }
SetToolHeaterActiveTemperature would not affect either shared or separate heaters:
const bool setHeater = (currentTool == nullptr || currentTool == this);
it would be false and not affect either. SetToolHeaterStandbyTemperature() on another side will work differently for shared and separate heaters:
reprap.GetHeat().SetStandbyTemperature(heaters[heaterNumber], standbyTemperatures[heaterNumber]);
will be executed. Now separate heater machine will have all heaters in standby mode and this will affect their current temperature. On shared heater heater will be in active state and this will not change temperature, only store it.
So according to this it is completely not necessary to call Tool::Standby() all temperatures would be updated properly by existing code. So I think cleanest fix here would be as I suggested before:
if( applicableTool->GetState() != ToolState::standby ) reprap.StandbyTool(applicableTool->Number(), simulationMode != 0);
as it will involve the minimum code change and minimize possible side effects.
But of course it is up to you to decide.
-
I think I see what you are saying, it's that in a dual heater machine the heater will be in standby mode, so when the call to SetToolHeaterStandbyTemperature sets the standby temperature it will affect the heater setpoint; but in a shared nozzle machine the heater will be in active mode so it won't.
However, if a slicer sends a M104 command near the start of the file to put the second tool on standby when it was previously off, then your proposed change would still set the heater to standby temperature - which is wrong if it is being used by the active tool. So I think it doesn't quite fix all instances of the problem.
-
@dc42 said in M104 with inactive tool puts heater in standby mode:
I think I see what you are saying, it's that in a dual heater machine the heater will be in standby mode, so when the call to SetToolHeaterStandbyTemperature sets the standby temperature it will affect the heater setpoint; but in a shared nozzle machine the heater will be in active mode so it won't.
Exactly
However, if a slicer sends a M104 command near the start of the file to put the second tool on standby when it was previously off, then your proposed change would still set the heater to standby temperature - which is wrong if it is being used by the active tool. So I think it doesn't quite fix all instances of the problem.
Yes it is possible. But first it is unlikely to happen - usual flow I believe is to issue M104 to inactive tool for it to heat in background and then M109 to active one to wait for it to reach. But even if that is the case solution for this case is very simple and straightforward - just send inactive tool M104 command (or newer Gnn command) in printer startup code. This is very simple step and nothing comparing to find every instance of M104 in middle of printing and remove it. And could be just documented in Wiki for multiextruder/shared nozzle setup.
On another side calling StandbyTool on standby state does not sound right, and usually it leads to problems sooner or later (what is actually happened in this case). If I would develop it I would write it like this:
void Tool::Standby() { if( state == ToolState::standby ) return; ...
but of course would do that in the beginning of developing, doing so now would be too dangerous for possible side effects. If you would want to hear my opinion I think cleaner solution would be to check from which state Tool is coming from and if it is off then it would also check every heater state and only apply state transition if it is in the same state. Probably the same for active to standby or standby to active transition as well. So something like this:
void Tool::Standby() { if( state == ToolState::standby ) return; for( auto heater : heaters ) { if( heater->GetState() == state ) heater->standby(); } state = ToolState::standby;
}
this is more pseudocode, but I think idea is clear. But again most probably it is not the good time to do it now when there are many parts depends on current behavior and in current situation changes in M104 section seems to be the smallest change which should have minimal side effects and pretty easy to test.
Thanks,
Slava -
I realise this is old.
I noticed this while reading through - I have been hitting this issue with M3D Promega (Duet Maestro) and three tools defined in CURA.
There is also another issue to consider which is that CURA 4.0 decides to turn off un-used tools, so if a tool is not used again for the rest of the print ( for example you finish with white filament and only carry on in black), then CURA sends an M104 TX S0.
It sends this 'after' it has selected the new tool so that all temps suddenly go to 0 and you can't extrude.You can get around this by:
- Settings all tools standby temps to the same as the printing temp - so any standby set doesn't cause issues.
- You can use regex as way to parse the gcode automatically in cura and remove any M104 tX s0 commands
This works correctly without issue for me...…..
However I have been conversing with smartavionics who helps out on CURA code and he has produced a proof of concept build which changes the order of the TX S0 commands so they are sent 'before' the new tool temp command.
- However CURA main devs are not keen on the change.
Obviously an ideal fix in CURA is a check box that acknowledges that all tools share a heater - and then this stops sending the Tool OFF and Tool standby messages during the print.
- This also is getting resistance from CURA devs as all the Ultimaker printers are independent heaters.
-
@andymoz said in M104 with inactive tool puts heater in standby mode:
Obviously an ideal fix in CURA is a check box that acknowledges that all tools share a heater - and then this stops sending the Tool OFF and Tool standby messages during the print.
This also is getting resistance from CURA devs as all the Ultimaker printers are independent heaters.
To be honest, I don't think they have expressed an opinion as to whether adding a shared heater checkbox to the machine definition dialog is approved or not. They may be quite amenable to that.
-
@burtoogle - Indeed. Maybe I should re-word as low on their priority so they may not find the time to do it themselves. I have read multiple bug reports on the cura GitHub where they are just shut as will not do. This gives a pretty strong indication to me.
-
The problem is that M104 and M109 are not fit for purpose. They were OK when 3D printers had only one extruder. They are sort of OK when each tool has exactly one heater that is not shared with any other tools. But for more complex situations, including mixing extruders (different tools share the same heater) and tools with multiple heaters (e.g. tools that use pellet hoppers, so there is a 2-stage melting process), they don't work.
RepRapFirmware implemented a solution way back in 2013. Instead of using commands to control tool heaters directly, use commands to specify the active and standby temperatures on a per-heater per-tool basis. Then when a tool is selected, RRF heats up its heaters to active temperature. When a tool is deselected, RRF starts cooling its heaters down to standby temperature. The slicer doesn't need to know the details of how the tools are arranged, it just needs to know the tool numbers you want to use and what active and standby temperatures you want to use for them.
This approach solves the problem, although I would have preferred it if the command to set tool temperatures wasn't G10 because that already had meaning in CNC machines, and it now also has a totally separate meaning in 3D printers (firmware retraction).
Unfortunately, most slicers persist in using M104 and M109 even when the target is RepRapFirmware. Worse, most of them don't even select a tool when they start heating. This means that when RRF receives M104 and M109 commands, RRF has to second-guess what the slicer is trying to do. That's why, when it receives M109 with a T parameter, it makes that tool active; and when it receives a M109 command with no T parameter and there is no active tool, it looks for a default tool to activate.
The real solution is for slicers to stop generating M104 and M109 commands when targeting RepRapFirmware, and to use G10 commands to set active and standby temperatures instead. There is one scenario that isn't covered by this approach: when targeting a dual-nozzle machine, Cura anticipates a tool changes and sends a M104 command to pre-heat the new tool to active temperature. I could add support for this in RRF by adding a new command meaning "start heating tool N to its active temperature".
Meanwhile, the only thing I can think of doing to help is to change the response to M104 so that if M104 has a T parameter which is not the active tool, then any heaters associated with that tool that are also used by the current tool are not altered.
-
That's all understood, @dc42 but I am not going to work on a G10 solution for Cura right now. Maybe in the future.
In the meantime, I'm adding a setting that makes Cura aware that the extruders share a heater and in that situation it won't issue any M104 or M109 gcodes for the non-active extruders. It won't do any ramp up/down of the non active extruders (obviously). It will simply issue a M109 when it has switched to an extruder whose temperature is different from that specified by the last M109 gcode issued.
-
@burtoogle. I think this will work. I need to slice a few models to make sure.