Implements support for a tool magazine along side the Y-axis when calling M6 Tx in your GCode.
This script was initially created for…
- A machine with X0Y0 in the upper left corner (!)
- A static tool magazine
- … along the Y axis
- … with tools sliding out in X+ direction
- HSD ES950 spindle which has
- Sensors: Tool inside, clamp open, clamp closed
- Functions: Cone cleaning on same input as the overpressurization
Features
- Tools positioned along side Y axis in Y+ direction
- Tools sliding out in X+ direction
- Individual X/Y/Z position for each tool allows for uneven spacing
- Unlimited number of tools
- Define special tools, which will not be changed automatically
- A lot of checks in the code to detect errors and prevent damage to the machine
Inputs
Some functions can bet se to „None“ in the settings file, which will disable the check function in case you do not need it. e.g. if you have no air pressure sensor
- Air pressure sensor
- Spindle – tool in spindle sensor
- Spindle – tool clamping open sensor
- Spindle – tool clamping closed sensor
Outputs
- Spindle – open clamping
- Spindle – cone cleaning / air purge
- Spindle – air seal
- Spindle – pressurization
Installation
- Place script M6.py in your /profile/<yourmachine> folder
- Place script ___CONF.py in your /profile/<yourmachine> folder and make sure settings are adjusted to your machine. All my scripts and general settings are included here, you may also find information here which is not relevant for the M6 script described in here.
Video
This video is currently still showing my old tool change routine in Mach3! A new video will be added shortly. The general setup remained the same though.
Settings
All settings have been separatly stored in a __CONF.py file. You can find an examle for my machine in the Git repository.
Here is an overview of the settings the script is using
Tool positions
Different to most macros, this M6 script supports individual tool positions defined in X, Y and Z.
- pos_atc_z_toolget = -115.450
General Z position, if all your tools are (really!) on the same Z- position. - pos_atc_z_purge = -80
Z position at which cone cleaning / purging is activated - pos_atc_pockets = {1: [‚X‘: 100, ‚Y‘: 100, ‚Z‘: -100], 2: [‚X‘: 100, ‚Y‘: 100, ‚Z‘: -100]}
Positions of tools with X, Y, Z coordinates. Leave Z empty and fill setting pos_atc_z_toolget if you have all tools set on same Z level.
Inputs
- in_colletclosed
CSMIO input to check if collet / tool clamping is closed - in_colletopened
CSMIO input to check if collet / tool clamping is open - in_toolinside
CSMIO input to check if tool is in spindle - in_pressure
CSMIO input for pressure sensor - in_curtain_up
CSMIO input signaling that the curtain is in up position.
Outputs
- out_opencollet
CSMIO output pin to open the tool clamping / collet of the spindle - out_cleancone
CSMIO output pin to activate the spindle cone cleaning / purge function - out_curtain
CSMIO output pin to raise the dust hood / curtain for vacuum - out_vac
CSMIO output pin to activate the vacuum / suction
Positions & Feeds
- move_atc_z_safe
Z heigth for moves above the tool magazine - move_atc_z_clean
Z heigth to activate spindle cone cleaning on the way down to fetch the tool - move_atc_xslide
Distance in X direction in front of tool before starting slide-in - move_atc_safe_x
Safe X position to move in front of the tool magazine - move_atc_safe_y
Safe Y position to start from
- feed_atc_z_final = 800
Feed for Z axis when approaching tool - feed_atc_z_fast = 2500
General Z feed rate for tool change - feed_atc_xy = 2500
General XY feed rate for tool change
General configuration
- conf_tools_special = {0, 3}
Tool numbers which cannot be changed automatically (i.e. oversize tools). - conf_tools_noprobe = {0,10}
Tools which cannot be probed automatically in Z direction (i.e. planing tools, probes, etc.) - conf_pause_debounce = 0.5
Debounde before checking spindle sensors for i.e. tool in spindle. On my machine a value of 0.5s worked well.
Code
Download the most current code from Git here. I am trying to keep the repository in sync with the documentation here as much as possible, but in doubt the repository will always be more up to date.
https://github.com/AndreUeberbach/simcnc/tree/main/M6
Logic and code walk-through
The term setting refers to a varialbel in ___CONF.py and is either a value or a digial input / output port of your CSMIO controller. You find a detailed overview of all settings in the conf section, as well as in the comments of the ___CONF.py file itself.
First, the script will perform checks and abort the tool change if nescessary.
- Exit if tool is in exception list for auto-tool-change
- Exit if pressure sensor is indicating low pressure
- Exit if called tool is already in spindle
- Exit if no tool number is called
- Exit if tool number called is out of range of tools
# exit if tool is in exception list for auto-tool-change
if tool_new_id in conf_tools_special:
throwMessage(msg_tool_special, "exit")
# exit if air pressure is too low
if getPinStatus(in_pressure) == False:
throwMessage(msg_air_warning, "exit")
# exit if tool is already in spindle
if tool_old_id == tool_new_id:
throwMessage(msg_old_equal_new, "exit")
# exit on tool zero
if tool_new_id == 0:
throwMessage(msg_tool_zero, "exit")
# exit if tool is out of range
if tool_new_id > conf_tools_count:
throwMessage(msg_tool_count, "exit")
Next, a few preparatory steps are taken
- Disable softlimits
So machine can move outside the work envelope. Its good practice to place static magazines outside the work area to avoid running into them - Set the spindle to „off“
- Raise the dust boot / curtain up
(if applicable)
Setting: out_curtain - Move to defined safe Z height
Setting: move_atc_z_safe - Move Y to defined safe Y position
So we do not run into any workpieces or workholding on the way to the magazine
Setting: move_atc_safe_y - Detect if there is a tool present in the spindle
Checking the tool sensor of the spindle (if applicable)
Setting: in_toolinside
# ignore softlimits
d.ignoreAllSoftLimits(True)
# Spindle off
d.setSpindleState(SpindleState.OFF)
# Curtain up
setOutput(out_curtain, True)
# move to safe Z
machine_pos[Z] = move_atc_z_safe
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_fast)
# move to Y start position
machine_pos[Y] = move_atc_safe_y
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
Now the actual tool changing action starts. Step 1 applies if there is a tool detected in the spindle in the previous step
- Move to the tools X position + for X offset
Setting: move_atc_xslide, pos_atc_pockets
machine_pos[X] = pos_atc_pockets[tool_old_id]['X'] + move_atc_xslide
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
- Move to the tools Z position
Setting: pos_atc_pockets
machine_pos[Z] = pos_atc_pockets[tool_old_id]['Z']
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_fast)
- Slide the tool into the pocket in X- direction by moving to tool X position
Setting: pos_atc_pockets
machine_pos[X] = pos_atc_pockets[tool_old_id]['X']
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
- Open the spindle clamping
Additional waiting period to debounce before checking the sensor
Settings: out_opencollet
setOutput(out_opencollet, True)
time.sleep(conf_pause_debounce)
- Exit if collet was not opened
Setting: in_colletopened
if getPinStatus(in_colletopened) == False:
throwMessage(msg_clamp_error, "exit")
- Move to safe Z position
Setting: move_atc_z_safe
machine_pos[Z] = move_atc_z_safe
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_fast)
- Close spindle clamping
And set a message that the tool was successfully dropped off.
Setting: out_opencollet
setOutput(out_opencollet, False)
throwMessage(msg_tool_dropoff, "")
Finally we can take care of getting the tool we have called in your M6 Tx GCode
Technically this is more or less the tool-re-store move, but in reverse. Nevertheless, let’s have a look at it in full length and step by step.
- Move to X position of new tool
Setting: pos_atc_pockets, feed_atc_xy
machine_pos[X] = pos_atc_pockets[tool_new_id]['X']
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
- Move to Y position of new tool
Setting: pos_atc_pockets, feed_atc_xy
machine_pos[Y] = pos_atc_pockets[tool_new_id]['Y']
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
- Open spindle clamping
Setting: out_opencollet
setOutput(out_opencollet, True)
- Exit of spindle clamp could not be opened
Setting: in_colletopened
if getPinStatus(in_colletopened) == False:
throwMessage(msg_clamp_error, "exit")
- Move to Z height where puring / cone cleaning should be activated
Setting: pos_atc_z_purge
machine_pos[Z] = pos_atc_z_purge
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_fast)
- Activate cone cleaning
Setting: out_cleancone
setOutput(out_cleancone, True)
- Move to Z position of tool
Setting: pos_atc_pockets
machine_pos[Z] = pos_atc_pockets[tool_new_id]['Z']
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_final)
- Close clamping and deactivate cone cleaning
Setting: out_cleancone, out_opencollet
setOutput(out_cleancone, False)
setOutput(out_opencollet, False)
- Exit if clamp could not be closed
Again, we add a little break before checking the sensor to debounce it
Setting: in_colletclosed, conf_pause_debounce
time.sleep(conf_pause_debounce)
if getPinStatus(in_colletclosed) == False:
throwMessage(msg_clamp_error_close, "exit")
- Exit if tool sensor in spindle does not detect a tool
Setting: in_toolinsidece
if getPinStatus(in_toolinside) == False:
throwMessage(msg_tool_load_error, "exit")
- Slide out tool in X+ direction
Setting: pos_atc_pockets, move_atc_xslide, feed_atc_xy
machine_pos[X] = pos_atc_pockets[tool_new_id]['X'] + move_atc_xslide
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_xy)
- Move to Z safe position
Setting: move_atc_z_safe, feed_atc_z_fast
machine_pos[Z] = move_atc_z_safe
d.moveToPosition(CoordMode.Machine, machine_pos, feed_atc_z_fast)
After successfully fetching the tool we can trigger an optional tool length probing.
You can enable this with setting conf_probe_t_active. In any case I like to keep scripts tidy and separate (i.e. to work on them independently and have the option to call them separately).
- Before calling the probing, check if tool is in no-probe list
For example because tool is oversize or a special tool like a probe, which you do not want to automatically measure.
Settings: conf_tools_noprobe
# call tool length probing if enabled
if conf_probe_t_active != None:
# exit if tool is in no_probe_list
if conf_tools_noprobe[tool_new_id]:
throwMessage(msg_noprobe, "")
else:
throwMessage(msg_calling_probing, "")
# call probing
Last step: Hand over information from your script to simCNC
- We are letting simCNC know that the new tool was successfully loaded.
Settings: None
d.setToolLength (tool_new_id, tool_new_length)
d.setToolOffsetNumber(tool_new_id)
d.setSpindleToolNumber(tool_new_id)
- End the M6 script with lowering the curtain / dust hood
and sending a success message
setOutput(out_curtain, False)
throwMessage(msg_m6_end, "")
Hallo André
Sehr schön deine Zusammenstellung. Auf so etwas habe ich nur gewartet. Ich bin ein Schreiner Benutze meine Maschine Hauptsächlich zum 3d gravieren schnitzen. Bin kein IT Profi.
Wieviel Aufwand müsste ich einplanen, um dem m6 Befehl so zu ändern. Dass meine Werkzeuge entlang der X Achse liegen und in Y rausgehen?
Ist dann die Frage ob man nur ein paar Parameter ändern muss oder alles neu schreiben muss.
Gruß Marek
Hallo Marek,
vielen Dank, freut mich sehr zu lesen das die Seite hilfreich für dich ist.
Die Anpassung ist nicht viel Arbeit, im aktuellen Zustand müssten die Achsen und Bewegungsrichtungen verändert werden. Der Grundaufbau bleibt identisch.
Ich habe aktuell eine Version in Arbeit bei der man die Richtungen komplett konfigurieren kann (z.B. Entnahme in negative Richtung). Wird allerdings noch bis Anfang Juli dauern bis ich das fertig gebaut und auch getestet habe.
Grüße,
André
Hallo André
du brauchst dir wegen mir kein stress machen. Habe im Augenblick eine Chinesen Spindel im Einsatz. Bin mit der 1.8 KW ATC Spindel am liebäugeln. Dafür muss ich mir noch einen anderen Kompressor organisieren und die ganzen Ventile.
Den Wechsel von Mach3 auf Simcnc habe ich auch hinter mir. Bin sehr mit SimCNC zufrieden.
Habe noch keinen gefunden der sich so damit beschäftigt.
Deine Start und pause Funktion funktioniert auch sehr gut.
Gruß Marek
Hallo Marek,
freut mich, dass die Seite dir schon geholfen hat!
Das M6 Macro werde ich auf jeden Fall umbauen, wird dann hier erscheinen sobald es fertig ist.
Ich habe auch erst vor Kurzem mit simCNC angefangen und bin ebenfalls sehr zufrieden. Bei all den Möglichkeiten habe ich jedoch gemerkt, dass es im Netz noch nicht viele Infos zu „Standardaufgaben“ gibt.
Es gibt im Forum cncwerk.de noch zwei simCNC Enthusiasten und aus Frankreich „erwan56450“ – ebenfalls im simCNC Forum mit einem guten M6 Script unterwegs. Bei ihm werden die Werkzeuge jedoch in Z-Richtung nur abgelegt und man kann aktuell nur die Position vom 1. WZ angeben, die anderen Werkzeuge ergeben sich durch einen festen Abstand sowie die Anzahl.
Grüße,
André
Hallo André
Weiß du zufällig ob es ein m6 Script gibt, bei dem nach einem manuellen werkzeugwechsel. Das Werkzeug automatisch an einer festen Position vermessen wird?
Gruß Marek
Hallo Marek,
Ich habe bisher noch nichts dergleichen gesehen, werde aber gene etwas hier einstellen.
Für Werkzeuge die nicht im Magazin sind möchte ich bei mir ebenfalls die Option für einen manuellen WZ-Wechsel einbauen, diesen Programmteil kannst du dann auch einzeln nutzen.
Idee:
Manualle Wechsel-Position anfahren, warten bis bestätigt, dann WZ vermessen und weiter im GCode.
Grüße,
André
Hallo André
Deine Idee hört sich schon gut an.
Mein m6 fragt ab welches Werkzeug eingelegt ist laut Werkzeug Datenbank. Wenn ein Werkzeugwechsel statt gefunden hat muss ich es bestätigen. Erst dan fährt sie los ohne zu messen.
Gruß Marek
Hallo Marek, es gibt ein M6 Makro für manuellen Werkzeugwechsel. Das nutze ich. Bei M6 stoppt das Programm-> dann wechselt man manuell das WKZ, quittiert mit okay und der das WKZ wird an einer angegebenen Koordinate(wo sich der Werkzeuglängensensor befindet;-)) vermessen und das Programm geht weiter.
Hallo André,
vielen Dank für die detaillierten Erklärungen. Die Seite ist wirklich hilfreich!
Was ich mich noch frage: Gibt es eine Möglichkeit, die Bewegungen der Maschine irgendwie sanfter zu machen? Also ein niedrigeres Beschleunigungslimit zu setzen? Der Werkzeugwechsel funktioniert jetzt zwar bei mir, ist aber noch sehr ruckartig. Eleganter wäre das natürlich, wenn die Maschine sanft beschleunigt und dann zu den entsprechenden Positionen fährt und vor dem Erreichen auch wieder sanft abbremst.
Viele Grüße
Felix
Hi Felix,
pardon für die späte Antwort, irgendwie bekomme ich keine Meldung über neue Kommentare…
Was du meinst ist die Beschleunigungsrampe, die lässt sich bei den Antriebseinstellungen setzen (mm/s^2). Außerdem lässt sich über den Wert „Jerk“ die Geschwindigkeit des Richtungswechsels einstellen. Aus beiden Werten errechnet simCNC dann eine S-Kurve und mit den richtigen Einstellungen bekommst du eine sehr ruhige Bewegung.
Viele Grüße,
André