Vai al contenuto
PLC Forum


Controllare La Velocita Motore Con Encoder


roberto8303

Messaggi consigliati

Mi potreste aiutare a capire come posso usare un encoder 3600imp/giro per misurare la velocita di un motore da 200 a 3000giri min...credo che bisogna usare un interrupt a tempo ma ogni quanti ms?? il motore accelera da min a max in circa 2 secondi ce la faccio a seguire la rampa con l interrupt?

Link al commento
Condividi su altri siti


ho trovato questa discussione molto interessante praticamente quello che serve a me riporto il messaggio di Livio Orsini e voglio fare propio come consiglia lui! :)

Il contatore lo fai andare in free running. Poi ti crei un interrupt a tempo con il timer di sistema. L'intervallo di tempo lo stabilisci in funzione delle tue esigenze. Ad ogni interrupt leggi il valore del contatore e lo memorizzi. In un altra Sub fai la differenza tra la lettura attuale e la precedente, il risultato è la velocità media nel tempo di misura. Conoscendo il la costante impulsi/giro ti ricavi la velocità angolare o, usando la costante impulsi/metro, la velociotà lineare.

come faccio a ricavare la velocita angolare conoscendo la costante impgiro 3600?

il contatore veloce devo impostarlo senza il reset ogni giro?

Link al commento
Condividi su altri siti

Immagina di aver impostato l'interrupt a 50ms. Immagina, per esempio, di aver letto 4500 impulsi come differenza di conteggio tra due letture. Come puoi sapere a che velocità sta ruotando il tuo motore?

Semplice. 3600 ipr * 3000rpm = 10.800.000 impulsi al minuto alla massima velocità, corrispondenti a 180.000 imp/1" => 9000 imp/50ms. Da questo avrai 9000:3000 = 4500: x Quindi la tua velocità sarà data da Delta_impulsi*(3000/9000) ovvero

w = delta_impulsi / 3.

Il contatore può andare in free running, l'unica precauzione è quando il risultato della sottrazione è negativo, significa che ha traboccato(ha fatto il "giro") quindi devi gestirlo, ma è facile.

Piuttosto con questo encoder e questo motore non puoi usare il contatore veloce dello S7-22x perchè la massima freqaunzadi conteggio è 20kHz (se ricordo bene) mentre qui hai ben 180kHz! :(

Link al commento
Condividi su altri siti

Caro Livio a costo di fare pratica e imparare lo faccio comunque! hai detto max 20khz? bene allora l encoder ce l ho ,i motori di tutti i tipi quindi usero un 6 poli e lo faccio andare con l inverter!...a 20khz il mio plc puo con questo encoder risolvere al max 330 giri/min giusto? e per ora mi accontento di questo!

allora aggiorniamo un po i calcoli

3600ipr * 300rpm =1.080.000 impulsi al minuto alla massima velocita

al secondo saranno quindi 18.000 che diviso 20 fanno 900 imp/50ms

da questo quindi 900 / 300= 450 / x qui non ha capito da dove esce 450?? e poi il delta e il diviso 3...mi puoi chiarire un po questo? :unsure:

Link al commento
Condividi su altri siti

Immagina, per esempio, di aver letto 4500 impulsi come differenza di conteggio tra due letture.

9000:3000 = 4500: x

Quindi la tua velocità sarà data da Delta_impulsi*(3000/9000) ovvero

w = delta_impulsi / 3.

1/3 = 3000/9000

delta_impulsi = numero di impulsi come differenza di conteggio tra due letture.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

non avevo letto bene.. :)

quindi per il progamma che per me è la cosa piu difficile faccio cosi

nel programma principale chiamo con sm01 una sub dove scrivo il temporizzatore da 50ms e nel interrupt leggo hco e lo memorizzo in una dwxx

in altra sub quella dove faccio la differenza deve essere (la sub) letta sempre con sm0.1 dal programma principale?

la differenza avviene con il valore del contatore in free running cioe propio hco?(senza il ciclo di 50ms...)

ricavata questa differenza la velocita sara =differenza /3 ?

Link al commento
Condividi su altri siti

NO.

