Nieko
LED addicted... Fijnmalen en snuiven maar!! :P
Beste forum leden,
Ik ben sinds een paar dagen bezig met een rotary switch uit te lezen in een PICje. Dit wil ik uiteraard het liefst doen met interrupts.
Nou weet ik niet precies wat voor type rotary encoder ik heb, maar ik verwacht dat het hetzelfde is als deze:
http://www.alps.com/WebObjects/catalog.woa/E/HTML/Encoder/Incremental/…
Hij heeft in ieder geval 3 aansluitingen voor de rotary (A B en C) en 2 voor de schakelaar als je drukt.
Nou lukt me het alleen niet helemaal om de draairichting te bepalen.
Contact C zit op het moment aan de GND, contact A zit aan RB0 van een PIC16F873A. De pullups voor poort B staan aan. Verder wordt er een interrupt gegenereerd op een opgaande flank. Op deze manier moet in mijn ogen te bepalen zijn welke kant ik op draai.
Als er een interrupt van pin RB0 komt en ik ga B uitlezen (die op pin RA5 zit) dan moet ik hoog of laag meten. Meet ik hoog dan draai ik bijv. linksom, meet ik een laag dan draai ik rechtsom. Of heb ik dat verkeerd?
Alvast bedankt!
Met vriendelijke groeten,
Nieko
Wouter van Ooijen
Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog
IMO de enige juiste manier om een rotary uit te lezen is met een state-machine, eventueel met interrupts, maar ik zou pollen.
roadrunner84
Meep! Meep!
De meest eenvoudige manier vanuit een microcontroller is door een van de twee pootjes aan een interrupt te hangen. Je kunt je interrupt vaak instellen om af te gaan bij een omhooggaande (of omlaag, maakt niet zoveel uit) flank.
In de interrupt routine lees je dan meteen het andere pootje uit, die je aan een gewone I/O lijn aansluit. Afhankelijk van of deze I/O hoog of laag is zal je je teller 1 omhoog of 1 omlaag willen bijstellen.
Wouter van Ooijen
Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog
Op 2 februari 2011 11:33:05 schreef roadrunner84:
In de interrupt routine lees je dan meteen het andere pootje uit, die je aan een gewone I/O lijn aansluit. Afhankelijk van of deze I/O hoog of laag is zal je je teller 1 omhoog of 1 omlaag willen bijstellen.
Dat is een erg slechte manier. Door dender van de contacten en/of door heen en weer draaien van de knop kan je volkomen de mist in gaan.
Die dingen aan de interrupt hangen is gevaarlijk.Het zijn mechanische kontakten en die denderen.dat betekent dus
dat je heel veel interrupts direkt achter elkaar kan krijgen en dus stack overflows.
Er zijn microcontrollers die automatisch een interrupt ack doen als de cpu de interrupt accepteert (via vektor).
Dit soort controllers is dus ongeschikt hiervoor.
Zelf heb ik ze met 1 poot aan een IOC (interrupt-on-change)-pin gehangen en dat werkt goed. Na verloop van tijd krijg je wel (meer) last van contactdender. Bij mij hielp het toen om C'tjes te zetten tussen de poten en GND (100 nF of zo, zou je even mee moeten experimenteren denk ik).
roadrunner84
Meep! Meep!
@Wouter: Uhm... als dat een slechte manier is, dan is een state machine dat net zo goed. feitelijk zeg je dat als een rotary hoog uitgeeft hij best wel eens laag zou kunnen zijn... De enige manier om dit op te lossen is door een low-pass filter te maken.
Het eerder voorgestelde condensatoren naar ground is een eenvoudige, maar dit kan evt. ook in software (bijv. tenminste X us hoog/laag).
Als je door "nog een keer te draaien" verkeere invoer krijgt dan zal jouw manier zeker niet werken; je voegt immers complexiteit toe waarvan je aangeeft dat de boel eigenlijk al te traag was!
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Nee roadrunner je begrijpt het volgens mij niet.
Wat wouter probeert te zeggen is:
Als je signaal normaliter 00 01 11 10 cyclisch doorloopt kaan je iedere keer als je een hooggaande flank op de tweede bit ziet gaan kijken naar het eerste bitje. Ga je van links naar rechts zit die hoog gaande flank tussen mijn eerste en tweede "state". Meet je een 0, ga je naar rechts....
Ga je naar links dan zit de omhoog flank van het tweede bitje tussen 4 en drie. Dan meet je een 1 en weet je dat je naar links aan het gaan bent.....
Ga je nu wat wiebelen met je encoder, zodat je tussen state 1 en state 2 heen en weer gaat, dan meet je TOCH steeds een omhoog flank van het tweede bitje, en steeds een 0 op het eerste bitje terwijl je toch niet steeds verder en verder aan het draaien bent!
Wouter van Ooijen
Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog
Op 2 februari 2011 16:07:49 schreef rew:
Wat wouter probeert te zeggen is:
Goed uitgelegd. Met andere woorden: dender en 'slim' draaien aan de encoder kan hetzelfde resultaat opleveren, en de eenvoudige uitlezing is daar niet tegen bestand. een state machine wel.
Wouter van Ooijen
Wouter van Ooijen: VOTI webwinkel, docent HvU (Technische Informatica); C++ on mictrocontrollers blog
Op 2 februari 2011 16:16:31 schreef Echoflex:
Ja het werkt!
Ik ben gisteren de straat over gestoken zonder links of rechts te kijken. Volgens jouw redenering zou ik dat dus de rest van m'n leven ook maar moeten doen?
SparkyGSX
Een manager is iemand die denkt dat negen vrouwen in één maand een kind kunnen maken
Ook dat valt nog wel mee, maar dan moet je iets meer moeite doen. De interrupt routine zelf is niet interruptable, tenzij je daar zelf voor zorgt. Je kunt dus prima na elke flank de betreffende interrupt uitzetten, en een korte tijd later (met een timer interrupt) weer aan zetten. Dit natuurlijk om overmatige interrupts tegen te gaan.
Een nadeel van deze methode, is dat je heel erg goed moet oppassen met de interrupt latency; als je een andere, niet-interruptable ISR hebt die wat langer duurt, loop je het risico dat je te laat bent met het lezen van het andere kanaal. Het kan wel weer gemakkelijker als je een externe interrupt hebt waarbij je kunt uitlezen wat voor flank het was, of dat met een stukje externe hardware oplost.
Nieko
LED addicted... Fijnmalen en snuiven maar!! :P
Super bedankt voor al jullie reacties!
Wat roadrunner zegt doe ik nu ook, ik zal hier even mijn ISR neer zetten:
ISR:
CONTEXT SAVE
INTF = 0
IF PORTA.5 == 1 THEN ;Als er na een opgaande flank de andere poort 1 is, dan draai ik linksom
PRINT AT 1, 1, "Linksom "
ELSEIF PORTA.5 == 0 THEN ;Als er na een opgaande flank de andere poort 0 is, dan draai ik rechtsom
PRINT AT 1, 1, "Rechtsom"
ENDIF
INC Teller
PRINT AT 4 ,1, DEC5 Teller
CONTEXT RESTORE
De intterupt zit op poort B0, ik genereer een interrupt op de opgaande flank.
De interne pullups van poort B staan aan, op poort A5 heb ik zelf een pullup gezet van 10k gezet. Over de schakel contacten heb ik een 100nF condensator zitten..
Dit werkt helaas niet, ik krijg constant "Rechtsom" op mijn display te zien. Met teller tel ik het aantal keer dat ik schakel. Als ik het uitgaande signaal van de rotary encoder bekijk, dan zou mijn teller om de 2 schakelingen 1 omhoog moeten gaan (als ik constant dezelfde kant op draai). Hij gaat alleen soms met iedere schakeling 1 omhoog, zou dit dan komen door contact dender of zo? Al heb ik er een 100nF condensator overheen staan..
Wat betreft JER00N zijn manier;
Mij lijkt het dan dat je iedere keer moet kijken of je nou een neergaande of opgaande flank hebt en aanvankelijk daar van bepaald of het andere signaal een 1 of een 0 moet zijn.. Dat lijkt me voor een basis test even wat omslachtig, ik wil het dus danig werkend hebben dat ik kan detecteren of ik links of rechtsom draai, als ik daar 2 schakelingen voor moet draaien vind ik dat niet erg..
Wat betreft dubbele interrupts, ik geloof niet dat dat gaat.. Ik heb ooit INTCON uitgelezen tijdens een interrupt, daar in zag ik dat GIE automatisch uitgezet werd.
Je moet het doen zoals Wouter zegt dat werkt het beste.
Probeer maar eens uit, als je heen en weer draaid zal je zien dat het op en aftellen heel snel fout gaat. Hij telt meer op als af, of anders om. En de fout wordt steeds groter.
[Bericht gewijzigd door Lambiek op (13%)]
Nieko
LED addicted... Fijnmalen en snuiven maar!! :P
Wouter zijn manier heb ik al geprobeerd, dat werkt wel prima.. Alleen ik heb die tijd van de uC eigenlijk voor iets anders nodig.. Anders krijg je een hele trage reactie snelheid waarbij de rotary switch het voor de helft van de tijd niet doet...
Dan is de opbouw van je programma mischien niet goed. Ik lees hier een encoder in met 500 pulsen per omwenteling bij 3000 T/M.
Het is dan wel een optishe encoder, maar toch.
Dus dat mechanische ding moet geen probleem zijn.
Nieko
LED addicted... Fijnmalen en snuiven maar!! :P
In de tussen tijd lees ik 2 ADC ingangen in, 25x met een tussen pauze van 20mS..
De rotary encoder wordt enkel voor het menu en de instellingen gebruikt. Ik zou dat ook op een timer interrupt kunnen zetten.. Al wil ik wat dat betreft ook wel de uitdaging aan gaan om de rotary encoder met interrupts uit te lezen..
Ja als je pauze's gebruikt van 20MS dan gaat het niet zo snel.
Als je het alleen voor je menu instelling gebruikt wordt het een ander verhaal.
Dat doe ik trouwens veel met een potmeter, dat werkt ook perfect.
Nieko
LED addicted... Fijnmalen en snuiven maar!! :P
Een potmeter is niet praktisch vind ik. Ik heb een menu, en daar moet met een draaiknop doorheen gebladerd kunnen worden. Verder moeten bepaalde waarden ingesteld kunnen worden..
Ik wilde net even proberen of het lukt met interrupt-on-change, alleen als er een 1 op de ingang van RB4 staat, dan blijft de interrupt constant aan.. Ik clear de interrupt flag wel, dus daar kan het niet aan liggen. Als er een 0 op de ingang staat dan werkt de interrupt goed..
Gatze
Congratulations on your purchase. To begin using your quantum computer, set the power switch to both off and on simultaneously
Op 2 februari 2011 16:16:31 schreef Echoflex:
In iedergeval heeft het interrupt principe zich al bewezen
http://www.circuitsonline.net/forum/view/86405/1/
Lees dit topic ook even door. Daar werkt het 'interrupt principe' niet goed.
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Ook ik geef Wouter gelijk (statemachine dus)!
Een ISR is niet robuust en gaat vroeg of laat valse counts geven.
Een condensator helpt wel een stuk maar daardoor wordt de maximale rotatie tijd weer lager. Voor de toepassing is het nu goed genoeg.
@Lambiek:
Het is dan wel een optishe encoder, maar toch.
Dus dat mechanische ding moet geen probleem zijn.
Dat is het dus wel (een probleem dus!) want een optische encoder denderd niet, een mechanisch ding wel.
@Echoflex:
En ja, ik heb een hekel aan mensen die mij vertellen hoe het wel moet.
Dat noemen ze eigenwijs 
(Ben ik ook wel, maar voor goede ideeën sta ik wel open.)
Ja daar heb je gelijk in, maar ik doelde eigenlijk op het aantal pulsen en die mechanische heeft er maar 16/omw of zo. Maar de contact dender blijft, dat klopt.
henri62
1-st law of Henri: De wet van behoud van ellende. 2-nd law of Henri: Ellende komt nooit alleen.
Ik had ook al zo'n vermoeden dat je eigenlijk het aantal pulsen/rot bedoelde maar ik had het toch maar even aangehaald voor het geval iemand anders het verkeerd begrijpt.