16 Pocket tool changer with PB and carousel.comp (Working config for reference)

31 May 2023 07:11 #272540 by GuiHue
Hi everyone,

I have spend the last week to finally get my tool changer going. I had build the mechanics at some point last year, but only now got to play with the software implementation.
I went the route of using probe_basic for the UI and Andypughs carousel.comp (most recent version @ master from late May 223) to control the carousel.
16 Pockets for ISO20, forks mounted to large aluminium disk mounted to an 1:80 reduction harmonic drive gearbox. The carousel is driven by a clsoed loop stepper motor auf Nema23 size through a 1:1 belt drive. Three sensors are used:
1 1xInductive sensor against a target on the disk for homing
2 1xInductive sensor for pockets against a target per pocket (targets are M6 SHCS mounted to the disk in cnc milled locations)
3 1x Optical Diffuse Reflection sensor ("laser") to check if a pocket is actually empty

Operation is done in index mode with forward and backward motion enabled. AlignDC is set low, to reliably hit the pocket. After roughly 100 M6 through various pockets I have not encountered any problems.

Probe Basic Integration: Honestly, too much to quickly type up. Main elements are described in the bullets below:
  • I have replaced most of the macros and added various additional ones. All carousel logic is handled by carousel.comp, Direction of rotation and number of steps is also determined within the macros but only for the purpose of moving the animation in the right direction.
  • Key pins of carousel.comp and the spindle are linked into custom m_codes (see folder m_codes in link below)
  • Mcode wrappers are used to bundle key functions such as release tool and check drawbar state into a single command to clean up the code
  • UI has been modified to adjust to my specific needs including debugging. Since my carousel is openly accessible by the operator, I have added some macro functions which required UI interaction.
    • Force empty carousel: Macro to reset all pockets and the animation to zero values
    • Check carousel: Macro to run through each pocket and check if a tool is physically present (sensor 3) and remove all entries where there should be a tool (according to numbered variables) but none could be found
    • Manually enter tool to pocket: Macro to receive tool and pocket from the ui to directly write that information into carousel control (without physically moving anything)
    • Manually remove tool from pocket: Macro to clear a specific pocket from tool information
  • General ATC process: atc_toolchange.ngc works as a master document doing the following
    • Distinguish between tools in the carousel and those outside, specific handling of probe (must not be in atc for me)
    • Puts tools back to where they came from - this is used to ensure that some tools are not being put back into the carousel although they were manually put into the machine (I have some tools that are too long/ too heavy) for the carousel)
    • Check if current tool in spindle is: 0, from the carousel or not from the carousel and perform actions accordingly (do nothing, drop into original pocket at atc, drop off at manual tool change location)
    • Check for the new tool: Is 0, is from carousel, not from carousel and perform accordingly
    • General assumptiona:
      • Tools in the carousel have received tool lenght measurement and have a correctly determined offset
      • Tools manually changed in during M6 are considered unknown and forced to do tool lenght measurement
    • Tools can be put into and removed from the carousel using UI interaction and physical operation of the machine. These are assumed to be known, i.e. the tool length offset has previously been determined 
Video of a sequence of M6 here:
Automatic Tool Change with carousel.comp and probe_basic in LinuxCNC 2.9 - YouTube

The whole configuration can be viewed here:
GuiHue/kondor: Repository for all things related to the control system of my Kondor CNC router (github.com)
Note that the modified probe_basic.ui file is also a part of the repository and needs to be placed whereever your ui file usually is located.
@devs: I'll be happy to clean this up and provide an example for the official repo

Many thanks to the wonderful developers of the various bits used. Specifically andypugh for carousel.comp and the qtpyvcp team (turboss for helping out on the discord).
The following user(s) said Thank You: TurBoss, tommylight, pommen, besriworld, anfänger, spumco

Please Log in or Create an account to join the conversation.

31 May 2023 11:38 - 31 May 2023 12:35 #272550 by spumco
Well done!

Couple of questions... are your UI files/mods available anwhere?

Do you have a carousel jog function?  i.e. a way to manually rotate the carousel one pocket and have PB update the current position and screen widget?
I'm asking because I'm also using carousel.comp and I've not been able to get carousel's internal jog function to work.  I think Andy Pugh is working on this, but it could certainly be something I've done wrong.

EDIT - missed the .ui in the repo
Last edit: 31 May 2023 12:35 by spumco.

Please Log in or Create an account to join the conversation.

31 May 2023 13:00 #272557 by spumco
Ok, had a dig in your config and I see you're using carousel's 'index' mode, plus M111/M112 to jog the carousel and screen widget.

I'm guessing my jog issue is related to the fact that I'm using 'counts' mode.

Please Log in or Create an account to join the conversation.

31 May 2023 13:17 - 31 May 2023 13:18 #272561 by GuiHue
I have not tried counts mode, as I was able to adjust things easily by working on the position of the sensors once. All jogging, which is implemented, is based on the index mode. This appears to be flawless.

Edit: In case contact is needed, you can find me @Guido on the LinuxCNC Discord - usually watching #general and #qtpyvcp
Last edit: 31 May 2023 13:18 by GuiHue.
The following user(s) said Thank You: spumco

Please Log in or Create an account to join the conversation.

31 May 2023 16:26 #272587 by spumco
The more I dig in to your ATC scheme, the more I'm impressed.  My own PB-carousel config looks amateurish in comparison.

Subtle things you did - like having the screen widget movements in a separate M-code - make the workflow more intuitive than mine.

