Esempio di calcolo velocità rotazione RPM
Home › Forum › Programmazione IEC 61131 (LogicLab) › Esempio di calcolo velocità rotazione RPM
- Questo topic ha 9 risposte, 4 partecipanti ed è stato aggiornato l'ultima volta 9 anni, 7 mesi fa da
Sergio Bertana.
-
AutorePost
-
Ottobre 4, 2013 alle 3:40 pm #35429
Luis
PartecipanteVolevo un aiuto per fare un programma che mi calcola i giri al minuto di un albero, volevo utilizare i ingresi DI0 E DI1 della CPU SlimLine Compact. Vi ringrazio in anticipo.
Ottobre 7, 2013 alle 6:54 am #37820Sergio Bertana
Amministratore del forumNon mi dici quale è il range di velocità da misurare, gli ingressi del modulo accettano a livello elettrico una frequenza massima di 10 Khz. Ma se si ipotizza una gestione tutta software è possibile campionare gli ingressi inserendo un programma nella task Fast al massimo ogni 100 uS (Vedi funzione SysSetTaskLpTime). Quindi ipotizzando che il tuo segnale abbia un Duty-Cycle del 50% la frequenza massima campionabile da software è 4 Khz.
L’ingresso DI00 è connesso ad un counter hardware è quindi può lavorare alla frequenza massima definita, per la gestione del counter si utilizza il blocco funzione SysGetCounter.
Perché ho parlato di counter, perché per calcolare la velocità di rotazione di un albero si contano gli impulsi generati in un determinato tempo. Se l’albero gira molto piano puoi usare addirittura come base tempi il minuto ed allora il numero di impulsi è direttamente la velocità in RPM, naturalmente verrà aggiornata ogni minuto.
Se l’albero gira molto velocemente invece puoi campionare con tempi inferiori e per avere la velocità in RPM dovrai seguire le opportune moltiplicazioni.
Ottobre 7, 2013 alle 9:01 am #37821Sergio Bertana
Amministratore del forumAggiungo un semplice programma eseguito in Fast che calcola la velocità di rotazione (Stampa e Download programma). Nel programma ho acquisito l’ingresso digitale DI00 del modulo CPU, ed eseguo il conteggio software delle variazioni. Controllo solo i fronti di salita, ma è possibile anche contare quelli in discesa, in questo caso avrò un conteggio doppio degli impulsi.
Ogni 10 secondi calcolo il numero di impulsi conteggiati, e da questo valore calcolo la velocità di rotazione (Supponendo 1 impulso al giro, se sono più impulsi al giro occorre fare i dovuti calcoli). Nel calcolo ho utilizzato la variabile MemoCtr anziche azzerare Counter perché in questo modo ho dimostrato come sia possibile conteggiare differenza di valore su di una variabile in continua evoluzione.
Questo torna comodo ad esempio quando si utilizza il blocco funzione SysGetCounter che ritorna un valore in continua evoluzione e che si può azzerare solo con l’ingresso hardware di Reset se disponibile. In questo topic trovi altre informazioni.
Ottobre 10, 2013 alle 6:00 am #37835Luis
PartecipanteGrazie Bertaser, adesso tutto è più semplice grazie al tuo aiuto, volevo chiedere si esiste una guida di programazione in ST.
Gennaio 14, 2014 alle 7:20 pm #37990Paolo
PartecipanteBuonasera dovrei rilevare i giri di un albero in cui e montata una ruota fonica (10 impulsi giro) velocità massima 80 giri minuto, ho montato un sensore di prossimita induttivo diametro 12 mm, ho provato il programma indicato nel post precedente modificando i tempi di aggiornamento a 1secondo.
Tutto funziona ma c’è un oscillazione di di 56 giri, visualizzo una velocita dell’albero di 7580 RPM mentre quella reale e di 7576 RPM, l’out del proximity e collegato sull’ingresso 0 della cpu MPS050*010, come posso risolvere il problema di questa oscillazione ?
Gennaio 15, 2014 alle 3:58 pm #37991Sergio Bertana
Amministratore del forumDa quanto mi dici immagino tu abbia modificato il calcolo velocità nel modo:
IF ((SysGetSysTime(TRUE)-TimeBf) < 1000000) THEN RETURN; END_IF;
TimeBf:=SysGetSysTime(TRUE); (* Time buffer (uS) *)
(* Ogni 1 secondo calcolo velocità, RPM=(Impulsi*60)/10. *)
MemoCtr:=Counter-MemoCtr; (* Memo counter *)
Speed:=(TO_REAL(MemoCtr)*60.0)/10.0; (* Velocità (RPM) *)
MemoCtr:=Counter; (* Memo counter *)Nel calcolo di Speed moltiplico per 60 per avere velocità in giri/min e divido per 10 perché la tua ruota genera 10 impulsi giro. Volendo si semplifica in Speed:=TO_REAL(MemoCtr)*6.0; Ora moltiplicando il numero di impulsi per 6 è evidente che la tua risoluzione è di 6 giri/min, basta la differenza di un impulso per avere +/- 6 giri. Per migliorare puoi:
Trasformare la linea IF (Pulse) THEN Counter:=Counter+1; END_IF; in Counter:=Counter+1; in questo modo conti sia il fronte di salita che quello di discesa ed hai 20 impulsi giro anziché 10 così moltiplicando per 3 avrai un errore di +/- 3 giri/min. Campioni ogni 2 o più secondi, l’errore si divide ad ogni multiplo di tempo, ma la lettura è più lenta.
Se utilizzi il doppio fronte e campioni ogni 3 secondi avrai Speed:=(TO_REAL(MemoCtr)*20.0)/20.0; in pratica la velocità è pari al numero di impulsi campionati, in questo modo la risoluzione è di +/- 1 giro.
Gennaio 16, 2014 alle 8:59 am #37992Sergio Bertana
Amministratore del forumAggiungo ancora una considerazione a quanto detto precedentemente, se vuoi più precisione devi calcolare la velocità usando un numero maggiore di punti di campionamento, quindi o aumenti il tempo di campionamento o aumenti il numero di impulsi giro.
Se vuoi più “fluidità” nel valore, cioè avere una variazione di valore che non sia a scatti puoi utilizzare la FB Average sul valore di velocità (Vedi post). Naturalmente anche questo introduce un ritardo nella acquisizione ma media le variazioni di lettura.
Gennaio 21, 2014 alle 10:51 am #38010Paolo
PartecipanteCon le modifiche da te suggerite rimane stabile nella lettura.
Settembre 4, 2015 alle 9:31 am #39059Gianluca
PartecipanteNell’esempio riportato in precedenza non veniva resettato il contatore, non c’è pericolo che una turbina girando vada in overfolw ?
Settembre 10, 2015 alle 10:23 am #39060Sergio Bertana
Amministratore del forumCredo tu ti riferisca alla riga di programma Counter:=Counter+1;
Sicuramente la variabile Counter và in overflow ma quando si esegue il calcolo MemoCtr:=Counter-MemoCtr; operando su variabili senza segno della stessa dimensione (Esempio UINT o UDINT) si ha la gestione del rapporto circolare ed il risultato è sempre corretto.
Se provi ad eseguire il calcolo MemoCtr:=Counter-MemoCtr; con MemoCtr=16#FFFFFFFF e Counter=16#00000004 ti troverai in MemoCtr il valore 5 che è appunto il numero di impulsi conteggiati tra le due letture di Counter anche se Counter ha avuto nel frattempo un overflow.
-
AutorePost
- Devi essere connesso per rispondere a questo topic.