Fai un interrupt, per esempio a 50 ms. Nel sub di servizio dell'interrupt leggi HCO e lo memorizzi in un DW. Poi esegui la differenza tra questa lettura e quella precedente (old_cnt), che avrai memorizzato. Memorizzi il risultato della differenza nella memoria di delt_imp, copi l'ultima lettura nella memoria di quella precedente (old_cnt) ed esci dalla sub di int.

In altra parte del programma, dove ti fa comodo, usi il valore di delt_imp per calcolarti la velocità.

Attenzione, questo metodo ha vantaggi e svantaggi, come tutti i metodi. Quando al velcità è bassa per avere una buona precisione dovresti avere la base tempi di misura, i 50 ms. dell'esempio, molto lunga, magari anche alcuni secondi. però se l'allunghi troppo l'aggiornamento della velocità è molto lento. Quindi devi scegliere l'interrupt a tempo in funzione del numero d'impulsi che ti danno una precisione decente a bassa velocità.

Con quel numero d'impulsi e le velocità in gioco io comincerei con 100 ms di tempo di campionamento.

Link al commento
Condividi su altri siti

quindi

Poi esegui la differenza tra questa lettura e quella precedente (old_cnt), che avrai memorizzato. Memorizzi il risultato della differenza nella memoria di delt_imp, copi l'ultima lettura nella memoria di quella precedente (old_cnt) ed esci

la old cnt risiede nell interrupt a tempo 50ms?

il box con la differenza lo devo scrivere nel main?

Livio il manuale l ho letto pero non riesco ancora a capire bene dove scrivere i segmenti se nel main sub o interrupt :( ho visto che nell interrupt bisogna scrivere solo il necessario per non impegnare troppo la cpu, ho capito come generare un interrupt a tempo come dall esempio del manuale,ma quando devo fare un applicazione come in questo caso mi trovo in difficolta a seguirti analizzando anche parola per parola!!mi dispiace crearti problemi a darmi spiegazioni anche perche mi hai gia insegnato un posizonatore :) !!!

Link al commento
Condividi su altri siti

old_cnt è una variabile e risiede nelle....varabili, cioè nei dati.

L'operazione di sottrazione e le operazioni di memorizzazioni le fai nella sub di interrupt.

Il calcolo della velocità lo fai nella sub di calcolo della velocità

Nel main fai la chiamata, quando serve, alla sub di calcolo della velocità. Non è una regola scritta, ma un metodo decente per programmare, prevede che nel main si scrivano, praticamente, solo le chiamate alle varie funzioni e la logica necessaria ad eseguirle o saltarle.

Link al commento
Condividi su altri siti

L'operazione di sottrazione e le operazioni di memorizzazioni le fai nella sub di interrupt.

sub di interrupt sarebbe nella sub oppure l interrupt legato a quella sub?

Link al commento
Condividi su altri siti

Livio ho iniziato a fare qualcosa...ma se ora mettiamo 100ms come tempo di campionamento cosa cambia ?

allora se ho una differenza di 450 impulsi come delta w

la velocita sara 450 : 3 quindi 150 giri min? oppure variando 100 ms cambia ?

Link al commento
Condividi su altri siti

Ecco fatto...

nel interrupt tempo ogni 100ms ho letto hco e caricato in vd100

nel main ho caricato hc0 in vd 200

di nuovo nell interrupt tempo ho fatto la sottrazione di vd200 - vd100 e il risultato l ho messo in vd300

nel main ho fatto la divisione D_I Vd300 : 3 e il risultato in vd 400...

vado nella tabella di stato

leggo i numeri che si aggiornano ruotanto a mano velocemente l encoder...

nella vd 300 esce al max 4...

nella vd 400 tra 0 e 1 o negativo a volte...

ho sbagliato?

Link al commento
Condividi su altri siti

ho sbagliato?

Sì.

Per prima cosa, non devi fare metà operazioni nella sub a tempo e metà nel main. Le operazioni vanno eseguite tutte nella sub a tempo e basta.

Poi, le operazioni da fare sono le seguenti:

- sottrazione tra valore attuale HC0 e VD100. Il risultato lo memorizzi in VD104

- memorizzazione del valore attuale di HC0 in VD100, che servirà per il prossimo controllo.

