Hello Guest it is April 27, 2024, 07:21:27 AM

Author Topic: Mach4: Need help with a macro for lathe turret.  (Read 2211 times)

0 Members and 1 Guest are viewing this topic.

Mach4: Need help with a macro for lathe turret.
« on: November 27, 2021, 12:52:15 PM »
I have been converting an Emco 242 lathe to mach4 control. I have everything done but this pesky Turret. I put it off until last, knowing it was going to be my biggest headache. I've searched google and other forums the last couple of days for a Lua M6 macro that would work with this 8 POS turret. Came up empty handed.  I'm not confident enough in my coding skills to write it from scratch. Hoping someone can point me in the right direction or lend a hand in coding this thing. I did find a post on LinuxCNC for the "duplo.comp" file but it's in a different language. I will post it below, this seems to be the same turret as what I have (duplomatic BSV-N 160)  and would work if someone could help me translate it to lua. Also found a post from Graham Waterworth for an emco turret macro but it seems to be for a smaller turret with a lot less going on as far as sensors and brakes. I can also post it if someone thinks it would be helpful.

A lot of people seem to be running PLC's for their turrets. I believe i have enough I/O to run it without one unless there are other benefits that people are using them.

As far as control hardware. I have a SmoothStepper with a c82 board from cnc4pc so everything is 24V making it easier to convert this machine as the sensors and contactors are 24V for the most part. Servos on X and Z. 10hp spindle run off a VFD. Original Encoder on the spindle.

The turret is ran off a 3phase motor, with a brake(24V) . Absolute 4bit encoder, 24V lock, indexing proximity switch, and a Proximity sensor to ensure the turret is locked after tool change.

If there is anymore information needed I have all the documentation on the turret as well. Thanks for taking the time to look at this post.

installation dans hall:
loadusr -W duplo8
net tool-change            iocontrol.0.tool-change      => duplo_us.toolchange
net tool-changed           iocontrol.0.tool-changed     <= duplo-us.toolchanged
net tool-number            iocontrol.0.tool-prep-number => duplo_us.toolnumber
net tool-prepare-loopback  iocontrol.0.tool-prepare     => iocontrol.0.tool-prepared
net                                                     <= duplo_us.codB0
net                                                     <= duplo_us.codB1
net                                                     <= duplo_us.codB2
net                                                     <= duplo_us.codB3
*****************************************************************************************/
component duplo8    " composant control changeur d'outils duplomatic ";
option userspace yes;
pin in  bit codB# [4] ;            /* table codB (0) to codB (3) of the absolute position encoder  */       
pin in  bit codparity ;            /*position encoder parity control input*/
pin out bit parity-error;          /* output indicates a parity error */
pin in  bit strobe ;               /* position encoder strerobe */
pin in  bit toolchange ;           /* signal input via M6: tool change request */
pin out bit toolchanged = 1 ;      /*tool changed signal output */
pin in  s32 newtoolnumber ;        /* signal input via M6: tool number from 1 to 8 */
pin out s32 currentduplonumber ;   /* current tool number signal output 1 to 8 */
pin out bit motorCW = 0 ;          /* clockwise motor control */
pin out bit motorCCW = 0 ;         /* anti-clockwise motor control */
pin out bit brake = 1 ;            /* false brake control released */
pin out bit indexingSolenoid = 0 ; /*electro indexer control */
pin in  bit indexingSwitch ;       /* input switch indexer */           
pin in  bit lockingSwitch ;        /* input switch locking indexer */ 
pin out s32 state = 0;
license "GPL";
;;
 
#include <unistd.h>
#include <stdio.h>    /* Standard input/output definitions */
#include <stdlib.h>
#include <stdint.h>   /* Standard types */
#include <time.h>
// variable int state = 0;  /* different sequences of the tool changer for the instruction switch  */
         
    int p = 0;  // current reading of encoder, transient if strobe not set
    int pcalc = 0;
    int i, start, beforenewpos;
    int sensCW = 0;
    int sensCCW = 0;
    int courseCW = 0;
    int courseCCW = 0;
