Vai al contenuto
PLC Forum


Codesys - frequency converter


rlc001

Messaggi consigliati

Buongiorno,

 

ho un'applicazione del seguente tipo: PC con codesys 3.5 collegato ad un bus coupler ethercat beckhoff EK1100 che a sua volta a collegato un solo modulo EL6731 che "trasforma" l'ethercat in profibus DP. Questo modulo profibus DP master è collegato ad un solo frequency converter della KEB (modello F5).

In Codesys vedo tutta la rete ma non trovo quale tipo di asse devo inserire nell'albero "SoftMotion General Axis Pool" e come collegare questo asse al device KEB_DP_F5_OP.

Sul sito Codesys e KEB non trovo documentazione o esempi di come fare questo link.

Qualcuno ha già avuto esperienze simili?

 

Grazie mille.

Immagine.png

Link al commento
Condividi su altri siti


6 ore fa, Luca001 scrisse:

Sul sito Codesys e KEB non trovo documentazione o esempi di come fare questo link.

ci sono tutti i presupposti per un discreto mal di testa...😁

Premesso che non ho mai utilizzato Codesys ma programmo Simotion che se non è zuppa è pan bagnato, ti allego codice del blocco a suo tempo utilizzato per gestire un asse controllato KEB. Insieme alla mappatura dei bit nella documentazione dei KEB dovresti cavarci qualcosa.

 

ATTENTO:

la mappatura del KEB è parametrizzata nei parametri dell'interfaccia Profibus (che loro chiamano "operatore" quindi la solfa cambia in funzione dei numerelli che ci metti dentro). Magari sapendo come sono i parametri dell'operatore si riesce a cavare il ragno dal buco!

 

Qui sotto trovi il codice che secondo me potresti migrare almeno parzialmente.

 

PS

Dimenticavo, KEB non esprime la quota in unità standard (es.mm, gradi ecc.) ma inpulsi. Se vuoi capirci qualcosa focalizzati bene sul capire come funziona....

 

//====KEB MAIN===============================================================
//  PIGROPLC
//---------------------------------------------------------------------------
//  version:       SIMOTION / Scout V4.1     
//  restrictions:
//  requirements:
//  functionality: KEB interface via Profibus
//---------------------------------------------------------------------------
//  change log table:
//  version     date        expert in charge        changes applied
//  01.00.00    17.10.11    pigroplc                created
//  01.01.00    18.10.11    pigroplc                changes of form, variables, ...
//  01.02.00    20.10.11    pigroplc                I/O parameters optimized
//  01.03.00    11.11.11    pigroplc                I/O adapted to the declaration
//  01.04.00    14.11.11    pigroplc                Final debug 
//===========================================================================

INTERFACE
    
// ----------- Export -------------------------------------------------------     
    
  
    FUNCTION_BLOCK FB_MAIN_KEB;   
END_INTERFACE

IMPLEMENTATION 
    
    
FUNCTION_BLOCK FB_MAIN_KEB
    VAR_TEMP
        temporary_real      : REAL;
    END_VAR
    
    VAR_INPUT
        Pulses       : DINT ;   (* Pulses received from Profibus *)  
        SY42         : WORD;    (* Status word high received from Profibus *) 
        SY51         : WORD;    (* Status word low received from Profibus *)     
        RU0          : WORD;    (* Status code received from Profibus *) 
        Usage_perc   : WORD;    (* Usage % received from Profibus *) 
        
        Pos_SetPoint : DINT;    (* input position set point expressed in mm*1000 *)
        Pos_window   : DINT;    (* positioning window pulses *)
        Spe_SetPoint : INT;     (* 0-100 % speed override *)
        Tor_SetPoint : INT;     (* 0-100% torque set point *)
        Enable       : BOOL;    (* Axis enable *)
        Start        : BOOL;    (* Start axis positioning *) 
        Homing_Start : BOOL;    (* Homing Start axis *)        
        Hom_SetPoint : INT;     (* homing speed set point *)
        Alarm_Reset  : BOOL;    (* Alarm reset flag *)
        Ratio        : REAL;    (* Ratio pulses / micrometers *)
        Data_Set     : BOOL;    (* Data set selection flag *)
        Motor_Speed  : DINT;    (* Motor Speed RPM *)
        Ratio_type   : BOOL;    (* 1=pulses per mm; 0=micron per pulses *)
    END_VAR

    VAR_OUTPUT
        Position_SP  : DWORD;   (* Position set point to Profibus *)  
        Speed_SP     : WORD;    (* Speed det point to Profibus *) 
        SY50         : WORD;    (* Control word to Profibus *)     
        Homing_Speed : WORD;    (* Homing speed set point to Profibus *) 
        Torque_SP    : WORD;    (* Torque % to Profibus *) 
        
        Ready      : BOOL;      (* Drive ready flag *)
        Homing_Done: BOOL;      (* Homing done flag *)
        Positioning: BOOL;      (* Axis positioning flag *)
        Alarm      : BOOL;      (* Axis Alarm flag *)
        Alarm_code : INT;       (* output: error values *)              
        Actual_pos : DINT;      (* output: axis actual position *)
        usage      : INT;       (* output: 0-100% usage OF the torque available *)      
        Direction  : BOOL;      (* Axis positioning direction *) 
        POS_Pulses : DINT;      (* Position set point for KEB pulses mapped *)  
    END_VAR
    
    VAR_IN_OUT
        Target_Reached: BOOL;    (* Positioning target reached *)   
    END_VAR 
    
   
        // variables
    VAR
        PEH        : BOOL;
        start_delay: TON;
    END_VAR                  
    
// #02 - Conversione della posizione attuale in base agli impulsi e al fattore di conversione
        
        temporary_real :=
        DINT_TO_REAL(in :=Pulses );   
        
        IF Ratio_type THEN;
            
        Actual_pos := REAL_TO_DINT(in := (temporary_real / Ratio)*1000.0) ;
        ELSE;
        Actual_pos := REAL_TO_DINT(in := (temporary_real * Ratio)*1000.0) ;
        END_IF;
        
// #03 - Scrittura della posizione di destinazione in funzione della conversione utilizzata
        temporary_real :=
        DINT_TO_REAL(in := Pos_SetPoint);
    
        IF Ratio_type THEN
        Position_SP := REAL_VALUE_TO_DWORD(in := (temporary_real * Ratio)/1000.0) ;
        ELSE
        Position_SP := REAL_VALUE_TO_DWORD(in := (temporary_real / Ratio)/1000.0) ;
        END_IF; 
        
// #04 - Scrittura della velocità di posizionamento in funzione della percentuale impostata         
        IF Spe_SetPoint > 100 THEN
        Speed_SP := DINT_TO_WORD(((100 * Motor_Speed)/100) *8) ;            // valuta al max 100%
        ELSE
        Speed_SP := DINT_TO_WORD(((Spe_SetPoint * Motor_Speed)/100) *8) ;   // valuta un % inferiore          
        END_IF;         
        
// #05 - Scrittura del flag di drive enable
        IF Enable THEN
        SY50.0:= TRUE;
        SY50.2:= TRUE;
        ELSE
        SY50.0:= FALSE;
        SY50.2:= FALSE;            
        END_IF;
        
// #06 - Scrittura del flag di selezione del set di dati
        IF Data_Set AND SY51.10 AND NOT Homing_Start THEN
        SY50.4:= TRUE;
        ELSE
        SY50.4:= FALSE;         
        END_IF; 

// #07 - Scrittura del flag di start asse 
        
        start_delay(
        in := Start
        ,pt := T#100ms 
        // ,q => 
        // ,et => 
        );
        IF (RU0 = 121 OR RU0 = 122) AND Start AND start_delay.q AND Enable THEN
        SY50.10:= TRUE;
        ELSE
        SY50.10:= FALSE;         
        END_IF;           

// #08 - Scrittura del flag di stop asse 
        IF NOT Start AND NOT Homing_Start THEN
        SY50.11:= TRUE;
        ELSE
        SY50.11:= FALSE;         
        END_IF;  

// #09 - Scrittura flag di reset allarme
        (* imposta il flag di allarme solamente quando serve e non solamente in funzione del tasto di reset*)
        IF Alarm_Reset AND (RU0 = 104 OR RU0 = 105 OR SY51.1) THEN
        SY50.1:= TRUE;
        ELSE
        SY50.1:= FALSE;         
        END_IF;          
        
// #10 - Scrittura della velocità di ricerca di zero
        Homing_Speed :=
        INT_TO_WORD(in := Hom_SetPoint);   
    
// #11 - Scrittura del flag di start ricerca di zero    
        IF Homing_Start THEN
        SY50.9:= TRUE;
        ELSE
        SY50.9:= FALSE;         
        END_IF;       

// #12 - Scrittura della coppia impostata 
      
        IF Tor_SetPoint > 100 THEN
        Torque_SP := 
        INT_TO_WORD(in := 1000);             // valuta il 100%
         ELSE
        Torque_SP := 
        INT_TO_WORD(in := Tor_SetPoint*10);    // valuta il % inferiore         
        END_IF;      
    
// #13 - Impostazione del bit di drive abilitato
        IF SY51.0 THEN
        Ready := TRUE;
        ELSE
        Ready := FALSE;            
        END_IF;     

// #14 - Impostazione del bit di posizione raggiunta con il controllo della quota
 
        POS_Pulses :=
        DWORD_TO_DINT(in := Position_SP);
        
       IF (POS_Pulses + (Pos_window/2) > Pulses) AND
          (POS_Pulses - (Pos_window/2) < Pulses) THEN
        PEH := TRUE;
        ELSE
        PEH := FALSE;            
        END_IF;            

// #15 - impostazione del flag di quota raggiunta
        IF RU0 = 121 AND SY51.11 AND SY51.14 AND PEH AND Start THEN
        Target_Reached:= TRUE;     
        END_IF;          
        IF NOT Start THEN
        Target_Reached:= FALSE;     
        END_IF;          
        
// #16 - impostazione del flag di sicronizzazione avvenuta
        IF SY51.10 THEN 
        Homing_Done:= TRUE;     
        ELSE
        Homing_Done:= FALSE;     
        END_IF;         
   
// #17 - impostazione del flag di asse in posizionamento
        IF RU0 = 122 THEN
        Positioning:= TRUE;
        ELSE
        Positioning:= FALSE;         
        END_IF;           
 
// #18 - impostazione del flag di direzione negativa
        IF SY51.3 THEN 
        Direction:= TRUE;     
        ELSE
        Direction:= FALSE;     
        END_IF;         

// #19 - impostazione del flag di asse in allarme 
        IF RU0 = 104 OR RU0 = 105 OR SY51.1 THEN
        Alarm:= TRUE;
        ELSE
        Alarm:= FALSE;         
        END_IF;          

// #20 - impostazione del codice di asse in allarme 
        Alarm_code :=
        WORD_TO_INT(in :=RU0 );   
        
// #21 - impostazione della percentuale di utilizzo del motore 
        usage :=
        WORD_TO_INT(in :=Usage_perc );           
END_FUNCTION_BLOCK
END_IMPLEMENTATION

 

 

Modificato: da pigroplc
Link al commento
Condividi su altri siti

Grazie mille per la pronta risposta con le utili informazioni!

Si hai ragione, collegandomi con il tool della KEB riesco a impostare per esempio il byte 0 della process data in è il parametro inverter_state, il byte 1-2 è l'actual pos e cosi via.

Una cosa ancora scusa, nel tuo Simotion la mappatura tra le tue variabili PLC (Es. Pulses) e i bytes dei "telegrammi" Profibus dove lo fai? Hai una finestra dedicata nel tuo Simatic?

Grazie ancora

Link al commento
Condividi su altri siti

Nell'immagine della configurazione hardware trovi come era stato impostato il telegramma con il KEB. 

Il blocco che ti ho allegato prima contiene delle variabili in ingresso dichiarate VAR_INPUT; variabili in uscita dichiarate VAR_OUTPUT; variabili sia in ingresso che in uscita dichiarate VAR_IN_OUT.

Ora, nel tuo codice Codesys dovrai fare qualcosa di simile, quando richiami il blocco dovrai sicuramente accoppiare al parametro di uscita una variabile che leggerai altrove, al parametro di ingresso una variabile che NON viene modificata dal blocco ma viene gestita da esso. Nella seconda immagine trovi specificato meglio quanto detto.

ATTENZIONE:

a livello KEB devi avere avere i parametri da FB01 in poi adeguati alla programmazione in Codesys altrimenti prendi lucciole per lanterne.

aaa.png

aab.png

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...