this is the macro that I use from 2015... run perfectly for my machine...
' Macro cambio utensile automatico (ATC) Rel 4.00 del 25/9/2014
'**************** Definizione degli I/O (si considerano attivi ad 1 e disattivi a 0)
' Output 1 comando carosello fuori
' Input 1 sensore carosello fuori
' Output 2 comando carosello dentro
' Input 2 sensore carosello dentro
' Output 3 pinza mandrino
' Output 4 valvola aria pulizia mandrino
' Home asse B sensore di zero su carosello
' Output 8 perno freno mandrino
' Input 4 sensore di posizione mandrino
' Output 7 Accende pompa circuito pneumatico
'*************** Definizione variabili
Dim old_tool As Single 'N. Utensile nel mandrino; 0 siginifica vuoto
Dim new_tool As Single 'N Utensile da prelevare, numeri ammessi da 1 a 8
Dim tool As Single 'N. Utensile nel mandrino; 0 siginifica vuoto
Dim B_pos (

As Double ' sono le posizioni, in gradi, degli utensili messi sul carosello
Dim refrigerante As Single ' memorizza se si stava usando il refrigerante o no
Dim old_speed As Single ' memorizza la velocità del mandrino
Dim counter As Double 'timeout fermo mandrino
counter=300000 'counter per attendere che il mandrino si fermi
'************** Definizione costanti
Const safe_z=-1 'posizione Z sicura per non urtare il carosello
Const load_z = -85 'posizione Z per presa utensile
Const timeout_carosello=3 'quanto tempo può impiegare il carosello per uscire o rientrare prima di errore
Const Z_speed=3000 'velocità di movimento asse Z
Const B_speed=4000 'velocità movimento carosello
Const vel_mandrino=40 'velocità mandindrino minima per posizionamento presa utensile
' le posizioni degli utensili nel carosello. Non si è usata una formula in modo da poter tarare esattamente ogni posizione
B_pos(1)=0
B_pos(2)=45
B_pos(3)=90
B_pos(4)=135
B_pos(5)=180
B_pos(6)=225
B_pos(7)=270
B_pos(

=315
' **** Inizio Programma ****
old_speed=GetRPM() 'legge la velocità mandrino
old_tool = GetCurrentTool()
new_tool = GetSelectedTool()
If new_tool=old_tool Then 'se il nuovo utensile è uguale al vecchio allora non fare nulla
End 'esce dalla macro
End If
If(new_tool>8 Or new_tool<0) Then 'il numero utensile > 8 o < 0
MachMsg("Il numero consentito di utensili è tra 0 e 8","ERRORE",0) 'scrive messaggio di errore
Code "M9" 'ferma il refrigerante
Code "M5" 'ferma il mandrino
DoOEMButton(1003) 'ferma l'esecuzione del gcode
End 'esce dalla macro
End If
tool = GetSelectedTool()
SetCurrentTool( tool )
' controlla se esiste lo zero macchina per assi Z e B
If (GetOEMLed(809) And GetOEMLed(811)) Then 'manca lo Zero macchina su Z o lo zero sul carosello
MachMsg("NON E'STATO FATTO LO ZERO MACCHINA","ERRORE",0) ' scrive messaggio di errore
Code "M9" 'ferma il refrigerante
Code "M5" 'ferma il mandrino
DoOEMButton(1003) 'ferma l'esecuzione del gcode
End 'esce dalla macro
End If
' Attiva Pompa circuito pneumatico
ActivateSignal(Output7) 'attiva pompa
' ferma refrigerante e ferma mandrino
refrigerante= GetOemLed(13) 'se stavo usando il refrigerante o no
Code "M9" 'ferma il refrigerante
Code "G53" 'passa a coordinate assolute macchina
Code "F" & Z_speed 'porta la velocità di Z a quella impostata per ATC
Code "G01 G53 Z" & load_z 'porta Z nella posizione LOAD per far uscire il carosello e rimettere l'utensile dentro
While IsMoving() ' attendi fino a che si ferma
Wend
Code "S"&vel_mandrino 'rallenta il mandrino
Code "M3" 'parte il mandrino
ActivateSignal(Output8) 'esce il perno freno mandrino
sleep(3500) 'aspetta 5 secondi
Code "M5" 'ferma il mandrino,che comuque dovrebbe fermarsi appena il perno entra nella sede
' While(IsActive(INPUT4)=FALSE And counter > 0) 'attende l'index posizione mandrino o timeout
' counter=counter-1
' Wend
counter=300000
' Code "M5"
' ActivateSignal(Output8) 'spenge mandrino
' sleep(1000) 'applica freno per 1 secondo
' DeactivateSignal(Output8) 'toglie il freno
' sleep (500) 'leggero ritardo
If (IsActive(INPUT4)=FALSE) Then 'se il sensore index del mandrino non è attivo
MachMsg("Il mandrino non si è fermato correttamente","ERRORE",0) 'scrive messaggio di errore
Code "M5" 'spenge il mandrino
'Disattiva pompa circuito pneumatico
DeactivateSignal(Output7) 'disattiva pompa
DoOEMButton(1003) 'ferma l'esecuzione del gcode
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
End 'esce dalla macro
End If
If(new_tool=0) Then 'se devo riporre l'utensile senza caricarne uno nuovo
' *********** Rimette l'utensile dentro il carosello
Code "F" & B_speed
Code "G01 G53 B" & B_pos(old_tool) 'posiziona il carosello sull'utensile da riporre
While IsMoving() 'attendi fino a che si ferma
Wend
' porta fuori il carosello
ActivateSignal(Output1) 'sposta il carosello in fuori
sleep(timeout_carosello * 1000) ' attende che il carosello sia fuori
DeactivateSignal(Output1)
If(IsACTIVE(Input1)=0) Then ' se il sensore del carosello fuori non è attivo
MachMsg("IL CAROSELLO E' BLOCCATO","ERRORE",0) ' scrive messaggio di errore
ActivateSignal(Output2) 'riporta il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
DeactivateSignal(Output2)
DoOEMButton(1003) 'ferma l'esecuzione del gcode
'Disattiva pompa circuito pneumatico
DeactivateSignal(Output7) 'disattiva pompa
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
End 'esce dalla macro
End If
ActivateSignal(Output3) 'apre la pinza del mandrino per mollare l'utensile
sleep(1000) 'aspetta un secondo
ActivateSignal(Output4) 'flush aria compressa per pulizia
sleep(500) 'aspetta mezzo secondo
DeActivateSignal(Output4) 'ferma flush aria compressa per pulizia
Code "F" & Z_speed 'porta la velocità di Z a quella impostata per ATC
Code "G01 G53 Z" & safe_z 'porta Z nella posizione Safe per far ruotare il carosello
While IsMoving() 'attendi fino a che si ferma
Wend
DeActivateSignal(Output3) 'chiude la pinza del mandrino
ActivateSignal(Output2) 'riporta il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
DeactivateSignal(Output2)
DoOEMButton(1003) 'ferma l'esecuzione del gcode
'Disattiva pompa circuito pneumatico
DeactivateSignal(Output7) 'disattiva pompa
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
End 'esce dalla macro
End If
If(old_tool>0) Then 'al primo cambio utensili mi trovo il mandrino vuoto altrimenti devo rimettere l'utensile a posto
' *********** Rimette l'utensile dentro il carosello
' rimettere l'utensile a posto
Code "F" & B_speed
Code "G01 G53 B" & B_pos(old_tool) 'posiziona il carosello sull'utensile da riporre
While IsMoving() 'attendi fino a che si ferma
Wend
' porta fuori il carosello
ActivateSignal(Output1) 'sposta il carosello in fuori
sleep(timeout_carosello * 1000) ' attende che il carosello sia fuori
DeactivateSignal(Output1)
If(IsACTIVE(Input1)=0) Then ' se il sensore del carosello fuori non è attivo
MachMsg("IL CAROSELLO E' BLOCCATO","ERRORE",0) ' scrive messaggio di errore
ActivateSignal(Output2) 'riporta il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
DeactivateSignal(Output2)
DoOEMButton(1003) 'ferma l'esecuzione del gcode
'Disattiva pompa circuito pneumatico
DeactivateSignal(Output7) 'disattiva pompa
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
End 'esce dalla macro
End If
ActivateSignal(Output3) 'apre la pinza del mandrino per mollare l'utensile
sleep(1000) 'aspetta un secondo
ActivateSignal(Output4) 'flush aria compressa per pulizia
sleep(500) 'aspetta mezzo secondo
DeActivateSignal(Output4) 'ferma flush aria compressa per pulizia
End If
' *********** Va a prendere il nuovo utensile
If(new_tool>0) Then ' se il nuovo utensile è da 1 a 8 allora lo prende
Code "F" & Z_speed 'porta la velocità di Z a quella impostata per ATC
Code "G01 G53 Z" & safe_z 'porta Z nella posizione Safe per far ruotare il carosello
While IsMoving() 'attendi fino a che si ferma
Wend
DeActivateSignal(Output3) 'chiude la pinza del mandrino
Code "F" & B_speed
Code "G01 G53 B" & B_pos(new_tool) 'si posiziona sul nuovo utensile
While IsMoving() ' attendi fino a che si ferma
Wend
' porta fuori il carosello, se non è già fuori.....
If(IsACTIVE(Input1)=0) Then 'se il carosello è ancora dentro
ActivateSignal(Output1) 'sposta il carosello in fuori
sleep(timeout_carosello * 1000) 'attende che il carosello sia fuori
DeactivateSignal(Output1)
If(IsACTIVE(Input1)=0) Then 'se il sensore del carosello fuori non è attivo
MachMsg("IL CAROSELLO E' BLOCCATO","ERRORE",0) 'scrive messaggio di errore
ActivateSignal(Output2) 'riporta il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
DeactivateSignal(Output2)
'Disattiva pompa circuito pneumatico
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
DeactivateSignal(Output7) 'disattiva pompa
DoOEMButton(1003) 'ferma l'esecuzione del gcode
End 'esce dalla macro
End If
End If
End If
Code "F" & Z_speed 'porta la velocità di Z a quella impostata per ATC
ActivateSignal(Output3) 'apre la pinza del mandrino
Code "G01 G53 Z" & load_z 'porta Z nella posizione di presa
While IsMoving() 'attendi fino a che si ferma
Wend
DeActivateSignal(Output3) 'chiude la pinza del mandrino
sleep(1000) 'attendi 1 secondo
ActivateSignal(Output2) 'riporta il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
If(IsACTIVE(Input2)=0) Then 'se il sensore del carosello dentro non è attivo
MachMsg("IL CAROSELLO E' BLOCCATO","ERRORE",0) 'scrive messaggio di errore
ActivateSignal(Output2) 'prova a riportare il carosello dentro
sleep(timeout_carosello*1000) 'aspetta
DeactivateSignal(Output2)
DoOEMButton(1003) 'ferma l'esecuzione del gcode
'Disattiva pompa circuito pneumatico
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
DeactivateSignal(Output7) 'disattiva pompa
End 'esce dalla macro
End If
'Disattiva pompa circuito pneumatico
DeactivateSignal(Output7) 'disattiva pompa
DeactivateSignal(Output2)
Code "G54" 'passa a coordinate precedenti
Code "F" & Z_speed 'porta la velocità di Z a quella impostata per ATC
Code "S" & old_speed 'ripristina velocitù mandrino
If refrigerante Then
Code "M7" 'se il refrigerante era acceso lo riaccende
End If
DeActivateSignal(Output8) 'rientra il perno fermo mandrino
Code "M3" 'riaccende il mandrino
'Code "G01 Z" & GetToolchangestart(2) 'rimette Z dove era prima della macro
While IsMoving() 'attendi fino a che si ferma
Wend
End