// timerT1 = 0.05   50e3;
    // timerT2 = 0.2   200e3;
void user_mainloop(void) {
    while (1) {
        FOR_ALL_INSTS() {
            for (i = 0; i < 4 ; i++) {
                p += codB(i) << i;  /* binary decimal conversion */
                pcalc ^= codB(i);   /* calculation of the parity pcalc = 1 if odd */
            }
if (strobe) {
              currentduplonumber = p;
              p = 0;
              parity_error = ( pcalc ^= codparity );
            }
switch (state) {
                case 0: /*stable on the pending currentduplonumber ... if request change  state = 1 */
                   
   // Check if tool change is indicated and calculate number of steps and direction
                    brake = 1;
                    if (toolchange) {
                        if (( currentduplonumber != newtoolnumber ) && ( newtoolnumber != 0)){
                            toolchanged = 0;
                            brake = 0;
                            state = 1;
                            // check how many steps are needed if rotate CW
                            start = currentduplonumber;
                            courseCW = 0;
                            while ( start != newtoolnumber ) {
                                start += 1;
                                courseCW += 1;
                                if( start == 9) {
                                    start = 1;
                                }
                            }
                            // check how many steps are needed if rotate CCW
                            start = currentduplonumber;
                            courseCCW = 0;
                            while ( start != newtoolnumber ) {
                                start += -1;
                                courseCCW += 1;
                                if( start == 0 ) {
                                    start = 8;
                                }
                            }
                            // Determine which direction to turn
                            if ( courseCW <= courseCCW ) {  /*the route 1 2 3 is the shortest or equivalent direction CW */
                                // rotate CW
                                sensCW = 1;
                                sensCCW = 0;
                                if ( newtoolnumber == 0 ) {
                                    beforenewpos = 8;
                                }
                                else {
                                    (beforenewpos = (newtoolnumber));
                                }
                            }
                            else {
                                // rotate CCW
                                sensCW = 0 ;
                                sensCCW = 1 ;
                                if ( newtoolnumber == 9 ) {
                                    beforenewpos = 1 ;
                                }
                                else {
                                    (beforenewpos = (newtoolnumber));
                                }
                            }
                        }
                    }
                    else {
                        toolchanged = 0;
                    }
                    break;
                case 1:  /*   comparison with new position, determination of direction of rotation and previous position cw rotation activated and brake release or ccw rotation activated and brake release rotates to the position preceding the target position*/
                    // Start spinning...
                    if ( currentduplonumber != beforenewpos ) {
                        motorCW = sensCW ;
                        motorCCW = sensCCW ;
                        indexingSolenoid = 0 ;
                        for (i = 0; i < 4 ; i++) {
                            p += codB(i) << i; /*  */
                            pcalc ^= codB(i); /* calculation of the parity pcalc = 1 if odd */
                        }
                        if (strobe) {
                            currentduplonumber = p;
                            p = 0;
                            parity_error = (pcalc ^= codparity );
                        }
                    }
                    else { /*case of the previous position already reached */
                        // Target position reached, go to next step
                        motorCW = sensCW;
                        motorCCW = sensCCW;
                        if (strobe == 0) {
                            state = 2;
                            indexingSolenoid = 1;
                        }
                    }
                    break;
                case 2: /* sequences before the final position the motor is rotating and arrives on strobe */
                    // Wait for indexing switch and turn motor reverse until lock switch
                     if (indexingSwitch) {
                        if (motorCW) {
                            motorCW = 0;
                            usleep(50e3);  // 50ms
                            while ( lockingSwitch == 1 ) {
                                motorCCW = 1;
                            }
                            motorCCW = 0;
                            brake = 1;         
                        }
                        if (motorCCW) {
                            motorCCW = 0;
                            usleep(50e3); // 50ms
                            while ( lockingSwitch == 1 ) {
                                motorCW = 1;
                            }
                            motorCW = 0;
                            brake = 1;         
                        }
                        usleep(200e3); // 200ms
                         indexingSolenoid = 0;                                  
         toolchanged = 1;
         state = 4;                       
                    }         
                    break;
                case 3: /* Tool changer fault */
                    // This is never reached and also better like this!
                    while (1) {
                        toolchanged = 0;
                        sensCW = 0;
                        sensCCW = 0;
                        motorCW = sensCW;
                        motorCCW = sensCCW;
                        rtapi_print_msg (RTAPI_MSG_ERR, "Tool changer parity error");
                        fprintf(stderr, "Tool changer parity error");
                    }         
                    break;
      case 4: /* Reset State to 0*/
                   
                     {
                        state = 0;
                    }         
                    break;
            } // switch
     } // FOR_ALL_INSTS()
  } // while
} //user_mainloop()
Re: Mach4: Need help with a macro for lathe turret.
« Reply #1 on: November 28, 2021, 03:56:22 PM »
Upon further inspection, of the 4bit, parity check, and strobe wires only 3 bit wires and strobe are connected. So that is a couple less wires and inputs to have to deal with. I will post the diagrams I have as well. Hopefully someone can help. I will pay for someone's time if that is needed. I realize this isn't a 5minute job.
Re: Mach4: Need help with a macro for lathe turret.
« Reply #2 on: November 28, 2021, 04:12:33 PM »
Re: Mach4: Need help with a macro for lathe turret.
« Reply #3 on: November 28, 2021, 06:52:53 PM »
So there is a bolt on the back of the motor on the turret that you can use to manually turn the motor. The documentation says that its bi directional so I wanted to test it. if i turn the motor one direction the turret rotates clockwise. if i reverse to try and turn the turret CCW it only locks the turret. It doesn't matter if the indexing solenoid is locked or not. So I will need to code this to only turn CW until the index position then CCW to lock. That should simplify things a little. Although it seems the Strobe signal should be used to actuate the solenoid. 
Re: Mach4: Need help with a macro for lathe turret.
« Reply #4 on: November 28, 2021, 11:35:33 PM »
Can anyone tell me the best way to go about this? Should I set up Bit1-3 into registers? Or all of the inputs into registers? The biggest issue I'm having is how do I make the bit signals into different tool numbers.

