Vai al contenuto
PLC Forum


Funzione Per Generare Rampa In Awl


attiliovolpe

Messaggi consigliati

Il seguente codice in AWL, potrebbe essere scritto per creare una subroutine in MicroWin?

Ci sono delle istruzioni che sono diverse o sarebbe solo un problema di sintassi?

Vorrei implementare qualcosa del genere, capire bene come funziona ed utilizzarlo per generare rampe e dissolvenze per gestione di una illuminazione a LED dimmerabile con 0-10V.

VAR_INPUT
Activate : BOOL ; //0= Function set Actual equal Null-Point
R_max : BOOL ; //1 = Actual value approach Max_Value ( Go to Maximum )
R_min : BOOL ; //1 = Actual value approach Min_Value ( Go to Minimum )
END_VAR
VAR_IN_OUT
R_OK : BOOL ; //1 = Actual value reached rated value
Max_Value : REAL ; //Maximal Value
Null_Point : REAL ; //Null-Point, value with which the function starts
Min_Value : REAL ; //Minimal Value
Actual_Value : REAL ; //Actual Value
R_plus : REAL ; //steprange for approximation Actual_Value to Max_Value
R_minus : REAL ; //steprange for approximation Actual_Value to Min_Value
R_Time : DWORD ; //Time for a Step
MEG_Time : DWORD ; //Cycle time of previous OB1 scan (milliseconds)
END_VAR
VAR_TEMP
Temp_Rated_Value : REAL ; //temporary rated value
Temp_Step_Range : REAL ; //temporary value for actual steprange
Proportion : REAL ; //Proportion between R_Time and Cycle Time
END_VAR
BEGIN
NETWORK
TITLE =Set Values
CLR ;
= #R_OK; // Reset "Done" - Signal
NETWORK
TITLE =check Activatebit
U #Activate; // Function should run
SPB m001; // go to m001, check input values
// the function is'nt to run
L #Null_Point;
T #Actual_Value; // set Actual_Value equal Nullpoint
BEA ; // and exit
NETWORK
TITLE =check input values
m001: L 0.000000e+000;
L #R_plus; // check R_Plus > 0
<R ;
SPB m01a; // if yes goto m01a, next check
// if R_Plus < 0
NEGR ; // Make R_Plus positiv
T #R_plus; // save R_Plus
L 0.000000e+000; // R_Plus == 0 ?
<>R ;
SPB m01a; // if not , next check
L 1.000000e+000; // else save default value ( 1 )
T #R_plus;
// check R_minus
m01a: L 0.000000e+000;
L #R_minus;
<R ; // if R_minus > 0
SPB m01b; // goto m01b, next check
SIMATIC ...\SIMATIC 400(1)\CPU416-1\...\FC10 06.12.1999 16:21:11
Seite 2..
NEGR ; // else set R_minus positiv
T #R_minus; // Save corrected Value
L 0.000000e+000; // R_minus == 0 ?
<>R ; //
SPB m01b; //if not go to m01b
L 1.000000e+000; // else save default value ( 1 )
T #R_minus; // for R_minus
//check time for step
m01b: L 0; // load compare value
L #R_Time;
<D ; // if R_Time > 0 goto m01c
SPB m01c;
L 1; // else load default value
T #R_Time; // save default value
m01c: NOP 0;
NETWORK
TITLE =set StepRange
U #R_max;
UN #R_min; // if function should go to max
SPB m02a; // go to m02a
UN #R_max;
U #R_min; // if function should go to minimum
SPB m02b; // goto m02b
// if R_max = R_min the function aprouch Actual_Value to Null_Point
L #Null_Point; //
T #Temp_Rated_Value; // save Null_Point as temporary rated Value
SPA m02c;
// the function aprouch Actual_Value to Maximum
m02a: L #Max_Value; //
T #Temp_Rated_Value; // save Maximum as temporary rated Value
SPA m02c;
// the function aprouch Actual_Value to Minimum
m02b: L #Min_Value;
T #Temp_Rated_Value; // save Maximum as temporary rated Value
// check Actual Value < rated Value
m02c: L #Actual_Value;
>R ; // if Actual_Value < rated Value
L #R_plus; // load R_plus for Steprange
T #Temp_Step_Range; //
SPB m003; // goto m003
// check Actual Value > rated Value
L #Temp_Rated_Value; // load rated value
L #Actual_Value; //
<R ; // if Actual_Value > rated Value
L #R_minus; // load R_minus for Steprange
T #Temp_Step_Range; //
SPB m003;
// case Actual Value == rated Value
SET ; //
= #R_OK; // set Function done
BEA ; // exit
NETWORK
TITLE =correct steprange
m003: L 0;
SIMATIC ...\SIMATIC 400(1)\CPU416-1\...\FC10 06.12.1999 16:21:11
Seite 3..
L #MEG_Time;
<D ;
SPB m03a;
L 0.000000e+000;
T #Temp_Step_Range;
SPA m004;
// check R_Time < Cycle time of previous OB1 scan
m03a: L #R_Time; // load time for a step
L #MEG_Time; // load cycle time
<D ; //
SPB m03b; // if OB1Cycle > R_Time, goto m03b, adjust R_Time,
// // R_plus and R_minus
// Calculate temporary Range for Step ( Temp_Step_Range ), for
// OB cycle time <= time for Step
// ========================================================
// Calculate Proportion between R_Time and Cycle Time
L #R_Time;
DTR ;
L #MEG_Time;
DTR ;
/R ;
T #Proportion; // save Proprotion
// Calculate new value for steprange
L #Temp_Step_Range;
L #Proportion;
/R ;
T #Temp_Step_Range; // save new value
SPA m004;
// if OB1Cycle > R_Time multiply R_Time, R_plus, R_minus by 2
// ========================================
m03b: L #R_Time;
SLD 1;
T #R_Time;
L #R_plus;
L 2.000000e+000;
*R ;
T #R_plus;
L #R_minus;
L 2.000000e+000;
*R ;
T #R_minus;
SPA m003;
NETWORK
TITLE =Calculate new value for Actual_Value
m004: L #Temp_Rated_Value;
L #Actual_Value;
>R ; // if Actual_value < rated Value
L #Temp_Step_Range; // load calculated StepRange
SPB m04a; // go to m003
// aproach actual value to minimum
// ==================
SIMATIC ...\SIMATIC 400(1)\CPU416-1\...\FC10 06.12.1999 16:21:11
Seite 4
NEGR ;
L #Actual_Value;
+R ;
T #Actual_Value;
L #Temp_Rated_Value;
>R ;
BEB ; // if Actual_Value > Temp_Rated_Value exit
T #Actual_Value; // else save rated Value as Actual_Value
SET ;
= #R_OK; // set "done" bit
BEA ; // exit
// aproach actual value to maximum
// ================
m04a: L #Actual_Value;
+R ;
T #Actual_Value;
L #Temp_Rated_Value;
<R ;
BEB ; // if Actual_Value < Temp_Rated_Value -> exit
T #Actual_Value; // else save rated Value as Actual_Value
SET ;
= #R_OK; // set "done" bit
BEA ; // exit
END_FUNCTION
Link al commento
Condividi su altri siti


