Saturday, 13 August 2022

Modifying the CNC12 PLC program to run a tool turret

With the servos, VFD etc all set up and working, it seemed like a good time to focus on cracking the controls for the turret toolchanger on the Tree. This is fairly simple - there's a single hydraulic solenoid that takes care of withdrawing the locking pawl, driving the turret off its locking "teeth" and rotating the turret (using a hydraulic motor). Once deactivated, the 2-way action of the solenoid applies reverse pressure, driving the turret backwards against the locking pawl, forcing the turret against its locking teeth and holding it there. There's also a Sanyo 8 way position switch (which appears to be a set of reed switches and a rotor-mounted magnet), which reports the current tool position.

There are several flavours of ATC catered for in the standard wizard options but none of them are exactly what I need. The closest uses 3 or 4 bit Gray code to report the position and a single output to drive the turret. Although I could arguably use a series of diodes to convert my 8-way switch outputs to Gray code, I'd rather do it in software. Otherwise it should be very close to what I require.

The PLC code is provided in the default cnct folder after installation and you are enabled / encouraged to make your own edits, then compile and test it for yourself.

Last night I made some changes to the PLC source code, as suggested by one of the Centroid staffers. This replaces the section that decodes the BCD inputs with a direct mapping of inputs from my ETHER1616 expansion board:
;==============================================================================
                               AtcGrayCode3Stage
;==============================================================================
IF TRUE THEN CurrentTurretPosition_W = 0
IF ToolTurretPosBit1 && ToolTurretPosBit2 && !ToolTurretPosBit3 THEN CurrentTurretPosition_W = 1
IF !ToolTurretPosBit1 && ToolTurretPosBit2 && !ToolTurretPosBit3 THEN CurrentTurretPosition_W = 2    ;**** Bit2
IF !ToolTurretPosBit1 && !ToolTurretPosBit2 && !ToolTurretPosBit3 THEN CurrentTurretPosition_W = 3
IF ToolTurretPosBit1 && !ToolTurretPosBit2 && !ToolTurretPosBit3 THEN CurrentTurretPosition_W = 4    ;**** Bit1
IF ToolTurretPosBit1 && !ToolTurretPosBit2 && ToolTurretPosBit3 THEN CurrentTurretPosition_W = 5
IF !ToolTurretPosBit1 && !ToolTurretPosBit2 && ToolTurretPosBit3 THEN CurrentTurretPosition_W = 6    ;**** Bit3
IF !ToolTurretPosBit1 && ToolTurretPosBit2 && ToolTurretPosBit3 THEN CurrentTurretPosition_W = 7
IF ToolTurretPosBit1 && ToolTurretPosBit2 && ToolTurretPosBit3 THEN CurrentTurretPosition_W = 8
IF TRUE THEN SV_PLC_CAROUSEL_POSITION = CurrentTurretPosition_W

With this (simpler) code:

;=========================================================================
                               ATCGrayCodeStage
;=========================================================================
; EME 2022-08-13 ATC control trials
; Input 1 on Ether1616 with A0 address = CNC12 input 33 etc
IF TRUE THEN CurrentTurretPosition_W = 0
IF INP33 THEN CurrentTurretPosition_W = 1
IF INP34 THEN CurrentTurretPosition_W = 2
IF INP35 THEN CurrentTurretPosition_W = 3
IF INP36 THEN CurrentTurretPosition_W = 4
IF INP37 THEN CurrentTurretPosition_W = 5
IF INP38 THEN CurrentTurretPosition_W = 6
IF INP39 THEN CurrentTurretPosition_W = 7
IF INP40 THEN CurrentTurretPosition_W = 8
IF TRUE THEN SV_PLC_CAROUSEL_POSITION = CurrentTurretPosition_W

Looks pretty straightforward. But obvs it wasn't clear to me if it was actually working when I tried it "dry" ie without the hydraulics running.

In the end, I went though the whole thing and deleted out everything that wasn't turret-related or specific to my turret type ("W4"). When I did that, it actually became quite understandable.

;=========================================================================
                             SetRequestedPositionStage
;=========================================================================
IF 1 == 1 THEN SET MEM1000
;=========================================================================
                             MonitorATCStage
