Skip to content

[2.0.x] SWITCHING_TOOLHEAD#11623

Merged
thinkyhead merged 2 commits intoMarlinFirmware:bugfix-2.0.xfrom
smoki3:bugfix-2.0.x-toolchanger
Sep 8, 2018
Merged

[2.0.x] SWITCHING_TOOLHEAD#11623
thinkyhead merged 2 commits intoMarlinFirmware:bugfix-2.0.xfrom
smoki3:bugfix-2.0.x-toolchanger

Conversation

@smoki3
Copy link
Contributor

@smoki3 smoki3 commented Aug 23, 2018

Add tool-changing with a single X-carriage and docking toolheads, as with the E3D Toolchanger system. More at the E3D TCBlog.


Hi everybody,

as i already mentioned here:
#11588

This PR also includes:
#11616

I prepared the main functionality by myself.
The tool change it self work already fine. But one required feature is still missing.
For this type of tool changer it would be great if we can place the actual tool head back and grab no new one. So that you don't have a active tool. But I have no idea to realize it.

Would be nice if someone can help me.

Thank you!

@smoki3 smoki3 changed the title Add SWICHTING_TOOLHEAD Feature [2.0.x] Add SWICHTING_TOOLHEAD Feature Aug 23, 2018
@smoki3
Copy link
Contributor Author

smoki3 commented Aug 23, 2018

So now it's fully working besides the "empty tool" function

@thinkyhead thinkyhead changed the title [2.0.x] Add SWICHTING_TOOLHEAD Feature [2.0.x] SWITCHING_TOOLHEAD Aug 24, 2018
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tabs are forbidden. Please set your editor to always use 2 real spaces for indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have a recommendation for a good editor? I actually using xcode. It handled the spaces very bad...

Copy link
Member

@thinkyhead thinkyhead Aug 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you forgot the if here and on other debugging lines.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes I see. I will clean up asap.
Thank you

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch from 95c6caa to 2e4e575 Compare August 24, 2018 22:11
@thinkyhead
Copy link
Member

thinkyhead commented Aug 24, 2018

Rebased, squashed, fixed formatting, typos, spelling, and bugs. Added option to example configs.

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch 4 times, most recently from cd78565 to c740ec2 Compare August 24, 2018 22:44
Copy link
Member

@thinkyhead thinkyhead Aug 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the hotend_offset pertains to the nozzle's position relative to another nozzle on the same carriage, I'm pretty sure that it should not be included here. The switching toolhead docking positions should refer to the carriage's position, and not to the nozzle's position.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So without the 'hotend_offset' the printer will crash by the next tool change as soon a offset is applied. Or is there a variable that refer always to the intal home position?

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch from c740ec2 to 1e2cd36 Compare August 24, 2018 23:26
@thinkyhead
Copy link
Member

But I have no idea to realize it.

First, split up the function so that the drop-off is in one function and the pick-up is in another function. Under normal conditions, the change will do both. But for a certain G-code command or parameter it could just do the drop-off. For example, T-1 might only drop off, but not pick up.

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch 4 times, most recently from 4a3fc6d to 6dc68d7 Compare August 25, 2018 02:33
@thinkyhead
Copy link
Member

This still needs more work to be fully comprehensive. With certain kinds of tool changers (such as E3D's) there's going to be a separate hotend (heater plus thermistor) for each toolhead. But for the E axis there may be either a single E stepper driver (with stepper signals routed through the carriage) or multiple E stepper drivers — one per toolhead. Regardless of whether there's only one E stepper driver or one-per-toolhead, each toolhead may want to use different E steps-per-mm, since different toolheads may have different sized drive gears, etc.

And, we need to look at how the hotend_offset applies also. I presume it refers to slight variations in the nozzle alignment in each toolhead.

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch 2 times, most recently from 38ef351 to 026af7b Compare August 25, 2018 03:04
@smoki3
Copy link
Contributor Author

smoki3 commented Aug 25, 2018

Sorry I don't got the point with one or more stepper drivers. In this kind of tool changer normally there use one per axis. Otherwise you can use switching extruder. And actually you can simply set the E-steps-per-mm per axis. With the function 'DISTINCT_E_FACTORS' you can set it per extruder.

So the 'hotend_offset' always refers to first nozzle. As soon the tool change is finished the nozzle will move to the offset position.

@thinkyhead
Copy link
Member

See https://www.youtube.com/watch?v=bn4gWYOzHxQ to see what I'm talking about with regard to a multi-tool setup that uses only a single E stepper driver, but where each tool has its own separate heater and thermistor.

The "Switching Extruder" is a whole different beast. It is implemented with the assumption that there will be two nozzles on a single carriage, switched with a servo, and it is currently limited to a setup with either a single X carriage or a Dual X Carriage.

Meanwhile, DISTINCT_E_FACTORS is currently implemented with the presumption that each extruder will have its own E stepper driver. So it will need to be modified to be able to handle a setup that utilizes a single E stepper driver, as with the E3D Toolchanger.

I have applied to be a Beta Tester for the E3D Toolchanger, and it's a merit-based queue, so there's a reasonable chance we will have a system to test with in the near future.

@smoki3
Copy link
Contributor Author

smoki3 commented Aug 25, 2018

On this video you see that for each hotend the use a separated extruder, stepper motor and stepper driver. You can see the 4 extruder under the hotend docking station.
They use the duet board with the extension board to handle up to 7 stepper drivers.

On
https://youtu.be/jfopGYO0r-M
at 14:05 you can see the electronics.

Would be nice to handle all motors with one driver. But this should be switched to another feature or not?

@thinkyhead
Copy link
Member

thinkyhead commented Aug 25, 2018

I was there at ERRF and got to see the beast for myself. Sanjay promised to send me a unit (but, he was kind of drunk at the time). E3D was also at ERRF with an more refined version. (By that time Sanjay had forgotten who I was….) There are electrical contacts on the carriage, so I was under the impression that they were there to pass signals to the stepper motor on the picked-up tool. But perhaps they do have separate signal lines for each tool.

@smoki3
Copy link
Contributor Author

smoki3 commented Aug 27, 2018

I think the wires from the carriage are only for the BLTouch and the lock mechanism servo.
I did a lot test prints last weekend. It work fine! You just have to consider that you switch back to T0 after a print. Because if you restart your printer marlin always starts with T0.

Is it possible to store the last used tool?

@alexxy
Copy link
Contributor

alexxy commented Aug 27, 2018

Its in principle possible to use one stepper motor driver for all tools but in this case you need additional electronics (signal switching system, and stepper drivers protection)

Personally i like your switching system very much and plan to use it on my corexy printer.

@smoki3
Copy link
Contributor Author

smoki3 commented Aug 27, 2018

yes thats right. In this case we need extra electronics. So i think this should be added in a additional feature

@alexxy
Copy link
Contributor

alexxy commented Aug 28, 2018

Btw seems part of this mechanism is already available for Prusa i3 MK2 MK3 =) But without driver disconnect protection.

@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch 3 times, most recently from a9f1cda to a7139b8 Compare September 2, 2018 19:44
@thinkyhead thinkyhead force-pushed the bugfix-2.0.x-toolchanger branch from a7139b8 to 696bfec Compare September 3, 2018 01:45
@alexxy
Copy link
Contributor

alexxy commented Sep 4, 2018

Actualy there is simple circuit that prevent damage to stepper motor driver =) and actualy this circuit can be built into switcher one.. (only few modifications needed)

More interesting problem is in case you wanna switch heater and thermistor

@smoki3
Copy link
Contributor Author

smoki3 commented Sep 5, 2018

so thinkyhead is only talking about shared stepper driver not the heater and thermistor.

Anyway I think this kind of multiplexer, should be done as an extra feature and not included into this.
Or what do you think?

@alexxy
Copy link
Contributor

alexxy commented Sep 5, 2018

Multiplexer can be separate feature. Marlin already have one supported (Prusa Stepper multiplexer)

@thinkyhead
Copy link
Member

thinkyhead commented Sep 8, 2018

I like it. Basically, the tool-changer I was imagining would be just like the E3D motion system with a multiplexer added on. So having this just target the tool-changing aspect makes good sense.

@thinkyhead thinkyhead merged commit e25d2ae into MarlinFirmware:bugfix-2.0.x Sep 8, 2018
@thinkyhead
Copy link
Member

I see that RepRapFirmware (on the E3D Toolchanger) uses T-1 to change to "no tool." We need to implement that too!

@UticaTechClub
Copy link

@smoki3 @thinkyhead
Hi,
We have also developed a tool changer that is similar to e3d's and managed tool parking and pickup through custom gcode on extruder change.
I just now noticed all this work you guys did in Marlin under SWITCHING_TOOLHEAD definition - thank you!
During the test, I ran issue with extruder Z offset.
After the boot, I run the following:

M218 T0 X0.0 Y0.0 Z0.0
M218 T1 X1.2 Y-2.2 Z4.0
G28
T1
T0
T1
T0
...

Problem: 4mm offset on T1 is never applied. Bed does not move 4mm up/down on extruder change.

@thinkyhead
Copy link
Member

thinkyhead commented Mar 10, 2019

@UticaTechClub — What does M114 say after T1 and T0 in that scenario?

Note that if the Z position is down at the bed, a T1 command won't move the nozzle down because it would damage the machine. However, it should be able to move the nozzle up in that case. So try M218 Z-4 before the G28 and see if it raises the nozzle when you do T1.

@UticaTechClub
Copy link

Thank you @thinkyhead @smoki3

I tried both, positive and negative Z offset and it behaves the same, meaning print bed does not go up/down on tool change.

Here is the exchange with negative Z offset:

Send: M851 Z0.0
Send: M218 T0 X0.0 Y0.0 Z0.0
Send: M218 T1 X0.0 Y0.0 Z-4.0
Send: G28
Recv: echo:Active Extruder: 0
Recv: X:147.00 Y:137.00 Z:10.00 E:0.00 Count A:22743 B:801 Z:801
Send: M114
Recv: X:147.00 Y:137.00 Z:10.00 E:0.00 Count A:22743 B:801 Z:801
Send: T1
Recv: echo:Active Extruder: 1
Send: M114
Recv: X:147.00 Y:137.00 Z:10.00 E:0.00 Count A:22743 B:801 Z:801
Send: T0
Recv: echo:Active Extruder: 0
Send: M114
Recv: X:147.00 Y:137.00 Z:10.00 E:0.00 Count A:22743 B:801 Z:801

Is it possible that merely issuing T command is not enough to trigger offset adjustments?
Maybe planner awaiting to receive G0 or G1?

I also tried applying X and Y offsets and those appears to be not working either.

Thank you so much for your help.

@UticaTechClub
Copy link

@thinkyhead @smoki3
Is it possible that in addition to M218, the following defines need to be un-commented?

// Offset of the extruders (uncomment if using more than one and relying on firmware to position when changing).
// The offset has to be X=0, Y=0 for the extruder 0 hotend (default extruder).
// For the other hotends it is their distance from the extruder 0 hotend.
//#define HOTEND_OFFSET_X {0.0, 20.00} // (mm) relative X-offset for each nozzle
//#define HOTEND_OFFSET_Y {0.0, 5.00}  // (mm) relative Y-offset for each nozzle
//#define HOTEND_OFFSET_Z {0.0, 0.00}  // (mm) relative Z-offset for each nozzle

I thought that enabling

#define SWITCHING_TOOLHEAD

is enough to also make offsets work.

@thinkyhead
Copy link
Member

I also tried applying X and Y offsets and those appears to be not working either.

I see a couple of bugs in the handling of switching_toolhead_tool_change. Let's see how it behaves after I patch the most obvious ones.

Is it possible that in addition…

Not needed. M218 will throw "Unknown command" if hotend offsets are non-existent. If you don't set them in the config they just default to 0,0,0.

@thinkyhead
Copy link
Member

@UticaTechClub — Could you ZIP your Configuration.h and Configuration_adv.h and drop the archive on your next reply? It will help me check that everything is compiling the way it should with your settings.

@UticaTechClub
Copy link

