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

Final assembly and test of the spindle nose adaptor - RESULT!!

After the recent distraction caused by the 3D scanner, resurrecting the 3D printer and buggering about with the throttle bodies for my Honda...