;=========================================================================
;Stage is to Determine what ATC related stages should be enabled and disabled based
;on ATC type, Inputs selected, and ect.
;ATCType_W 0 = Manual Tool Changer
;ATCType_W 1 = Umbrella/Carousel
;ATCType_W 2 = Counter Turret
;ATCType_W 3 = Graycode 2 Output
;ATCType_W 4 = Graycode 1 Output - THIS IS THE CLOSEST TO MINE
;ATCType_W 5 = Time Based Turret
;ATCType_W 6 = Axis Based Turret
;ATCType_W 7 = Rack Based Tool Changer

;ATC Setup
IF (ATCType_W == 3) || (ATCType_W == 4) THEN RST ReportCarouselPositionStage,
SET ATCGrayCodeStage,
;Index the turret - IF THE VCP IS REQUESTING "Index TURRET"
IF SkinTurretIndex_M THEN SET TurretIndex_M, SET IndexTurretStage
; TurretIndex_M is a flag; IndexTurretStage IS A STAGE (CODE SECTION)

;Call out stage to perform tool change
IF M6 && (ATCType_W == 4) THEN SET RotateTurretStage2, RST TurretIndex_M

;=========================================================================
                               ATCGrayCodeStage
;=========================================================================
; EME 2022-08-13 ATC control trials
; Input 1 on Ether1616 with A0 address = CNC12 input 33 etc
IF TRUE THEN CurrentTurretPosition_W = 0
IF INP33 THEN CurrentTurretPosition_W = 1
IF INP34 THEN CurrentTurretPosition_W = 2
IF INP35 THEN CurrentTurretPosition_W = 3
IF INP36 THEN CurrentTurretPosition_W = 4
IF INP37 THEN CurrentTurretPosition_W = 5
IF INP38 THEN CurrentTurretPosition_W = 6
IF INP39 THEN CurrentTurretPosition_W = 7
IF INP40 THEN CurrentTurretPosition_W = 8
IF TRUE THEN SV_PLC_CAROUSEL_POSITION = CurrentTurretPosition_W

;=========================================================================
                                IndexTurretStage
;=========================================================================
IF TurretIndex_M && (CurrentTurretPosition_W == SV_MACHINE_PARAMETER_161) 
THEN RequestedTurretPosition_W = 1
; SV_MACHINE_PARAMETER_161 SHOWS THE MAX TOOL NUMBER
; IF CURRENTLY AT MAX TOOL NUMBER, THE NEXT TOOL POSITION IS #1
IF TurretIndex_M && (CurrentTurretPosition_W != SV_MACHINE_PARAMETER_161) 
THEN RequestedTurretPosition_W = CurrentTurretPosition_W +1
IF (ATCType_W == 2) || (ATCType_W == 4) THEN SET RotateTurretStage2, RST IndexTurretStage
; THE CORRECT STAGE FOR INCREMENTING TYPE 4 is RotateTurretStage2

;=========================================================================
                                HomeTurretStage
;=========================================================================
;If not at home, turn turret on
IF M18 && !TurretHomed_M THEN SET RotateToolTurret
; THIS IS ONLY REQUIRED IF CUSTOM HOMING MACRO M18 IS CALLED
;Turn timer on once home signal is triggered
IF M18 && ToolTurretSyncBit THEN SET ToolTurretOffCurrentToolTimer

;Turn motor off and assign value of 1 when timer is up
IF ToolTurretOffCurrentToolTimer THEN RST RotateToolTurret, CurrentTurretPosition_W = 1, SET TurretHomed_M

;=========================================================================
                                RotateTurretStage2
;=========================================================================
;--1 Output GrayCode Turret
;Determine the desired tool location
IF !TurretIndex_M THEN RequestedTurretPosition_W = SV_TOOL_NUMBER

;Error if Tool # is Invalid
IF RequestedTurretPosition_W > SV_MACHINE_PARAMETER_161
THEN FaultMsg_W = INVALID_TOOL_REQUEST, SET OtherFault_M

