Tool Length Setter

I’ve been struggling to get the tool length setter up and operational.

Ive Read tons of posts here as well as researched it online, So I’m hoping someone else has gon down this path and has a solution.

if you review the information on the FLuidNC wiki there is a section that specifically suggests the behavior I want:

Specifically this section:

spindle/atc: atc_manual

“This uses a human to change the tool, but it uses an electronic tool setter to automate the setting of the tool length offset (TLO) so the Z axis only needs to be zeroed on the work once. Ideally the tool setter has some over travel, so you can safely probe faster.”

I’ve added the config to config.yaml

atc_manual:
safe_z_mpos_mm: -1.000000
probe_seek_rate_mm_per_min: 400.000000
probe_feed_rate_mm_per_min: 80.000000
change_mpos_mm: 80.000 0.000 -1.000
ets_mpos_mm: 5.000 -17.000 -40.000
ets_rapid_z_mpos_mm: -25.000000

but the M6 commands are ignored in Fluid.

On a typical job I’ll have 4-5 tool changes and on occasion, I almost forget to “re-Zero” the working “Z” height.

I’m thinking If I can zero “Z” once then after each manual tool change run a tool length sequence to make the necessary tool length offset then I’d only have to zero Z on the material once.

anyway any help would be greatly appreciated.

1 Like

Hi. I really dont use the tool changer options/modes.

I have found more easly to run multiple gcodes per bit/operations and perform manual changes for the bits/file.
-i use a bitsetter, so all my bits are at the same height in the z axis (i cut mostly 4-6mm sheets)
-i use a safe z height of 20mm in all my machines (that way the one that have the floating z axis works with the vbits correctly) i use the same pc/software to generate all the gcodes and that way i avoided messing with the machine settings

There you can see what im talking about.

Regarding the z height: its only measured for one of the bits at the beginning

1 Like

Did you setup the M6 macro and define it in the config.yaml under atc_manual? I recently got M6 commands setup on my pen plotter for pen changes. I’m not quite sure what the macro needs to do here.

Also, M6 commands are ignored if the tool number didn’t change.

The example code on the FluidNC Wiki has nothing shown for the m6 Macro

So when you enter the m6 command does it “only” run a macro or does M6 have it’s own internal to Fluid operations.

This is the code snippet from the FluidNC Wiki that was not working

PWM:
pwm_hz: 5000

atc: atc_manual
m6_macro:

I tried to include this in the config.yaml file but Fluid gave an error and said I did not define a pin

It’s my understanding that PWM is for a communications line between Fluid and the Spindle Controller

In my case I am not doing that I’m controlling the spindle speed manually and on of manually on the spindle controller. I’m not including code in my g-code files to turn the spindle on / off or control spindle speed.

So, as far as Fluid is concerned, it has no idea if I’m using a spindle or a router.

I just want to measure the tools loaded in the spindle and have a tool length offset set automatically so z-0 for the end mill and z-0 for the v-bit are the same and no matter which bit I put in the spindle after the tool length operation it goes back to the top of the workpiece regardless of how long the bit is.

I’m gathering that in order for the m6 command to work there must be an m6 macro defined that it calls and runs is that correct?

reading the wiki closer I think the problem is not having an m6 macro defined and written to tell Fluid what to do when the M6 command is invoked:

Details

M6 Macro

An m6_macro: can be used with any spindle type. It will run if it is defined and the spindle does not have an ATC config item. Read more about macros here.

You must set the current tool number with M61Q in your macro. This allows you to decide if the tool change was successful. In most cases you will want to set an alarm and exit the macro if there is a problem. Use $Send/Alarm=3 (Abort during cycle)

Gcode behavior

  • M61 Q Used to set the tool number already installed. Typically done at startup if the tool number is not right.
    • Sets the current tool.
    • Macro is not run
    • This will change the spindle if Q<tool_num> is in the range of another spindle
  • T
    • Preselects the tool. Nothing happens until an M6 comes.
    • Macro is not run

**M6

    • Runs the macro*

^^^It can’t run a macro that is not there!!!^^^ DOH!

  • M6 T to T
    • Does nothing
  • M6 T<outside current spindle tool range>
    • Changes spindle and uses new spindles ATC config.

That is my understanding.

My m6 macro is on a BESC “spindle” which is just a servo that holds the pen in place. I would imagine I could have made that work with atc_manual.

This is what I’m doing:

1 Like

Now what PIN number do I use for PWM since I’m not actually connecting the Jackpot to the Spindle Controller.

Should I use the GPIO pin number of the tool setter GPIO 39

Or pick some “unused” pin that is not connected to anything.?

-or- can I just define where the M6 Macro is outside or the PWM section?

I’ll need to tackle this in the morning after coffee. Late Night coding and fast spinning blades on robots are not a good combination!

1 Like

Reading the wiki some more, it doesn’t seem like you should need M6 macros. I’m not sure. Sorry if I led you astray.

1 Like
  • M61Q
    • Sets the current tool
    • If there was a previous tool number it resets the TLO to 0.0

^^^ this works ^^^

I can enter m61q1 (enter) in the console

then with $G I get a readout that shows me that the tool number is 1

If I enter m61q2

tool number changes to 2

So Fluid is recognizing the M6 command in this instance.

1 Like

That’s what I thought…

Generically the macro is just “pre-typed”_ commands that Fluid will execute…

So in theory typing those same commands in the console will have the same results.

“in theory”

The thing about the tool length setter is storing the current relationship between workspace Z-0 and machine Space z-height at that workspace z-0