In VD104 trovi il numero di impulsi contati nel tempo impostato per l'esecuzione dell'interrupt, ed è questo valore che devi utilizzare per fare i successivi calcoli.

Insomma, più semplice di quello che sembra.

Una domanda: gli indirizzi delle variabili sono da prendere solo come esempio, ma non capisco perché utilizzi VD100, VD200, VD300 e così via.

E tutte le variabili che ci stanno in mezzo, che fanno?

Perché non utilizzi variabili contigue, tipo VD100, VD104, VD108....?

Link al commento
Condividi su altri siti

Allora vediamo di chiarire un concetto fondamentale.

L'interrupt a tempo serve per stabilire una base tempi precisa e affidabile e, soprattutto, costante. E', in pratica, l'orologio con cui misuri il tempo.

Nella sub legata all'interrupt è fondamentale leggere il contatatore. Teroricamente le altre operazioni potrebbero non essere effettuate in quella sub. Nella pratica è conveniente arrivare sino alla misura del numero degli impulsi contati tra due letture. Quindi eseguire sottrazione e memorizzazione del delta impulsi e dell'ultima lettura del contatore.

Se cambi il tempo di misura cambia, ovviamente, la costante usata per il calcolo della velocità. La costante la ricavi moltiplicando il numero di giri al secondo, dell'encoder, per il numero di impulsi a giro del medesimo. Questo numero dovrà essere moltiplicato per la base tempi. Se la base tempi è, ad esempio, 100 ms (0,1") lo moltiplicherai per 0,1. Se è 50 ms (0,05") la moltiplicazione sarà per 0,05. Così via secondo base tempi.

Link al commento
Condividi su altri siti

Buongiorno!

prima cosa grazie per gli ulteriori chiarimenti ad entrambi che vanno al di fuori della nostra applicazione...purtroppo a me servono molto per imparare anche se capisco che per voi sono delle ''bazzecole'' e quindi possono scocciare a spiegarle continuamente...quindi grazie sopratutto di questo!

Ora veniamo a noi

X Batta

Hai ragione devo abituarmi ad usare vdxx contigue non l ho fatto perche in questo caso ne sono solo 4 di VDxx se ne dovevo usare di piu sicuramente non avrei neanche potuto farlo... :)

inoltre mi è molto chiara la tua spiegazione in generale...

X Batta e Livio

Perche continuate a chiamare sub a tempo invece di chiamare interrupt a tempo? cioe i calcoli li faccio nell interrupt ogni 100ms giusto?

Per me quando dite sub a tempo o la sub legata all interrupt significa SBR_0 e (non INT_0 ) è sbagliato?

X Batta

In VD104 trovi il numero di impulsi contati nel tempo impostato per l'esecuzione dell'interrupt, ed è questo valore che devi utilizzare per fare i successivi calcoli

quindi i successivi calcoli li faro nella SBR_0?

Chiarito questo mi sara tutto molto piu facile e potro iniziare a svolgere questo ''compitino'' grazie ancora!! ;)

Link al commento
Condividi su altri siti

Perche continuate a chiamare sub a tempo invece di chiamare interrupt a tempo?

L'interrupt è una funzione del processore attivata da un evento solitamente hardware: ingresso fisico, periferiche interne (contatori, timer, USART, etc) e da allarmi di sistema. All'interrupt può essere associata un sottoprogramma chiamato direttamente dal vettore di interupt, quindi si definisce quelsottoprogramma come sottoprogramma associato all'interrupt xy (interrupt a tempo nel tuyo caso). E' detta comunemente, anche, routine di servizio per l'inteerupt xy.

quindi i successivi calcoli li faro nella SBR_0?

Assolutamente NO! La SBR_0 deve essere usata esclusivamente per le operazioni di inizializzazione; deve essere eseguita una, ed una sola volta al power-on

Nella sub di interrupt devi assolutamente eseguire, nell'ordine, la lettura del contatore, il calcolo della differenza impulsi tra due letture e sua memorizzazione, memorizzazione della lettura attuale nella memoria per il ciclo successivo.

Queste sono le operazioni indispensabili per una corretta gestione.

Devi valutare tu se aggiornare anche il calcolo di velocità in questa sub, oppure effettuare una funzione ad hoc richiamata dal main secondo necessità.

Non c'è una regoal precisa; io valuto di volta in volta quale è la strategia migliore per l'applicazione.

Link al commento
Condividi su altri siti

ecco ora ho capito!!appena posso rifaccio tutto e ti faro sapere subito ;) ah se avessi avuto avuto queste curiosita ai tempi della scuola.... :)

Link al commento
Condividi su altri siti

allora ho ripreso tutto...

ho fatto nell sub di interrupt (richiamata dalla sbr_0 ogni 100ms ) le due operazioni..

mov Dw di hco in vd100

sottrazione D_I tra hco - vd100 = in vd104

ora quali calcoli devo fare nella sub di calcolo velocita per conoscere la velolcita? imp giro encoder 3600 velocita max 300 rpm e interrupt di 100ms...

Link al commento
Condividi su altri siti

io ho usato un metodo complementare, in pratica lancio un interrupt quando il valore del contatore veloce raggiunge un determinato numero di impulsi, nell'interrupt lancio la funzione bgntime che salva il valore in millisecondi di un temporizzatore di sistema della cpu.

A questo punto ricarico il contatore e un secondo interrupt, nel secondo interrupt faccio igntime che calcola la differenza di tempo tra il secondi interrupt e il primo.

Queste funzioni però ci sono solo sulle cpu di massimo un paio di anni.

Non so quale dei due sistemi possa essere più leggero per la CPU

Link al commento
Condividi su altri siti

.....imp giro encoder 3600 ...

Semplice. In un minuto hai 600 volte l'interrupt da 0.1". In VD104 hai il numero d'impulsi contati in 0.1", lo moltiplichi per 600 e hai gli impulsi relativi ad 1', poi dividi per il numero di impulsi per giro, 3600, e hai il numero di rpm. In pratica devi dividere per 6 il valore di VD104.

io ho usato un metodo complementare,...
E' il metodo più efficace per avere buone precisioni a basse velocità. La precisione dipende dal numero d'impulsi usato come soglia e, soprattutto, dalla precisione con cui si misura il tempo.

Come controindicazione si ha che al misura di velocità avviene in tempi variabili in funzione della velocità stessa.

Nelle misure che richiedono buona precisione anche a bassa velocità si usa un algoritmo che è un mix delle due procedure: periodimetro (questo) e frquenzimetro (il precedente). Però con un PLC non è molto agevole da implementare

Link al commento
Condividi su altri siti

ho provato l encoder a banco senza collegarlo al motore e girandolo a mano velocemente non riesco ad incrementare vd104 piu di 1!! sembra funzionare ma Livio quante è la velocita minima che posso rilevare con 100ms (giri al min)?l ultima operazione è la vd104 diviso 6 nella operazione div_Di nella SBR_2 richiamata dal programma con Sm0.0 ,

quindi dovrei avere 6 impulsi di differenza tra hco reale e hco nell interrupt ogni 0,1'' in modo da ottenere come risultato della divsione 1 che sarebbe un giro al minuto...ora perche gia nel vd104 non riesco a superare un unita eppure mi sembra che faccio piu di un giro al min anche se ruoto l alberino cn le dita..

Link al commento
Condividi su altri siti

1 Verificare che l'interrupt avvenga ogni 100 ms

2 Verificare anche i conteggi di HCO

3 Verificare gli impulsi dell'encoder

4 Verificare che lettura, memorizzazione e conti siano corretti

Link al commento
Condividi su altri siti

Ovviamente stasera verifico tutto!! ma secondo me se nell interrupt carico hc0 in Vd100 e sempre nel interrupt faccio la sottrazione è come se hco caricato in vd 100 viaggia alla stessa differenza di tempo della sottrazione ogni 100ms ma differenza di tempo 0...non so se mi spiego cosa voglio dire...

Link al commento
Condividi su altri siti

per poter avere il campionamento occore un numero di impulsi di hc0 contato all istante e un altro ogni 100ms in modo che si verifichi la differenza cioe il ritardo nel tempo ben preciso nel nostro caso 100ms.... se io pero aggiorno hc0 ogni 100ms ed eseguo la differenza ogni 100ms come rileviamo la differenza di impulsi nel tempo se sono entrambi a 100ms ?

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