I'm seriously considering porting your config to my setup and testing it out.

What laser sensor did you use for tool detection?  I'm far from expert in sensors... I've found a few reasonably-priced diffuse sensors (Automation Direct) but don't know if they'd be suitable.

On a similar topic, I should really get a sensor (laser) for my power draw bar.  I have air cylinder up/down sensors, but nothing to detect that the l PDB itself is in the right position... and BT30 tools are capable of being half-grabbed but not seated in the taper.  Any thoughts on this?

Please Log in or Create an account to join the conversation.

31 May 2023 18:43 #272596 by GuiHue
Hi spumco, thank you for your kind words. I have not been super consistent with the implementation. I should refactor by using even more subs. Especially the calculation of the animation is not fully externalized. I need to play with handling variables between macros some more.

The laser sensor is of ali express OMCH M12 Laser diffuse something. Cannot copy the link anymore because it cannot be shipped to Germany at the moment, and it won't show me the page. To find out if a sensor is suitable: Ensure that you can electrically connect it (i.e. Voltage, NPN/PNP (I use 24V, NPN but connected as PNP with the help of a resistor) and make sure that its useful range applies to your application. Do note that diffuse sensors do not require a reflector or receiver, which is beneficial in this application. However, they are also less stable.

My spindle has two inductive sensors: 1) drawbar position (high if the drawbar is open) 2) tool presence (high if there is a tool in the spindle). Inductive should work nicely in a spindle, as they can be reasonably compact, and setup is easy. I have not opened the spindle, but I suspect that there are features on the actual drawbar that trigger the sensor internally. Would not want to this without!
The following user(s) said Thank You: spumco

Please Log in or Create an account to join the conversation.

01 Jun 2023 02:13 #272622 by spumco
Well, I'm now educated... I thought those sensors were expensive, but $8 from Amazon was too good to pass up.

Thanks for the tips.  Once the sensor gets here I'll hook it up and start playing with your config.


Please Log in or Create an account to join the conversation.

16 Jun 2023 20:36 #273716 by Lcvette
I am curious on the carousel comp on how it physically wants the motor connected, does it have to use an axis output or is it using gpio pins?

Please Log in or Create an account to join the conversation.

17 Jun 2023 17:43 #273746 by spumco

Carousel doesn't create a joint or axis in the normal sense.  It might help to think of a carousel-controlled motor as a rotary axis outside the normal framework, which is commandable via gcode (using motion.analog-out and digital-in/out), but which is not synchronized to the other axes.

If using carousel in counts mode, it is physically connected like a step/dir axis.
If using one of the other modes, it uses gpio to turn on/off a 'dumb' motor.  Your 3-phase induction motor with relays (or digital IO to the vfd) would be an example of using a non-counts mode.

For a 'counts' (stepgen) version of carousel my basic architecture looks like this:
  • stepgen physical pins connected to Mesa step/dir output
    • could be parallel port, or other pins fast enough for your particular system
  • stepgen (software or Mesa in my case) set up in hal
    • Usual stepgen settings in INI file (scale, accel, velocities, type) like an axis
  • stepgen input connected to carousel output
    • stepgen.N.counts <= carousel.N.counts
    • stepgen.N.position-command <= carousel.N.counts-target
  • desired pocket number command via gcode
    • carousel.N.pocket-number <= motion.analog-out-NN
  • carousel position, homing, and other feedback connected via gpio
    • Counts mode only requires a single index pin - no per-pocket sensor required
For one of the other carousel modes (grey, binary, bcd, etc) the ATC requires an encoder of some sort depending on the mode selected.
  • Encoder can be complicated or simple
    • "Index" mode requires a home (index) sensor as well as a per-pocket sensor
    • I've seen at least one example on the forum of a BCD encoder which uses four proxys and a four-track series of holes drilled in the ATC platter to create an absolute encoder for carousel
  • Carousel uses the encoder feedback to turn on/off gpio outputs to the motor at the appropriate time
  • Fine alignment, both for homing or pocket-to-spindle, can be adjusted in carousel settings
    • carousel.N.home-offset
    • carousel.N.align-dc (and other related settings)

Beyond that, commanding carousel is virtually identical to what you cooked up in Probe Basic... except the M10/M11/M12 subroutines are no longer necessary.  Instead of doing the destination pocket math in the subroutine, carousel handles distant & shortest-path and reports back to LCNC (via carousel.N.current-position) when the target position is reached.

In my config, I connect the "P" parameter (passed to M10) to carousel instead of passing it on to M11/M12.
;***Rotate ATC***
M68 E0 Q#<P>                            ; Set carousel destination pocket
M64 P0                                  ; Rotate carousel to selected-pocket
G4 P0.5                                 ; Pause required before M66 check
M66 P0 L3 Q10                           ; Wait for carousel finished
                                        ; Stop motor
O120 if [#5399 LT 0]
    (abort, failed to align carousel)
O120 endif
M65 P0

So all the math & motor enable/disable is done inside carousel.

Does this help?
The following user(s) said Thank You: TurBoss

Please Log in or Create an account to join the conversation.

17 Jun 2023 17:47 #273747 by spumco
clarification for above:

M68 E0 - motion.digital-out (carousel destination pocket number)
M64 P0 - carousel enable
M66 P0 - carousel.N.ready (in position)
M65 P0 - carousel disable

Please Log in or Create an account to join the conversation.

Moderators: KCJLcvette
Time to create page: 0.228 seconds
Powered by Kunena Forum