Jump to content
PLC Forum


Sign in to follow this  
aduri

pic ed encoder

Recommended Posts

aduri

Salve a tutti,

sto provando con insuccesso a gestire un encoder con il pic16F877a a 20MHz ma salta sempre degli impulsi.

Premetto che ho triggerato con un cd4093 i 2 segnali in quadratura dell'encoder.

Sapevo che i pic non sono piu' adatti ma quando ho visto che una rivista che reputo seria lo ha fatto ci ho provato anch' io.

L'encoder e' di quelli economici a microswitch.

Qualcuno sa darmi qualche dritta?

Allego 2 esempi in Mikrobasic uno con interrupt e l'altro senza che danno lo stesso problema.

'*
' * Project name: Rotary encoder
' * Description: Rotary encoder with interrupt
' * Test configuration:
'     board: My Board Aduri
'     MCU:             PIC16F877A
'     Oscillator:      HS, 20.000 MHz
'     Ingressi   :     A su RB4, B su RB1
'     SW:              mikroBasic v5.0 or higher
' * NOTES:
'     LCD su PORTD, trigger with CD4093
' *

program Rotary_encoder
dim temp as byte
dim txt as string[3]

sub procedure interrupt     ' Interrupt service routine
  If PORTB.4 = 1 then

    else
      If PORTB.1 = 1 then
      temp = temp - 1
        else
      temp = temp + 1
      end if
  end if
delay_ms(25)                     'delay
INTCON.RBIF = 0             ' interrupt flag disable
end sub

main:
  LCD_init(PORTD)        'LCD on portD
  TRISB = %11111111      'PORTB.1 and .4 are inputs
  INTCON = %10001000     ' Enable interrupt on change

while 1=1            ' loop
delay_ms(100)
bytetostr(temp,txt)
 LCD_out(1,1,"Nr pulses:")
LCD_out(2,1,txt)
wend

end.
e questo
program encoder_A
'     MCU:             PIC16F877A
'     Dev.Board:       Myboard
'     Oscillator:      HS, 20.000 MHz
'     Ext. Modules:    trigger with CD4093, Lcd_2x16
'PROGRAM TO DETERMINE DIRECTION OF QUADRATURE ENCODER

DIM PORTB_OLD AS BYTE
DIM PORTB_NEW AS BYTE
dim count as byte
dim txt as string[3]

'USING A 2 BIT (QUADRATURE SYSTEM) THIS IS THE RULE:
'LOW BIT OF OLD VALUE IS ALWAYS EQUAL TO HIGH BIT OF NEW VALUE
'IF MOVING CLOCKWISE
'LOW BIT OF OLD VALUE DOES NOT EQUAL HIGH BIT OF NEW VALUE
'IF MOVING COUNTERCLOCKWISE

main:
'TRISA = 0              'RA0 LED WILL INDICATE CW; RA1 LED WILL INDICATE CCW
TRISB = %00000011      'RB0 and RB1 Inputs
TRISC = 0
PORTA = 0
PORTB = 0
 LCD_init(PORTD)        'LCD su portD
 LCD_out(1,1,"Numero impulsi:")
 LCD_out(2,1,"Dir:")
PORTB_OLD = PORTB

my_direction:

PORTB_NEW = PORTB

IF PORTB_NEW XOR PORTB_OLD <> 0 THEN     'test for encoder change
   IF (PORTB_NEW >> 1) = (PORTB_OLD AND 1) THEN
      PORTC = 1        'CW DIRECTION
       LCD_out(2,6,"I")
       count = count-1
   ELSE
      PORTC = 0       'CCW DIRECTION
       count = count+1
       LCD_out(2,6,"A")

   END IF
END IF
 bytetostr(count,txt)
     LCD_out(1,18,txt)


PORTB_OLD = PORTB_NEW

GOTO my_direction

end.

ciao

Antonio

Share this post


Link to post
Share on other sites

Livio Orsini

Manca un dato importante: la frequenza dell'encoder.