@UticaTechClub — Could you ZIP your Configuration.h and Configuration_adv.h and drop the archive on your next reply? It will help me check that everything is compiling the way it should with your settings.

@thinkyhead Thank you!!!
Please see attached.

I will look at the debug output tonight with M111 (just saw this cool command), because tool_change.cpp sends some really good debug messages to at least distinguish the program flow.
Marlin.zip

@UticaTechClub
Copy link

@thinkyhead
If I may ask you...
Are you planning to attend MRRF2019?

I met you with my students last year and it was such a delight :)

@thinkyhead
Copy link
Member

tool_change.cpp sends some really good debug messages

They should be even better if DEBUG_LEVELING_FEATURE is enabled, as it covers homing, leveling, tool-change, and some other things.

Are you planning to attend MRRF2019?

Yes, I will be there. Last year was a lot of fun. It was good to see the RepRap spirit is alive and well!

@UticaTechClub
Copy link

@thinkyhead

I have submitted these offsets, homed and switched over to T1:

M218 T0 X0.0 Y0.0 Z0.0
M218 T1 X-2.0 Y-2.0 Z-2.0
G28
T1

I can see how offsets applied to the current_position and they are proper, but then Move Back is happening and everything is getting lost:

SENDING:T1
echo:T1
>>> T(1)
  current_position=(147.00, 137.00, 10.00) : BEFORE
  current_position=(147.00, 137.00, 12.00) : Starting Toolhead change
  current_position=(147.00, 137.00, 14.00) : (1) Raise Z-Axis
(2) Place old tool 0
  current_position=(1.60, 137.00, 14.00) : Move X SwitchPos
  current_position=(1.60, 305.00, 14.00) : Move Y SwitchPos + Security