I know tool 1 is 1-0-0 and so on but how do I turn that into code that runs efficiently?

Any help forward is greatly appreciated

GOOMBA

*
Re: Mach4: Need help with a macro for lathe turret.
« Reply #5 on: November 29, 2021, 09:28:16 AM »
Something like the attached file is what you're looking for.
I have not tested this macro thoroughly and I don't know if it will work on your machine. I'm sure some things would have to be changed.
This macro assumes the turret is assigned to the C axis and assumes the turret has a home switch that activates when tool 1 is the active tool.
Meaning C home == tool 1 AKA 60 degrees.
Like I said it'll need to be modified.
Re: Mach4: Need help with a macro for lathe turret.
« Reply #6 on: November 29, 2021, 09:59:29 PM »
Thank you goomba for posting your M6 macro. I dont have anyway of Indexing 45 or 60deg. I have a 3phase AC motor that is controlled by sensors and brakes unfortunately. If it had a stepper or servo i feel like this would be much easier. The motor mounts with 3 screws and has a small pinion gear on the shaft. Not sure i could get a gear that small on an appropriate size stepper or servo. 

Offline Graham Waterworth

*
  • *
  •  2,673 2,673
  • Yorkshire Dales, England
    • View Profile
Re: Mach4: Need help with a macro for lathe turret.
« Reply #7 on: December 04, 2021, 10:54:40 PM »
Normally on this type of turret you have to count the strobe signals on and off, the timing is critical so usually a PLC is needed.

1. The first thing you have to do is read the switches to see which tool is in the cutting position.

2. Work out how many on and off signals you need to count to get to the required tool.