;If not at desired location start rotating the turret
IF (M6 || TurretIndex_M) && (RequestedTurretPosition_W != CurrentTurretPosition_W) 
THEN SET RotateToolTurret, SET ToolChangeTimeOutTimer, SET ToolTurretEnable

;Turn the timer on once at the desired location to go slightly past the tool location
;in order to reverse into correct tool location
IF (M6 || TurretIndex_M) && (RequestedTurretPosition_W == CurrentTurretPosition_W) 
THEN SET ToolTurretOffCurrentToolTimer 
; This is the overshoot time, to enable the turret to go slightly past the final position. 
; Uses timer T21 / Parameter #851 - default 0.75s

;Reverse turret after timer expires in order to lock into correct tool location
IF ToolTurretOffCurrentToolTimer THEN RST RotateToolTurret, SET ToolChangeComplete_M, RST ToolTurretEnable
; Uses timer T22 / Parameter #849 - default 10s

;If timer expires set fault
IF ToolChangeTimeOutTimer THEN SET SV_STOP, FaultMsg_W = TURRET_TIMEOUT_FAULT


;=========================================================================
                        MonitorIndexATCRequestStage
;=========================================================================
; I'VE NO IDEA IF THIS IS REQUIRED> LOOKS LIKE CAROUSEL / RACK ATC TO ME
IF SkinATCIndexMinus_M THEN (ATCIndexMinusPD)
IF (ATCIndexMinusPD && !DoingIndex_M) && (!SV_PROGRAM_RUNNING ||(SV_MDI_MODE && 
  SV_PROGRAM_RUNNING && !DoingM6_M)) 
  THEN SET DoingIndexMinus_M, SET DoingIndex_M, SET RequestedBinPositionStage  

IF SkinATCIndexPlus_M THEN (ATCIndexPlusPD)  
IF (ATCIndexPlusPD && !DoingIndex_M) && (!SV_PROGRAM_RUNNING ||(SV_MDI_MODE && 
  SV_PROGRAM_RUNNING && !DoingM6_M)) 
  THEN SET DoingIndexPlus_M, SET DoingIndex_M, SET RequestedBinPositionStage

IF (ATCIndexMinusPD || ATCIndexPlusPD) && M6
  THEN InfoMsg_W = MANUAL_INDEX_WHILE_ATC_MSG, RST DoingIndex_M   

IF M6 && !DoingIndex_M 
  THEN (M6PD)
; M6 is toolchange
  
IF M6 && (DoingIndexMinus_M || DoingIndexPlus_M)
  THEN RST M6, InfoMsg_W = ATC_WHILE_MANUAL_INDEX_MSG 
  
IF M6PD THEN SET DoingM6_M, SET RequestedBinPositionStage

;=========================================================================
                                TailStockStage
;=========================================================================
; MIGHT AS WELL LEAVE THIS IN, AS I'LL BE LOOKING AT THIS SOON
IF SkinTailStock_M THEN (TailStockPD)
IF (TailStockPD && !SV_PROGRAM_RUNNING && !TailStockInOut) || (M32 && SV_PROGRAM_RUNNING)
THEN SET TailStockInOut, SET Aux11LED
IF (TailStockPD && !SV_PROGRAM_RUNNING && TailStockInOut) || (!M32 && SV_PROGRAM_RUNNING)
THEN RST TailStockInOut, RST Aux11LED

;IF TailOut_T THEN RST M33, RST TailOut_T ;Reset After 15 Seconds
; M32 = tailstock in custom macro
; M33 = tailstock out custom macro

It all looks pretty reasonable with the exception of the MonitorIndexATCRequestStage bit, which I suspect isn't relevant here.

And indeed, that all seems to work. Admittedly, I haven't got the hydraulic pump running but everything else computes. If you run the PLC Detective (press Alt-E while CNC12 is running), you can see the status of the variables that are displayed as they change. So hovering the mouse over RequestedTurretPosition_W would show the currently requested tool position etc. That's pretty handy for checking what it thinks is going on.

No comments:

Post a Comment

TIG welder up and running - after some fault diagnostics and repair

Finally got some time to connect up the flow meter and argon hose. Plugged in the torch and ground cables and the torch hose etc. Powered it...