Sari la conținut
ELFORUM - Forumul electronistilor

Citire rotary encoder


Postări Recomandate

New_Bits=GPIO & %110000 >>4loop:     New_Bits = GPIO & %110000 >> 4                       If (New_Bits & %110000) = (Old_Bits & %110000) Then DoneRotEnc    RotEncDir = New_Bits.4 ^ Old_Bits.5     If RotEncDir = 1 Then        led1=1        delayms 1000        led1=0        delayms 1000    Else        led2=1        delayms 1000        led2=0        delayms 1000    EndIf    GoTo loopDoneRotEnc:     Old_Bits = New_BitsGoTo loop

Pune, te rog, programul complet.

Asta e programul complet ?

Inteleg din program ca folosesti GPIO4 si GPIO5 conectati la Encoder.  Este corect ?

Link spre comentariu

Daca tot incepem codam, codez si eu. :) 

New_Bits=GPIO & %110000Old_Bits=GPIO & %110000loop:     New_Bits = GPIO & %110000                       If New_Bits <> Old_Bits Then        RotEncDir = New_Bits.4 ^ Old_Bits.5        If RotEncDir = 1 Then         led1=1         led2=0       Else         led2=1         led1=0       EndIf        EndIf    Old_Bits = New_BitsGoTo loop
Editat de Liviu M
Link spre comentariu
New_Bits=GPIO & %110000 >>4loop:     New_Bits = GPIO & %110000 >> 4                       If (New_Bits) >0 Then DoneRotEnc            led1=1        delayms 1000        led1=0    GoTo loopDoneRotEnc:     Old_Bits = New_BitsGoTo loop

Cand se aprinde LED-ul acum? Cand rotesti sau cand nu e rotit ?

<<sa folosesc intreruperi,>>

Nu stii ce te astepta cu intreruperile. Multi spun asta ca.....de fapt asa au citit pe undeva.

 

Intr-adevat ar trebui sa fie intrerupere, daca dai volulul mai tare la muzica.

Dar aici...........

Link spre comentariu

incearca asha:

 

New_Bits=GPIO & %110000 >>4loop:     New_Bits = GPIO & %110000 >> 4                       If (New_Bits) >0 Then DoneRotEnc            led1=1        delayms 1000        led1=0    GoTo loopDoneRotEnc:     Old_Bits = New_BitsGoTo loop

Cand se aprinde LED-ul acum? Cand rotesti sau cand nu e rotit ?

<<sa folosesc intreruperi,>>

Nu stii ce te astepta cu intreruperile. Multi spun asta ca.....de fapt asa au citit pe undeva.

 

Intr-adevat ar trebui sa fie intrerupere, daca dai volulul mai tare la muzica.

Dar aici...........

 

 

Care e scopul acestui cod ? sau ce ar trebui sa faca ?

Editat de djvas
Link spre comentariu

Mondan,codul trebuie sa detecteze modificarile pe pinii respectivi si, mai ales, succesiunea lor. Daca sari peste evenimente, te chinui degeaba.Cu "testat portul din cand in cand" functioneaza doar daca controllerul e relativ neocupat. Daca vrei sa faca si altceva nu doar sa pazeasca pinii cu encoder, nu prea scapi de intreruperi.Si unii dintre noi vorbesc dupa ce au realizat practic un "cititor de encodere".

 

Succes,

Liviu

Link spre comentariu

Care e scopul acestui cod ? sau ce ar trebui sa faca ?

Am scris si inainte. Sa aprinda un led daca se roteste spre stanga, si alt led daca ii spre dreapta.

Asta doresc sa faca codul respectiv.

Bineinteles ca softul va face mai multe, iar citirea encoderului o voi face cu intreruperi.

Dar pana acolo, o iau pas cu pas, sa reusesc sa citesc encoderul si sa se aprinda ledurile.

Nu mai am posibilitatea sa testez decat sapt viitoare. 

Pana atunci, va multumesc pentru idei si sfaturi.

Link spre comentariu

Mondan,Cu "testat portul din cand in cand" functioneaza doar daca controllerul e relativ neocupat.

Exact!

 

 

Si pare controller ocupat sa aprinda 2 LED-uri ? :rade:

-----------------

Codul nu are cum sa fie complet, led1=0 trebuie specificat led1=GPIO......

 

------------------

 

As vrea sa vad cand terminati voi codul asta ! Si sa merga celui care a intrebat, ca doar asta e scopul!