Io uso da parecchio tempo il PIC come interfaccia encoder senza problemi sino >20kHz di frequenza encoder, però uso due routines in assembler sugli ingressi da interupt esterno (quelli sulle porte cool.gif.

Tieni presente che con quarzo da 20MHz il pic esegue un'istruzione in 200ns; con frequenza di encoder a 20kHz si eseguono 250 istruzioni tra due impulsi. Le routines di servizio interrupts eseguono <10 istruzioni, quindi hai ancora più di 200 instruzioni libere prima di amndare il processore in hung up.

Tu scrivi in basic e le istruzioni si sprecano...

Share this post


Link to post
Share on other sites
aduri

Innazitutto grazie della risposta.

Premetto che ho fatto una imprecisione nel mio post.

In effetti l'encoder ne conta di piu' di quanto dovrebbe di impulsi pero' discrimina perfettamente il verso.

L'encoder che ho utilizzato per le prove non so' se si puo' considerare tale perche' e' del tipo meccanico ultra economico usato nelle autoradio per la regolazione del volume.

Ne ho un'altro ottico che invece e' piu' serio con risoluzione 256 inpulsi a giro.

Gli encoder vorrei usarli come contaimpulsi per vari utilizzi (tipo contagiri per bobinatrice e per usarli per una sintonia digitale di una radio).

Share this post


Link to post
Share on other sites
Livio Orsini

Quello che ho scritto sopra vale comunque. Se ti conta più impulsi del dovuto è una questione di "spifferi".

E' sempre meglio fare un discriminatore esterno Hw. Se usi i DSPic hai già integrato nel micro il rivelatore di quadratura. Questi rivelatori fanno anche una funzione filtrante, evitando così di conteggiare impulsi spuri. Io, con i Pic, uso un'interfaccia optoisolata costituita da un doppi D FF: 74HC74, l'uscita Up e l'uscita Down li mando a due ingressi interrupts. Mai avuto problemi di falsi conteggi.

Share this post


Link to post
Share on other sites
aduri

Io ho triggerato gli ingressi con un CD4093 ma a quanto pare non basta.

Non vedo differenza tra con e senza scheda filtro.

Probabilmente non e' ben dimensionata la soglia di intervento.

Cortesemete potresti postare lo schema della scheda opto?

Grazie

Share this post


Link to post
Share on other sites
Livio Orsini

Non è questione di opto o di soglia è una questione di quadratura. L'impulso è ritenuto valido solo se sono presenti i due impulsi sfasati di 90 gradi. Ora non ho sottomano la copia pdf del discriminatore, appena la metto su questo PC la metto on line.

Comunque questo filtraggio lo puoi fare anche software, perdi un po' di tempo di CPU, ma se non vai velcoe con gli impulsi non succede nulla. Bisogna considerare il fronte di un canale rispetto allo stato dall'altro e non accettare impulsi se non sono state ripristinate le condizioni di partenza.

Una nota operativa. L'uso della funzione "delay_" in una routine di interrupt è da evitatrsi. Anzi sarebbe da evitare sempre perchè durante la funzione la CPU "gira i pollici"

Edited by Livio Orsini

Share this post


Link to post
Share on other sites
aduri

Salve a tutti,

sono riuscito a far funzionare perfettamente il secondo codice senza interrupt con un encoder ottico collegato ad un motore.

Con l'encoder meccanico anche col filtro e trigger col CD4093 conta sempre piu' di quanto dovrebbe.

Non ho ancora provato a mettere dei condensatori in parallelo ai contatti ma non so come dimensionarli (con la costante di tempo tau della scarica dei condensatori??).

Appena l'ottimo Livio Orsini mettera' in linea il suo discriminatore lo provero'.

Grazie di nuovo dell'aiuto

Share this post


Link to post
Share on other sites
walterword

alcuni pic hanno dell eperiferiche gia predisposte per leggere il conteggio degli impulsi derivati da un encoder e resettare tale registro

Bene il basic , mikro basic ect , ma io resterei sul C

Se usi un dspic il cui costo poco differisce da un 877 , anzi costa meno , hai una cpu a 16 bit con tanta di quella roba che nemmeno te lo immagini

Scarichi gratis mplab e poi la versione student del compilatore C30 che e' una bomba .Il basic .....

Share this post


Link to post
Share on other sites
ifachsoftware

Per decodificare in hardware un encoder puoi usare questo schema : Decodifica Encoder

che ti ritorna un impulso sul segnale di avanti ed uno sul segnale di indietro , effettuando la decodifica e lasciando al PIC il solo compito di incrementare o decrementare sotto interrupt un contatore.

Con quell'esempio devi usare 2 interrupt , ma con una piccola modifica hardware puoi generare un solo interrupt e portarti su un pin normale il segnale di indietro e quando entri nell'interrupt a seconda el pin di indietro decrementi o incrementi il tuo contatore....

Ciao smile.gif

Share this post


Link to post
Share on other sites
NeXtor
ifachsoftware+7/06/2008, 09:41--> (ifachsoftware @ 7/06/2008, 09:41)

Sono interessato anche io alla lettura di un encoder...

Vorrei visualizzare su un display il senso di rotazione e gli impulsi.

Utilizzando lo schema che hai postato, dovrei solo far incrementare al pic una variabile (impulsi) in base al pin (indietro o avanti) che attiva l'interrupt e quindi tramite lo stesso pin sapere se va, come dice il pin stesso, avanti o indietro giusto?

Share this post


Link to post
Share on other sites
ludo69

scusate se dico la mia, non ho mai programmato un PIC ma ho avuto spesso a che fare con segnali affetti da rumori....

Quando un interruttore meccanico si chiude genera dei rimbalzi che un circuito logico è in grado di vedere, quindi se è un contatore è in grado di contarli! temo appunto che il PIC conti i rimbalzi dell'interruttore, ma basterebbe che ne contasse uno e che poi ignorasse gli altri a meno che non cambi stato l'altra linea in quadratura, ovvero a meno di un'avvenuto avanzamento (REALE) dell'alberino.

Se non sbaglio i vari circuiti HW proposti fanno questo: 1bit di "avvenuto conteggio" su ogni linea in quadratura resettato dall'attivazione dell'ALTRA linea in quadratura.

Mettendo questa "finestra" legata al logico divenire dei segnali si riesce a discriminare correttamente l'informazione cercata.

Ovviamente i sensori ottici (encoder ottico) non hanno rimbalzi e un'ingresso a trigger di smith è sufficiente ad interfacciare questo segnale analogico (nel senso delle possibili lente transizioni tra i livelli logici) con l'entrata digitale.

Edited by ludo69

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...