Thoughts on Multi-Tool Alignment (long)
-
@T3P3Tony said in Thoughts on Multi-Tool Alignment (long):
one question i have on the metal on metal contact is what the effect of encrusted plastic on the nozzles would be. I am told that the probing scheme you have described is used on CNC. however the end mil and contact plate are presumable more reliable as a metal on metal contact?
The Jubilee has a wiper, a silicone strip, as part of the parking stall. If we heat the nozzle (probably should anyway, for best probe accuracy) and wipe it (possibly some extra wiping), I believe this will work. Yet to be proven... I'm hopeful because I've printed with this thing a fair amount, and the nozzles are REALLY clean.
So, we'll see.
-
@timcurtis67 said in Thoughts on Multi-Tool Alignment (long):
Personally, I am waiting for conditional statements and variable storage to be added to the firmware.
This will be a big enabler. Meanwhile, for D3, we have Python (or anything else) on the Pi, and modules that can send and fetch to the Duet. I've already got all the Python interfaces working. I can issue any Gcode, including probes, and I can fetch anything that is in an M114 JSON response. Of course, variables, conditional, math, etc... it is Python!
My version of alignment will be just as it is with my sinker and wire EDM machines. A simple hole probe routine with each tool head.
- Probe back and forth in X direction, calculate center between both touch points.
- Probe back and forth in Y direction, calculate center between both touch points.
3.Re-probe back and forth in X direction, calculate center between both touch points. - Store offset in G10 for that tool.
Exactly.
Z can be probed the same way by touching off a setter block or the top corner of the probe block.
Exactly.
-
This will be a big enabler. Meanwhile, for D3, we have Python (or anything else) on the Pi, and modules that can send and fetch to the Duet. I've already got all the Python interfaces working. I can issue any Gcode, including probes, and I can fetch anything that is in an M114 JSON response. Of course, variables, conditional, math, etc... it is Python!
That sounds great! A bonus of using a Pi with the Duet3 board.
I haven't made the plunge to Duet3 yet. Still working with Duetwifi and a Duex5 expansion. I'm in the process of rebuilding my big IDEX into a jubilee type tool change printer. So aside from capturing M114 commands from the DuetWifi serial port with a Pi, I'll have to continue the wait for conditional statements to be implemented.
On my IDEX setup I do the same tool alignment manually on a touch block and it works great. Enter the offsets in G10 and away I go. I just have to keep a pad of paper and pencil handy
Lucky the offsets don't change unless I have a crash which happens from time to time....
-
I think that sensing z height could easily be done electrically by contact but x and y might be a problem because of nozzle coating. I don't know if it has been mentioned or if it goes without saying but there should be a .sys file that sets and stores all offsets for every tool.
Again not sure if feasible or not but it would be nice if the printer could identify the individual tool as in 'this is tool # 12 (or whatever)' and then the x/y/z coordinates of the .sys file are automatically applied. This implies that more tools could be set up then are actually mounted in the printer. One reason I see this as essential - I could have different nozzle sizes and different heat blocks on different tool heads. I could for example have a 0.4 mm and 0.2 mm nozzle on normal heat blocks, a 0.4 and 0.8 nozzles on a Volcano heat blocks and so on.
If electrical continuity is set up for z height, there may be implications to other functions such as not being able to measure in the center of the bed or what happens if your glass plate thickness changes.I wonder if it would make sense to break the link of bed height compensation and tool so that bed height probing happens without a tool (or a special calibration tool) and then each indidual tool head gets measured individually and an x/y/z offset from a reference position is determined.
I am just rambling here and haven't really thought about this too much but this makes sense from several perspectives.
It obviously implies that there is very minimal error due to the toolhead mounting system.
-
@jens55 said in Thoughts on Multi-Tool Alignment (long):
I think that sensing z height could easily be done electrically by contact but x and y might be a problem because of nozzle coating. I don't know if it has been mentioned or if it goes without saying but there should be a .sys file that sets and stores all offsets for every tool.
I believe that wiping will take care of this. I've printed a lot already, and the nozzles are REALLY clean. We'll see.
Again not sure if feasible or not but it would be nice if the printer could identify the individual tool as in 'this is tool # 12 (or whatever)' and then the x/y/z coordinates of the .sys file are automatically applied. This implies that more tools could be set up then are actually mounted in the printer. One reason I see this as essential - I could have different nozzle sizes and different heat blocks on different tool heads. I could for example have a 0.4 mm and 0.2 mm nozzle on normal heat blocks, a 0.4 and 0.8 nozzles on a Volcano heat blocks and so on.
This is all built into Duet/RepRap firmware already. G10 Pn Xx Yy Zz to set offsets for tool n. Auto-applied when that tool is mounted.
If electrical continuity is set up for z height, there may be implications to other functions such as not being able to measure in the center of the bed or what happens if your glass plate thickness changes.
Not for OVERALL z height, that's still the Z probe on the bottom of the carriage. Nozzle-to-touch-block-electrical is used only to calculate (not set, calculate) that individual nozzle's Z offset for that individual tool's G10 command.
It obviously implies that there is very minimal error due to the toolhead mounting system.
The Jubilee system is fully compatible with the E3D system of kinematic coupling. Both are extremely repeatable.
-
There is M675 to probe the center of a cavity. This should simplify the probing for metal on metal contact. Unlike for CNC work coordinate systems there doesn't seem to way to set tool offsets relative to the current position. So without extensions it can't currently not be for setting tool offsets. If WCS are useable in 3D printing mode each tool could probe and use a separate WCS instead of tool offsets.
-
Nice! I'd missed that one.
Given the dynamic nature of Duet configuration, several of these alternatives will work if I make the io4.in pin the endstop for that axis. The only problem with that is, I have to undefine the regular endstop... and of course I'd want to set it back after executing this process. I worry about what would happen if the process is interrupted.
I have actually considered ending the whole process with an M999. That would reliably ensure that the contents of config.g were in force.
Hmmm....
-
It might also be possible to sense the centre of the nozzle using an inductive sensor, but only if the range of the sensor is short enough for the heater block not to throw it off. Or perhaps use a vertical rod as a capacitive sensor?
-
OK, so people have been talking about sensing. Could be camera, microswitch(es), piezo, inductive, and more. I'm still going to pursue metal-metal for now.
Now let us think about G-Code vs Scripting on the Pi.
Q1: Do we believe that tool-to-tool offset could be done ENTIRELY in G-Code?
- Prior to conditional G-Code?
- With conditional G-Code?
Q2: What fundamental probing technique/command is best for this?
- G1 H3?
- M585?
- M675?
- Other?
Q3: If scripted on the Pi, what language?
- Python
- Perl
- bash (or similar)
Or all above in one generic question: SPECIFICALLY how to do this, right now?
-
The only way I think it could be done now is using M675. But for XY offset measurement, I think a capacitive sensor and special firmware support may be a better option. Two options in particular spring to mind:
- Probe above a vertical rod or above a disc on the top surface of a PCB, measuring the capacitance between the rod or disc and the nozzle. It should be a maximum when the nozzle and the rod are aligned on the same axis, unless the capacitance to the heater block is significant.
- Lower the nozzle into a cone and probe inside that.
To measure the Z offset, I favour a nozzle-contact sensor. We've already tested one type with the E3D tool changer, but it didn't work as well as we had hoped. We have another design planned.
-
Why a cone for XY? When probing X, Y has not yet been set with absolute certainty, and therefore contacting a chord of X (instead of a radius of X) would throw things off.
I'm thinking a square hole would be better. Aligned XY as best as possible. That way, when probing X, small errors in Y don't matter.
This piece has a Z touch area, and a square hole.
-
At the moment, I'm still shooting for metal to metal contact. I do like the "capacitance to rod" idea. A .5mm rod should "peak" really well with most nozzle tips. May have to look at that some more.
In fact, with regard to metal-to-metal, I have a prototype working as a Python script on the Pi. It uses the 'CodeConsole' interface over and over. Because I can't get M558/M585 style probing to work at the moment, and because it needs to probe on all three Axis, it dynamically re-configures the M574 style endstops and uses G1 H3 probes. It then has to reset the axis limit that was changed by the H3, and reset the endstop as well. To ensure that these 'reset' reconfigurations never vary from what is in config.g, the python scripts extracts the proper commands from config.g. and runs them.
The plate (photo a couple of posts up) is on a corner of the bed (for now) and is grounded. Each tool nozzle has a wire... these wires (plural) come back to a common point, where they join a single wire headed for io4.in.
The python code, in addition to being able to issue any G-Code command, can issue M408, parse the output, and retrieve the position of any axis.
It is quite nifty that Duet RRF allows dynamic reconfiguration... but... this is all very much a hack, and I look forward to doing it a different way in the future.
Anyway, it does work. I'm still seeing how consistent it is. An experimental run on one tool, with just "print" statements of the results, looks like this:
# Start of probing for Tool 0 G0('','',10,1000) # Lower bed to avoid collision with square hole plate. Gcode('T0') # Pick up Tool zero Gcode('G10 P0 Z0 X0 Y0') # Remove all offsets from Tool zero # Z Axis Gcode('M574 Z1 S1 P"!io4.in"') G0('','',10,1000) # Lower bed to avoid collision with square hole plate. G0(290,285,'',10000) # Move nozzle to spot above flat part of plate Gcode('G1 H3 Z0') toolZ = getPos()[2] # Capture the Z position at point of contact print('>>>>>>>>>> ToolZ '+str(toolZ)) G0('','',10,1000 ) # Lower bed to avoid collision with square hole plate. resetAxisLimits() Gcode('M574 Z1 S1 P"nil"') # X Axis Gcode('M574 X1 S1 P"!io4.in"') G0('','',10,1000) # Move the bed to ensure no dragging G0(290,270,'',1000) # Place the nozzle tip in center of square hole. G0('','',toolZ-1,100) # Place the nozzle tip just below surface. Gcode('G1 H3 X270') toolX = getPos()[0] # Capture the X position at point of contact print('>>>>>>>>>> ToolX '+str(toolX)) G0(290,270,'',1000) # Place the nozzle tip in center of square hole. resetAxisLimits() Gcode('M574 X1 S1 P"nil"') # Y Axis Gcode('M574 Y1 S1 P"!io4.in"') G0('','',10,1000) # Move the bed to ensure no dragging G0(290,270,'',1000) # Place the nozzle tip in center of square hole. G0('','',toolZ-1,100) # Place the nozzle tip just below surface. Gcode('G1 H3 Y250') toolY = getPos()[1] # Capture the X position at point of contact print('>>>>>>>>>> ToolY '+str(toolY)) G0(290,270,'',1000) # Place the nozzle tip in center of square hole. resetAxisLimits() Gcode('M574 Y1 S1 P"nil"') resetEndstops()
The output of the print statements from a run against a single tool:
>>>>>>>>>> ToolZ 4.962 >>>>>>>>>> ToolX 281.681 >>>>>>>>>> ToolY 260.3
-
the usual technique is:
-
probe one axis inside a circle - find the ends of the chord
-
move the axis to mid-point of the chord - now you should be on the radius of the other axis
-
probe the other axis - find the ends of the chord
-
move to the mid-point of the chord ( which should be the diameter )
-
re-probe the first axis now that you are centered in the circle
-
midpoint of the chord should be a high accuracy center point
-
-
Got it, thanks!
-
OK, switched over to M675 for XY. Works great. Doing the X, Y, X again thing... still in the square hole. I will make a round hole plate tomorrow.