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