then calculating the “offset” distance between bit lengths and automatically adjusting workspace z-0 by the difference so the te tip of bit 1 and the tip of bit 2 “different lengths” will go to the same z-0 position.

So it’s more involved then just sending the machine to certain machine positions. there is a calculation that must be made for that tool length difference and an adjustment to g54 settings

I’m going to try these G-Sender macros then see if I can create FluidNC Macros based on these if it works in G-Sender.

What I’m hoping for is to have the macros loaded in the Fluid Dial so I can execute tool length setting from the Fluid Dial which is my preferred tool to jog and move the spindle about as well as my preferred method for loading and running g-code files.

In general other than uploading the g-code files to the SD card using the FluidNC web interface I never need to have the computer connected to the Jackpot up and running I can just turnon the jackpot and go about running the machine.

I think that sounds reasonable.

So, is this way this is supposed to work?

  • Initially probe with a touch plate
  • When you change tools for the first time, get the offset of the original tool.
  • Switch to the next tool
  • Get the new offset and update Z for that offset.

For my own curiosity, what tool length probe are you using and how do you have it connected to the Jackpot?

Yes, that’s the “proposed” workflow.

Technically, I could use the touch probe after each tool change to accomplish the same thing. Still, there are occasions when the material surface that was there at first is gone because of machining, and there is no way to use a touch probe or find the original top of the material. This is when a separate and fixed location tool setter is useful.

https://www.amazon.com/RATTMMOTOR-Automatic-Normally-Setting-Engraving/dp/B08LK93NTC?ref_=ast_sto_dp

You have to get a normally open type.

I only wired the positive and negative to GPIO 39 the sensor has an over run switch if the head is depressed too far which you can wire to an e-stop

Additionally you could add a step after the tool length sensor finishes to send the spindle bck to work x0,y0 so the machine is ready to start the next job.

I’d likely double and triple check that the z-offset was correct for the first several jobs. no one wants to drive an endmill through the workpiece ruining the job.

Using a set of Macros for G-Sender I was able to get the workflow I wanted:

See this Video for them in use:

video

1 Like

Now the real challenge is to convert or re-write these macros for G-Sender into Macros that FluidNC understands

are there any programmers here who know the ins-and outs of converting from: “Javascript” to “LinuxCNC”

Advanced Macros

gSenders Macro architecture is based on JavaScript and uses the Esprima library (https://esprima.org/) and so will theoretically support any code that it does. This is exciting because Macros can move far past basic variables if you’d like to perform advanced functions on your CNC:

G-Sender Macro

to:

http://wiki.fluidnc.com/en/features/gcode_parameters_expressions

Parameters and expressions allow you to use gocde as a programming language. It has a lot of limitations, but should be able to allow you to create more powerful macros and things like simple tool changers. It is based on LinuxCNC and NIST RS274NGC

Are you using these specifically as is?

This doesn’t look bad at all to convert. It might use JavaScript behind the scenes but it’s mostly just using variables. It does seem to have some features that FluidNC doesn’t have but nothing that doesn’t have an alternative.

I’ve messed with this FluidNC gcode parameters and expressions quite a bit. I don’t think you need to be a programmer.

I can help convert this if once you confirm the exact scripts you are using. It’s also possible to create a macro to automatically do that X/Y/Z probing. It might take a few passes.

Looking at the initial script, here are some pointers on what converting means:

; Wait until the planner queue is empty
%wait

FluidNC doesn’t have an equivalent here. If really necessary (I don’t think it is), we could put a pause (M0) or a dwell (G4) instead.

; Set user-defined variables

%global.state.SAFE_HEIGHT = -10 ; clear everything height(negative number, distance below Z limit)

In FluidNC, to have a global variable (meaning you can still use it after the macro is complete), you just need to prefix the variable name with an “_”. This would translate to:

#<_SAFE_HEIGHT>=-10

When you need to use that defined variable, you just need to reference that variable similar to what the gsender macro is doing, So, this:

G53 Z[global.state.SAFE_HEIGHT]

becomes this:

G53 Z[#<_SAFE_HEIGHT>]

You don’t necessarily need the brackets so this works as well:

G53 Z#<_SAFE_HEIGHT>
; Keep a backup of current work position
%X0=posx, Y0=posy, Z0=posz

These are local variables (so they don’t need the _ prefix) storing the current location to restore to later. This should be the equivalent. Note that the _x, _y, _z are system defined named global parameters. These are specifically the “current work coordinates with all offset applied”.

#<X0>=#<_x>
#<Y0>=#<_y>
#<Z->=#<_z>
; Save modal state
%WCS = modal.wcs
%PLANE = modal.plane
%UNITS = modal.units

These again are local variables that we need to store from named global variables. There are some differences here that might need a bit of investigation. For example, I’m assuming that modal.units is “G20” or “G21”. FluidNC has _metric and _imperial. So, I’m assuming if it’s in metric, _metric has a value of 1 and _imperial has a value of 0. We would need to translate that with an if statement. Also, FluidNC only stores numeric values in variables. So, the _coord_system is going to return 54 and not G54.

; Save modal state
#<WCS>=#<_coord_system>
#<PLANE>=#<_plane>
#<UNITS>=21
o100 if[#<_imperial> EQ 1]
  #<UNITS>=20
o100 endif
[WCS] [PLANE] [UNITS] [DISTANCE] [FEEDRATE] [SPINDLE] [COOLANT]

When it restores the values at the end, it will need to add the letter prefix, so for the first 3:

G[#<WCS>] G[#<PLANE>] G[#<UNITS>]

I have not tested any of this but wanted to give you an idea. Understanding the gcode is probably more difficult than the “programming” part.