3. Unlock the turret

4. Start rotating and counting the strobe.

5. Check for in position signal.

6. Stop rotating. Reverse if needed.

7. Lock turret and check lock signal.
Without engineers the world stops
Re: Mach4: Need help with a macro for lathe turret.
« Reply #8 on: December 05, 2021, 07:14:08 PM »
Thank you Graham for your reply. I'm unfamiliar with a PLC. I've seem them talked about quite a bit but i have never used one. Is it required for something like this? Do I run the risk of damaging this turret without it? If so I will gladly order one if it will reduce the complexity and ensure reliable operation of this turret. I have been reading and trying to understand how to go about writing this macro for a week or so. I haven't made it very far might I add lol. I have a pretty good of understanding of what I need the turret to do. Coding it to do just that is where my struggle begins.

I have however managed to pull the components from the control cabinet that run the turret and have them temporarily mocked up on my work bench so I can test as I go. I have the turret spinning CW or CCW with buttons I put on a temp screen in mach4. I have a register set for current tool. Hoping I could read tool numbers as they passed while the turret was spinning. It's not updating the register as I intended. I do see the inputs go low and high on the diagnostic screen.

I set "input 1" in the signal library to call a function "TurretPos" since input 1 changes state between each tool. I thought it would trigger to look for the current tool. I must have a misunderstanding of how to do this. I will post that "turretpos" function below. Not that I need that function, I was just practicing the coding part to see how to check for tools real time so then I could stop it at the right position. As you stated the timing is very critical, as this turret spins a little faster than I anticipated. I'm sure i have done something wrong, I'm not good at this whole coding thing.

Code: [Select]
function TurretPos()
local inst = mc.mcGetInstance()
local rc = mc.mcRegGetHandle(inst, "iRegs0/TCPos")
local CurrentTool = mc.mcRegGetValue(rc)
local sigh = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT1)
local bit1 = mc.mcSignalGetState (sigh)
local sigh2 = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT2)
local bit2 = mc.mcSignalGetState(sigh2)
local sigh3 = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT3)
local bit3 = mc.mcSignalGetState(sigh3)
-- local strobe = mc.mcSignalGetHandle(inst, mc.ISIG_INPUT4)

if (CurrentTool ~= nil) then
CurrentTool = 0
elseif (bit1 == 1 and bit2 == 0 and bit3 == 0) then
CurrentTool = 1
elseif (bit1 == 0 and bit2 == 1 and bit3 == 0)then
CurrentTool = 2
elseif (bit1 ==1 and bit2 == 1 and bit3 == 0)then
CurrentTool = 3
elseif (bit1 == 0 and bit2 == 0 and bit3 == 1)then
CurrentTool = 4
elseif (bit1 == 1 and bit2 == 0 and bit3 == 1)then
CurrentTool = 5
elseif (bit1 == 0 and bit2 == 1 and bit3 == 1)then
CurrentTool = 6
elseif (bit1 == 1 and bit2 == 1 and bit3 == 1)then
CurrentTool = 7
elseif (bit1 == 0 and bit2 == 0 and bit3 == 0)then
CurrentTool = 8
mc.mcRegSetValue(rc, CurrentTool)
end
end
Re: Mach4: Need help with a macro for lathe turret.
« Reply #9 on: December 05, 2021, 08:35:35 PM »
Would the Click series PLC's be appropriate for this application? I found these on automation direct. I also looked at the DL line of plc's as well as a couple others and a lot of the other stuff is out of stock.

Click C2-01CPU
https://www.automationdirect.com/adc/shopping/catalog/programmable_controllers/click_series_plcs/click_plus_plcs_(stackable_micro_modular)/cpus/c2-01cpu

8 input / 6 output module
https://www.automationdirect.com/adc/shopping/catalog/programmable_controllers/click_series_plcs/click_plus_plcs_(stackable_micro_modular)/cpu_option_slot_modules/c2-14d2