(3) Unlock and Place Toolhead
  current_position=(1.60, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(1.60, 220.00, 14.00) : Move back Y clear
(4) Move to new toolhead position
  current_position=(83.00, 220.00, 14.00) : Move to new toolhead X
  current_position=(83.00, 305.00, 14.00) : Move Y SwitchPos + Security
(5) Grab and lock new toolhead
  current_position=(83.00, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(83.00, 220.00, 14.00) : Move back Y clear
  current_position=(83.00, 220.00, 16.00) : (6) Apply Z offset
Toolhead change done.
Offset Tool XY by { -2.00, -2.00, -2.00 }
  current_position=(81.00, 218.00, 14.00) : sync_plan_position
  destination=(147.00, 137.00, 10.00) : Move back
>>> do_blocking_move_to(147.00, 137.00, 10.00)
<<< do_blocking_move_to
echo:busy: processing
echo:Active Extruder: 1
  current_position=(147.00, 137.00, 10.00) : AFTER
<<< T()

The current_position, definitely has proper offsets applied,

  current_position=(83.00, 220.00, 16.00) : (6) Apply Z offset
Toolhead change done.
Offset Tool XY by { -2.00, -2.00, -2.00 }
  current_position=(81.00, 218.00, 14.00) : sync_plan_position

but at line 857 of tool_change.cpp it moves back to destination position which doesn't have offsets applied

        // Move back to the original (or tweaked) position
        do_blocking_move_to(destination);

So the question maybe is why destination has no new extruder offsets applied?

@UticaTechClub
Copy link

@thinkyhead One other observation...

Line 554 of tool_change.cpp, inside switching_toolhead_tool_change() function, applies Z offset to the current_position:

current_position[Z_AXIS] += hotend_offset[Z_AXIS][active_extruder] - hotend_offset[Z_AXIS][tmp_extruder];

An then, on line 797, X, Y and Z offsets are applied, so Z gets applied second time. Function switching_toolhead_tool_change() applied Z offset, and now X, Y, Z offsets are applied from tool_change() which just called switching_toolhead_tool_change():

current_position[X_AXIS] += xdiff;
current_position[Y_AXIS] += ydiff;
current_position[Z_AXIS] += zdiff;

And that is what debug output is showing, when Z goes from 14.0 to 16.0 and to 14.0:

  current_position=(83.00, 220.00, 14.00) : Move back Y clear
  current_position=(83.00, 220.00, 16.00) : (6) Apply Z offset
Toolhead change done.
Offset Tool XY by { -2.00, -2.00, -2.00 }
  current_position=(81.00, 218.00, 14.00) : sync_plan_position

@thinkyhead
Copy link
Member

I see you found the same code anomaly I was referring to above.
I will patch it shortly.

thinkyhead added a commit that referenced this pull request Mar 13, 2019
@UticaTechClub
Copy link

@thinkyhead
Thank you for the update, I will re-test everything.

But, what about line 846 of tool_change.cpp, moving back to destination while disregarding current_position (which takes in account hotend offsets)?

        // Move back to the original (or tweaked) position
        do_blocking_move_to(destination);

@UticaTechClub
Copy link

@thinkyhead
The latest code addressed this #11623 (comment) issue, but this #11623 (comment) issue is still the same.

Here is the debug code of switching from T0 to T1:

>>> T1
SENDING:T1
echo:T1
>>> T(1)
  current_position=(147.00, 137.00, 10.00) : BEFORE
  current_position=(147.00, 137.00, 12.00) : Starting Toolhead change
  current_position=(147.00, 137.00, 14.00) : (1) Raise Z-Axis
(2) Place old tool 0
  current_position=(1.60, 137.00, 14.00) : Move X SwitchPos
  current_position=(1.60, 305.00, 14.00) : Move Y SwitchPos + Security
(3) Unlock and Place Toolhead
  current_position=(1.60, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(1.60, 220.00, 14.00) : Move back Y clear
(4) Move to new toolhead position
  current_position=(83.00, 220.00, 14.00) : Move to new toolhead X
  current_position=(83.00, 305.00, 14.00) : Move Y SwitchPos + Security
(5) Grab and lock new toolhead
  current_position=(83.00, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(83.00, 220.00, 14.00) : Move back Y clear
Toolhead change done.
Offset Tool XY by { -2.00, -2.00, -2.00 }
  current_position=(81.00, 218.00, 12.00) : sync_plan_position
  destination=(147.00, 137.00, 10.00) : Move back
>>> do_blocking_move_to(147.00, 137.00, 10.00)
<<< do_blocking_move_to
echo:busy: processing
echo:Active Extruder: 1
  current_position=(147.00, 137.00, 10.00) : AFTER
<<< T()

And T1 to T0:

>>> T0
SENDING:T0
echo:T0
>>> T(0)
  current_position=(147.00, 137.00, 10.00) : BEFORE
  current_position=(147.00, 137.00, 12.00) : Starting Toolhead change
  current_position=(147.00, 137.00, 14.00) : (1) Raise Z-Axis
(2) Place old tool 1
  current_position=(83.00, 137.00, 14.00) : Move X SwitchPos
  current_position=(83.00, 305.00, 14.00) : Move Y SwitchPos + Security
(3) Unlock and Place Toolhead
  current_position=(83.00, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(83.00, 220.00, 14.00) : Move back Y clear
(4) Move to new toolhead position
  current_position=(1.60, 220.00, 14.00) : Move to new toolhead X
  current_position=(1.60, 305.00, 14.00) : Move Y SwitchPos + Security
(5) Grab and lock new toolhead
  current_position=(1.60, 315.00, 14.00) : Move Y SwitchPos
echo:busy: processing
  current_position=(1.60, 220.00, 14.00) : Move back Y clear
Toolhead change done.
Offset Tool XY by { 2.00, 2.00, 2.00 }
  current_position=(3.60, 222.00, 16.00) : sync_plan_position
  destination=(147.00, 137.00, 10.00) : Move back
>>> do_blocking_move_to(147.00, 137.00, 10.00)
<<< do_blocking_move_to
echo:busy: processing
echo:busy: processing
echo:Active Extruder: 0
  current_position=(147.00, 137.00, 10.00) : AFTER
<<< T()

Offsets were set to:

M218 T0 X0.0 Y0.0 Z0.0
M218 T1 X-2.0 Y-2.0 Z-2.0

As you can see, offsets are applied to current_position but lost when moved to destination.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants