Rotary encoder uitlezen

EricP

mét CE

Voor dit geval hoeft dat ook niet, als de totale tijd van de isr routines maar binnen je kritische window valt. En dat is zeer goed voorspelbaar.

Hoe dan? 3 encoders die (in deze context) at random interrupts genereren... Dat gaat alleen goed als het 'snel' is. Als het 'snel' is, is die hele interrupted interrupts ongein niet nodig...

Dat wordt (vaak) bepaald door de architectuur van de gebruikte CPU.
Sommige ondersteunen dat, andere niet, soms is het een feit dat het zo is. Normaal laat ik de interrupts op dezelfde prioriteit lopen, dan wordt er niks genest. Per CPU type zoek ik dat uit hoe het precies in elkaar zit.

Dat is onzin. Als je de boel gaat nesten, moet je oppassen dat het niet te diep genest wordt. Daar doe je niks aan. Je kunt wat met priorities doen - als de interrupt controller dat kan - maar dan nog is het oppassen geblazen. En tot op heden heb ik nog niet meegemaakt dat het noodzakelijk is - wel dat een programmeur wilde laten zien 'hoe goed hij de controller begreep'. En feitelijk dus liet zien dat-ie niet in staat is om efficiënte code te schrijven / er net iets langer over na te denken zodat dat niet nodig is.

Zonder context is dit een gevaarlijke uitspraak.

De context is er: hardware counters die de boel bijhouden. Jij vraagt de status op op het moment dat je er interesse in hebt. That's is. Komt geen interrupt aan te pas.

[...]Kijk, nu haal je de context er wel bij: Laat de hardware het doen, net beweerde je nog dat je alles in de main-loop moet doen en dat werkt hier nu juist net niet.

Eh... Dat beweerde ik niet. Dat beweerde Jochem. Wel in de juiste context blijven hoor.
Mijn enige reactie was dat het technisch wel(licht) kan, met de retorische vraag of je het moet willen. Stack ontploft?? :)

Dat 'beweerde' Jochem niet zomaar, want ook dat was in de context dat dat gunstiger is op het moment dat je in je mainloop toch verder bijna niks doet, omdat je dan de overhead van de aanroep van een interruptroutine bespaart.

En wat EricP aankaart is eigenlijk de belangrijkste reden dat wij in onze sector (m.n. luchtvaart, en industriële fail-safe en real-time environments) doorgaans interrupts proberen te vermijden voor de 'gewone' taken. Want als je een gecontroleerde main-loop hebt, waarin je berekent wat je worst-case af moet handelen, dan is dat veel voorspelbaarder. Gebruik je wel heel veel interrupts, dan moet je namelijk alsnog uitrekenen wat er worst-case nog voor tijd voor je mainloop overblijft, en dat is veel complexer. Dan maar liever elke deeltaak z'n eigen tijdsframe geven. En ja, als je dat ver doorvoert lever je gemiddeld wat performance in in ruil voor echte real-time eigenschappen.

En natuurlijk snap ik de voordelen van een korte interrupt (eigenlijk in alle gevallen waarbij die routine z'n naam eer aan doet). Ik zeg dus niet dat interrupts altijd moeten worden vermeden, zeker niet.

Ik zeg ook niet dat het in dit geval van TS per se de oplossing is om alles in een main-loop te doen. Maar ik ben het 100% met EricP eens dat dat een veel meer voorspelbare methode is dan maar allerlei interruptable interruptroutines elkaar te laten onderbreken.

Maar aan het eind van de rit zijn we het gewoon met elkaar eens, en zeggen we: pak een stukje hardware (al dan niet on-chip bij je uC) dat de afhandeling van het tellen van die flanken doet. Software is daarna een eitje.

If you want to succeed, double your failure rate.

Ha wow, had niet verwacht dat dit zo veel reacties op zou leveren, zeer interessant allemaal!

Op zich is het niet noodzakelijk om alle drie de assen atomic (die kende ik nog niet) uit te lezen, op het moment wil ik mij meer gaan richten op het vergelijken van de positie per as, niet zozeer de combinatie van de drie assen.

Zoals ik inderdaad al aangaf, is de 28k interrupts per seconde echt het hardwarematige maximum, dat is als alle drie de assen op maximale snelheid draaien. In de praktijk draait de z-as maar nauwelijks en als deze draait staan de andere assen over het algemeen stil tijdens het printen. Ook ben ik er van uit gegaan dat de x en y as 150mm/s kunnen gaan, terwijl dat eigenlijk de maximale gecombineerde snelheid is. In de praktijk is het natuurlijk goed om van de worst case uit te gaan, maar er zit zeker nog wel wat marge op.

Wat ook al aangegeven werd is dat het niet zozeer om de snelheid gaat, maar om de positie. De printer wordt aangestuurd met 1/32e microstepping, wat in mijn situatie een precisie geeft van 5micron. Omdat het aardig onmogelijk is om dat te meten, heb ik mij gericht op het meten van 32 micron; anders zou ik nog een idiotere hoeveelheid interrupts per seconde af moeten halen...
Immers, een afwijking van 32 micron, 1/3e van een menselijke haar, geeft nagenoeg geen significante afwijking op de prints, zeker als je andere afwijkingen meerekent die veel groter zijn (verschillen in filament-dikte, afwijkingen in de nozzle dikte, backlash, verkeerde berekeningen in de slicer, etc.)

Ik zit er in ieder geval aan te denken om een dual-core Single board linux pc te nemen, een kernel-module te maken voor het afhandelen van de interrupts en proberen er 1 core volledig voor te reserveren.Ik durf niet te zeggen of dat uberhaupt kan, maar ik ga er eens naar kijken of het zou kunnen met een Cubieboard 2 (dual core 1GHZ ARM)

Ik heb door jullie reacties in ieder geval even genoeg dingen die ik moet gaan uitzoeken...

Als je inderdaad voor een linux-gebaseerde oplossing gaat, overweeg dan om daar een real-time extension overheen te leggen. Zoektermen: RTAI, LXRT, Xenomai. Daarmee krijg je de beschikking over harde garanties m.b.t. bijvoorbeeld maximale interrupt latencies.
Verder zijn er sowieso wat aanvullende maatregelen nodig als je pc-gebaseerd gaat. Bijv: als het BIOS besluit om de CPU-frequentie aan te passen (frequency scaling, power management etc), dan koppelen sommige moederborden de klok tijdelijk los van de CPU, passen dan de frequentie aan, en bieden hem pas weer aan de CPU aan als de nieuwe klok stabiel is. In zo'n geval kan je software nog zo realtime zijn, als de klok niet loopt gaat het toch fout...

Heb even wat berekeningen opnieuw gedaan, omdat ik het idee had dat ik mis zat.
Ik had inderdaad wat verkeerd gerekend. De aansturing van de kop gebeurt met een nauwkeurigheid van 5 micron. Omdat ik minimaal 2x die resolutie wil halen om een zinnige meting te doen, zou ik uitkomen, op maximale snelheid, op een worst-case scenario van 60000 pulsen per seconde, per as. Omdat ik het voorlopig niet bepaald zie zitten om zo snel te kunnen meten, ga ik me voorlopig richten op het meten van andere onderdelen.
De meting zou immers niet enkel snel moeten zijn, ook moeten de pulsen snel verwerkt worden, omgerekend worden naar afstand, maar ook moet deze vergeleken worden met de beoogde positie van de kop, het liefst <1ms.
Eerst eens even wat meer ervaring opdoen met embedded hardware voor ik mij daar op ga richten.