# 4. Programmazione del PLC Siemens

Il Function Block avanzato permette, rispetto all'FB base, di controllare tramite fieldbus parametri aggiuntivi quali velocità e accelerazione di Jog, limitazione di corrente e freno.
Richiedendo un maggior numero di words Profinet rispetto alla configurazione base, l'applicazione avanzata è compatibile unicamente con PSD1 ad asse singolo.
Di seguito la struttura dei dati scambiati tra PSD e PLC:

- Ouptut PSD --> Input PLC

  | Nome		| DataType	| Contenuto					|
  |-------------|-----------|---------------------------|
  |`0x6041.0`	| WORD		| Status word				|
  |`0x6064.0`	| LREAL		| Posizione attuale			|
  |`0x606C.0`	| LREAL		| Velocità attuale			|
  |`0x31C1.1`	| WORD		| Input digitali Drive		|
  |`0x603F.0`	| WORD		| Codice errore Drive		|
  |`0x3321.2`	| LREAL		| Corrente attuale			|

- Output PLC --> Input PSD

  | Nome		| DataType	| Contenuto			    	|
  |-------------|-----------|---------------------------|
  |`0x6040.0`	| WORD		| Control word				|
  |`0x6081.0`	| LREAL		| Posizione target			|
  |`0x6083.0`	| LREAL		| Velocità posizionamento	|
  |`0x6084.0`	| LREAL		| Accel. posizionamento		|
  |`0x346A.0`	| LREAL		| Decel. posizionamento		|
  |`0x3468.0`	| LREAL		| Velocità Jog				|
  |`0x346E.0`	| LREAL		| Accel. Jog				|
  |`0x341C.5`	| WORD		| Decel. Jog				|
  |`0x3212.1`	| WORD		| Jerk						|
  |`0x3212.2`	| WORD		| Limite corrente positivo	|
  |`0x3402.0`	| LREAL		| Limite corrente negativo	|

### Importare il Function Block in TIA Portal:

Per poter utilizzare l'FB in TIA Portal sarà necessario importarne il codice sorgente dal pacchetto *FB avanzato per PSD1*

- In *Project Tree > PLC_1 > External source files* selezionare la voce *Add new external file* e indicare il percorso del file *FB_PSD_1_0_2.scl*
<br>
<br>
  <img src="https://docs.dctrasmissioni.it/uploads/images/gallery/2024-11/tia-add-source.png" alt="tia-add-source.png" width="300"/>
<br>
<br>

- Ora è necessario generare l'FB premendo il tasto destro del mouse sul file appena importato e selezionando la voce *generate blocks from source*
<br>
<br>
  <img src="https://docs.dctrasmissioni.it/uploads/images/gallery/2024-11//tia-generate-blocks.png" alt="tia-generate-blocks.png" width="300"/>
<br>
<br>

A questo punto sarà possibile richiamare il blocco nella sezione desiserata, assegnargli un'istanza e parametrizzarlo.

### Parametrizzazione del Function Block:

- Input:

  | Nome 		  	| DataType | Funzione		 					    |
  |-----------------|----------|----------------------------------------|
  | `HW_Address`	| HW_IO    | Indirizzo hardware Profinet del PSD1	|
  | `Enable`		| BOOL     | Abilitazione Drive					    |
  | `Reset`			| BOOL     | Reset allarmi Drive					|
  | `QuickStop`		| BOOL     | Fermata rapida Drive <sup>1</sup>      |
  | `OpenBrake` 	| BOOL     | Apertura freno quando `Enable = 0`	    |
  | `StartMove`		| BOOL     | Start movimento (NON-latching)		    |
  | `JogP` 			| BOOL     | Comando Jog positivo					|
  | `JogN`			| BOOL     | Comando Jog negativo					|
  | `Homing`		| BOOL     | Avvio procedura di homing del Drive	|
  | `MovingMode`	| INT      | Modalità di movimento					|
  | `Limit_Range`	| INT      | Finestra di raggiungimento `TargetRef` |
  | `PosCurrentLimit`| INT     | Limite di corrente positivo			|
  | `NegCurrentLimit`| INT     | Limite di corrente negativo			|
  | `JogSpeed`		| DINT     | Velocità di Jog 						|
  | `JogAccel`		| DINT     | Acccel. Jog 							|
  | `JogDecel`		| DINT     | Decel. Jog 							|
  | `Speed`			| DINT     | Velocita posizionamento 				|
  | `Accel`			| DINT     | Accel. posizionamento 				    |
  | `Decel`			| DINT     | Decel. posizionamento 				    |
  | `Jerk`			| INT      | Jerk posizionamento 					|
  | `TargetRef`		| DINT     | Target di posizione/velocità <sup>2</sup> |

  <sup>1</sup> Il drive necessita di essere riabilitato tramite `Enable` dopo un `QuickStop`
  
  <sup>2</sup> `TargetRef` rappresenta il target di posizione per `MovingMode = 0/1` oppure di velocità per `MovingMode = 2`
  <br>
  <br>
  la variabile `HW_Address` identifica il driver specifico controllato dalla FB e può essere configurato dinamicamente scrivendo al suo interno l'oggetto Profinet corrispondente al Drive desiderato
<br>
<br>
  <img src="https://docs.dctrasmissioni.it/uploads/images/gallery/2024-11/tia-psd-hw-address-20words.png" alt="tia-psd-hw-address-20words.png" width="600"/>
<br>
<br>

  La variabile `MovingMode` può assumere valori 0-3 corrispondenti alle seguenti modalità di movimento:

  | Valore | Funzione           |
  |-----|-----------------------|
  | `0` | Controllo assoluto	|
  | `1` | Controllo relativo	|
  | `2` | Controllo in velocità |
  | `3` | Modalità Jog		    |

- Output:

  | Nome 		  		| DataType | Funzione		 				  |
  |---------------------|----------|----------------------------------|
  | `Enabled`			| BOOL     | Drive abilitato				  |
  | `SafeTorqueOff`		| BOOL     | STO attivato					  |
  | `Error`				| BOOL     | Errore Drive					  |
  | `Moving`			| BOOL     | Motore in movimento			  |
  | `Homed` 			| BOOL     | Homing eseguito				  |
  | `TargetReached`		| BOOL     | Target posizione/velocità raggiunto |
  | `InPos` 			| BOOL     | la posizione è in `TargetRef ± Limit_Range` |
  | `ActualPos`			| DINT     | Posizione attuale				  |
  | `ActualSpeed`		| DINT     | Velocità attuale				  |
  | `ActualCurrent`		| DINT     | Corrente attuale				  |
  | `CommunicationError`| BOOL     | Comunicazione interrotta o configurazione Profinet errata |
  | `DriveStatus`		| INT      | Stato del Drive				  |
  | `_Status`			| STRING[30] | Descrizione dello stato		  |
  | `ErrorCode`			| WORD     | Ultimo codice di errore Drive (lista allarmi PSD) |
  | `ErrorQuittable`	| BOOL     | Indica se l'errore è resettabile <sup>3</sup> |
  | `ErrorDescription`	| STRING[100] | Descrizione dell'errore		  |

  <sup>3</sup> Se `ErrorQuittable = False` sarà necessario riavviare il drive per resettare l'errore

### Esempi di modalità di movimento:

- Modalità di Movimento Assoluto o Relativo (`MovingMode = 0/1`)

  I parametri necessari sono:

  | Nome          | Valore    |
  |---------------|-----------|
  | `MovingMode`  | `0`		  |
  | `Speed`	      | `305000`  |
  | `Accel`       | `1000000` |
  | `Decel`		  | `1000000` |
  | `TargetRef`	  | `2450`	  |

  `TargetRef` corrisponde alla quota da raggiungere in modalità assoluta o all'incremento in modalita relativa.
  <br>
  <br>
  
- Modalità di Movimento in Velocità (`MovingMode = 2`)

  I parametri necessari sono:

  | Nome          | Valore    |
  |---------------|-----------|
  | `MovingMode`  | `2`		  |
  | `Accel`		  | `1000000` |
  | `Decel`		  | `1000000` |
  | `TargetRef`	  | `305000`  |

  `TargetRef` corrisponde alla velocità da mantenere e può essere modificato anche in movimento.

  Il motore può essere fermato con `StartMove = 0` oppure con `TargetRef = 0`.
  <br>
  <br>

- Modalità di Movimento Jog (`MovingMode = 3`)

  I parametri necessari sono:

  | Nome          | Valore    |
  |---------------|-----------|
  | `MovingMode`  | `3`		  |
  | `JogSpeed`	  | `20000`	  |
  | `JogAccel`	  | `1000000` |
  | `JogDecel`	  | `1000000` |

  Il movimento viene gestito tramite gli ingressi `JogP` e `JogN`.