La lista istruzioni del 200 è differente dall'AWL del 300/400, quindi occorre convertire le istruzioni; qui:

http://support.automation.siemens.com/IT/llisapi.dll?func=cslib.csinfo&lang=it&siteid=cseus&aktprim=0&extranet=standard&viewreg=IT&objid=10805149&treeLang=it

trovi il manuale di sistema con le istruzioni del 200; quella che hai postato mi sembra una routine, non c'è indirizzamento, quindi non dovresti avere grossi problemi; l'unico dubbio è su queste righe:

// check R_Time < Cycle time of previous OB1 scan
m03a: L #R_Time; // load time for a step
L #MEG_Time; // load cycle time
<D ; //
SPB m03b; // if OB1Cycle > R_Time, goto m03b, adjust R_Time,
// // R_plus and R_minus
// Calculate temporary Range for Step ( Temp_Step_Range ), for
// OB cycle time <= time for Step

se fa quello che è scritto nei commenti, non so se esiste qualcosa di simile nel 200: al limite si può ovviare usando il temporizzatore di sistema.

Link al commento
Condividi su altri siti

Infatti ho cominciato a editare in microwin e a queste righe ho la x rossa....

Dovrò convertire le istruzioni manuali alla mano e provare che tutto funzioni.

Link al commento
Condividi su altri siti

Dai un occhio alle istruzioni BITIM e CITIM (in ladder BGN_ITIME e CAL_ITIME) del temporizzatore di sistema; se imposti la prima in testa al MAIN e la seconda in fondo sempre al MAIN (OB1), dovresti ottenere il tempo di scansione che ti serve.

Link al commento
Condividi su altri siti

Come si fa a scrivere il codice sul forum così come è adesso?

Io ho fatto un semplice copia e incolla, esiste una funzione apposta?

Saluti

Link al commento
Condividi su altri siti

  • 2 weeks later...

Ciao, sto dando un occhio alle differenze tra il set istruzioni per 200 e 300: CLR (resetta RLC (=0)), non trovo corrispondenza per 200; con quale istruzione posso resettare RLC = 0 ?

In AWL per 200 "L" diventa "LD" ?

Link al commento
Condividi su altri siti

Non ricordo di una istruzione simile a CLR nel 200; potresti scrivere una cosa del genere:

LD M1.0             // Inizio - Accesso al bit M1.0
AN M1.0             // M1.0 in serie negato
R   M1.0, 1         // Resetta 1 bit a partire da M1.0
// Così hai un bit sempre OFF

Avendo creato un bit sempre OFF, automaticamente ottieni lo stesso effetto che usare CLR, sempre che io ricordi bene ...

Per quanto riguarda LD, va usato sempre quando inizi un segmento (o catena), poi usi A, AN, O e ON per aggiungere in serie e paralello contatti, negati e non; non credo esista neanche L, ma devi usare le sue istruzioni, come in questo esempio preso dalla guida in linea:

LD  I0.0            // Inizio - se I0.0 ON
+I AC1 AC0          // Somma i due accumulatori - risultato in AC0
*I AC1 VW100        // Moltiplica AC1 per VW100 - risultato in VW100
/I VW10 VW200       // Divide VW200 per VW10 - risultato in VW200
Link al commento
Condividi su altri siti

Ciao Drugo, ok per il bit sempre ad off ma come faccio a caricare il valore del bit nella variabile #R_Ok?

In MicroWin non si ha la possibilità di creare FC ed FB, bisogna lavorare con subroutine ed interrupt ed gestire tutto nell' OB1....

Siccome in ob1 non si possono definire le variabili come richiesto nella prima parte del listato awl, ho creato una sbr0 e all'interno ho definito tutte le variabili come si vede da screenshoot allegato:

post-112421-0-01011200-1405419000_thumb.

Ora scrivo le righe che mi hai postato e vorrei assegnare il valore del bit M1.0 alla variabile #R_OK.....

Link al commento
Condividi su altri siti

Ciao,

diciamo che nel 200 non esistono gli FB con i blocchi DB di istanza, ma, in pratica, tutti i blocchi SBR sono equivalenti ai blocchi FC.

Se ho bisogno del bit sempre OFF, lo creo in quel modo in testa al MAIN (OB1); poi lo utilizzo, quindi nel passare il parametro #R_OK a SBR0 gli metti il tuo bit OFF; addirittura potresti passargli un negato a SM0.0, che nel 200 è il bit sempre ON (è da provare, perchè, definito il parametro come IN_OUT, non so se accetta un contatto negato o solo il bit).

Se vuoi, prova a postare quello che hai scritto finora (non mi sembra molto lungo), evidenziando i tuoi dubbi: posso darci un'occhiata e provare a consigliarti meglio ...

Link al commento
Condividi su altri siti

Mi correggo,

ho approfondito quello che devi fare e non si puo' convertire direttamente senza fare modifiche sostanziali:

CLR ;
= #R_OK; // Reset "Done" - Signal

se non ho capito male, qui, ogni volta che viene chiamata la routine, viene resettato il bit R_OK, per poi settarlo dopo, in determinate condizioni.

Non c'è modo di fare una cosa del genere con il 200, che io sappia: potresti provare con un reset del bit comandato da SM0.0 (bit di sistema sempre ON), ma c'è il rischio che il comando reset abbia comunque priorità più alta rispetto agli altri comandi sul bit (se la routine è chiamata sempre), quindi sarebbe da provare.

Link al commento
Condividi su altri siti

  • 2 weeks later...

Buongiorno, con il non piccolo aiuto di Drugo66 ho avuto la possibilità di capire l'ambiente MicroWin, totalmente diverso dal fratello maggiore Step7.

Per distrazione non avevo informato Drugo che la CPU in mio possesso è una 214, molto vecchia, per la quale ci sono non poche difficoltà a scrivere una routine del genere: non tutte le operazione di confronto e conversione sono disponibili, la 214 non accetta routine parametrizzate, le variabili IN OUT e per tante righe di programma si riceve l'errore "segmento troppo complesso....".

Ancora una volta il buon Drugo si è reso disponibile con spiegazione e dispendio di tempo per aiutarmi, per ora però non riesco a caricare ancora la routine nella cpu.

La routine potrebbe funzionare per le cpu serie 22x, purtroppo non in mio possesso, non ho intenzione di abbandonare il discorso, ho ancora qualche giorno a disposizione, poi andrò un po' in ferie, ma abitualmente, di carattere, mi piace che le cose funzionino, vedremo...

Aggiornerò questa discussione se ci fossero sviluppi, con Drugo66, quando avremo qualcosa di funzionante, ne pubblicheremo il risultato e gli accorgimenti presi per raggiungere lo scopo, anche una eventuale soluzione più semplice per la cpu 214.

Buona domenica a tutti gli amici del forum

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...