Linuxcnc Hal Component to implement ATC for a EMCO Turn120 / Compact6 CNC lathe This is a direct interface, where Linuxcnc reads the opto sensor board and controls the toolturret motor, 6pins on the parallelport are used (4opto sensors, motor direction, motor enable) Once the correct tool position has been reached, the motor is reversed and pulse width modulated to hold around 0.8 Amp. Thanks to ArcEye (schooner30@tiscali.co.uk) who wrote the origional component for a Denford Orac Lathe and cncbasher who tested and helped develop it http://wiki.linuxcnc.org/cgi-bin/wiki.pl?ContributedComponents#Denford_Orac_Lathe_ATC_toolchanger_component I only modified their work to suit the emco lathe. Instructions: in the terminal run: sudo apt-get install emc2-dev sudo apt-get install build-essential Extract the emcochanger component from this text file and place it in a file named emcochanger.comp , copy this to you config file. cd/linuxcnc/configs/ "your lathe name" / install the component with: sudo comp --install emcochanger.comp Extract the hal component and add it to your .hal file. Hardware Notes: The EMCO opto sensor board runs on 24VDC, I used a voltage divider with R1=10k & R2=2.2k to drop the voltage before connecting to the parallel port. Pinout: brown -> 24V green -> GND blue -> opto 1 pink -> 2 yellow -> 3 gray -> 4 on the motor output side I used an H-Bridge IC, and a 2222 transistor to switch form motor direction to In1 & In2 of the H-bridge. *******************************hal component****************************************** loadrt emcochanger addf emcochanger servo-thread net tool-change iocontrol.0.tool-change => emcochanger.toolchange net tool-changed iocontrol.0.tool-changed <= emcochanger.toolchanged net tool-number iocontrol.0.tool-prep-number => emcochanger.toolnumber net tool-oldnumber iocontrol.0.tool-number => emcochanger.currenttoolnumber net tool-prepare-loopback iocontrol.0.tool-prepare => iocontrol.0.tool-prepared net sig1 emcochanger.opto1 <= parport.0.pin-11-in net sig2 emcochanger.opto2 <= parport.0.pin-12-in net sig-forward emcochanger.forward => parport.0.pin-08-out net xhomed axis.0.homed => emcochanger.ishomedX net zhomed axis.2.homed => emcochanger.ishomedZ ********************************* emcochanger component*********************************** component emcochanger "This component controls the EMCO Lathe Auto Tool Changer. M6 calls this"; pin in bit toolchange "Receives signal from M6 that tool change required"; pin in s32 toolnumber "Receives Tx data from M6 (tool number requested) Only allows 1-8"; pin in s32 currenttoolnumber "Receives old tool number"; pin out bit toolchanged = false "Sends signal when tool change finished"; pin in bit opto1 = false "State of opto sensor 1"; pin in bit opto2 = false "State of opto sensor 2"; pin out bit forward = false "Direction signal"; pin in bit ishomedX = false "Status of X axis homing"; pin in bit ishomedZ = false "Status of Z axis homing"; pin out s32 position = 0 "Initialised as a pin for debugging so we can check where it thinks it is"; param rw float times = 500 "Number of polls of progress_levels 1 & 3 before beginning next move - gives delay for relays"; // Internal and debugging stuff pin out s32 progress_level = 0; // tracks the progress of the toolchange, just here so it can be read easily param rw s32 tnumber = 0; // Internal toolnumber to allow overrun of quadrant by 1 then reverse back onto it variable float sleeptime = 0; // our own timer to set delay between progress levels 1 and 2 option singleton yes; // makes no sense to have more than one of these components running - only one ATC function _; author "ArcEye schooner30@tiscali.co.uk"; license "GPL"; ;; int oldtool = currenttoolnumber int tool = toolnumber int newtool = tool int maxtool = 6 int curpos = oldtool int steps = 0 int counter = 0 int sleeptime = 5 FUNCTION(_) { While (newtool > maxtool) { rtapi_print_msg(RTAPI_MSG_ERR, "Invalid tool number, only upto 6 tools"); break; } If (newtool == oldtool) && (newtool > 0) { break; } If (oldtool == 0) { forward = true; While (!opto2) { } curpos = 1; tnumber = curpos; } If (curpos == newtool) { tnumber = newtool; forward = false; delaystart = true; toolchanged = true; break; } If (newtool > curpos) { steps = newtool - curpos; } Else { steps = maxtool - curpos + newtool; } forward = true; countpulses: While (!opto1) { } counter = counter + 1; While (opto1) { } If (counter == steps) { forward = false; tnumber = newtool; delaystart = true; toolchanged = true; break; } goto countpulses; }