4
« 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()