Da, normal ca se face cu intreruperi, dar explicati voi cuiva pe internet daca puteti.

 

El nu mi-a raspuns nici daca se aprind continuu LED-urile, ca nu are timp, ceea ce e un program banal.

Voi credeti ca va lucra usor cu intreruperile. Eu banuiesc ca nu stie la ce sa se astepte cu intreruperile.

 

Eu am lucrat cu intreruperi in ASM cu vectorul de intrerupere la 0x004, daca imi amintesc bine si vrectorul reset la 0x000

In C e mai simplu ca scrii void interrupt ........

Dar nu cred ca ai aceeasi libertate ca in ASM.

De exemplu sa faci jump dintr-o procedura in alta

Sa scrii cod in interiorul unui Delay

Sa calculezi timpul de executie.

Editat de Mondan
Link spre comentariu

 

 

Cand se aprinde LED-ul acum? Cand rotesti sau cand nu e rotit ?

 

 

El nu mi-a raspuns nici daca se aprind continuu LED-urile, ca nu are timp, ceea ce e un program banal.

Ca sa raspund (din nou) la intrebarile de mai sus:

Cand se roteste spre stanga se aprinde un led 1 secunda, apoi se stinge. Cand se roteste spre dreapta, la fel, se aprinde alt led 1 secunda apoi se stinge. 

Nici nu am spus ca codul e complet, din contra, am specificat ca nu e complet. 

Am mai lucrat cu intreruperi, nu e prima data...

Ce nu imi iesea, era citirea acelui encoder. Am inteles acum unde am gresit in cod, chiar daca nu am testat inca codul. 

Va doresc o duminica placuta.

Link spre comentariu

Salut,

 

Nu stiu daca mai e de actualitate .. Sper sa nu fie un caz tipic in care OP a aruncat piatra, apoi dispare in neant ...

 

In fine. Intamplarea face sa lucrez la un rotary encoder ptr un proiect si ceea ce vreau sa va spun e ca e destula bataie de cap. Nu e chiar floare la ureche, mai ales cand trebuie sa-l integrezi cu restul programului. Ce pot sa va spun e cam asa:

-Este exclus lucrul cu delay() daca vrei sa mai faci si altceva. In cazul meu procesorul mai are de sapat si la altele.

-Solutia este lucrul cu intreruperi periodice similar cu scanarea unei tastaturi

-Analiza intrarilor de la codor o fac cu o mica masina de stari, care trateaza absolut toate combinatiile posibile. Sunt 16. Nu lasati nicio stare neacoperita, ptr ca mai devreme sau mai tarziu ignorarea unor stari posibile se va transforma intr-un izvor nesecat de buguri si nervi.

-Interrupt on change nu este o solutie din cauza gliciurilor; vedeti poza atasata. Sau este, dar treaba se complica. Desigur, se pot pune condensatoare, dar dupa mine e mai elegant sa faca softul curatenie.

- In etapa de dezvoltare, folositi simulatorul la greu. Creeati un stimul care mimeaza semnalele encoderului, folositi breakpointuri si exersati toate starile masinutei de stari.

 

In poza de jos se vede o captura "single sweep" a celor doua semnale de la encoder in timp ce am invartit cat am putut de repede de ax. Pozele de sus sunt zoom-in in zona cu gliciuri. Morala e ca semnalul e departe de o forma ideala si rutina de citire trebuie sa tina cont si sa fenteze mizeriile.

 

post-174676-0-94080100-1449035506_thumb.png

 

Surse de inspiratie:

http://www.microchip.com/forums/tm.aspx?m=347116&mpage=1http://electronics.stackexchange.com/questions/31564/how-to-interface-a-quadrature-encoder-with-pic

Editat de cirip
Link spre comentariu

Salut cirip,

eu am facut un aparatel cu encoder folosind interrupt on change si n-a functionat chiar asa rau (a mai dat rateuri, dar nu chiar asa de suparatoare). Ca "masuri de combatere" a evenimentelor false  am folosit condensatori pe contactele encoderului si am luat decizia stanga/dreapta dupa cateva (2-3) evenimente "neintrerupte" in acea directie ("debouncing" software?).

Pentru decodificare, la inceput si eu foloseam multe if-uri, pana cand mi-a fost aratata "formula" din postul linkuit in postul #21. Formula pare sa acopere toate "variantele".

 

Spor,

Liviu

Editat de Liviu M
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări