Drehgeber Signale auftrennen, IC dafür?

Hallo

So weit mir bekannt sind die üblichen Drehimpulsgeber (als Poti-alternative) eher so gebaut das sie ein Überlappendes Signal an zwei Pins ausgeben aus dem man die Richtung und Zahl der Impulse erst raus "rechnen" müsste.

Gibt es dazu evtl. ein IC (und wie heißt dessen Funktion) das diese Signale auftrennt so das man z.b. 2-3 einfache Digitale Signalausgänge erhält die einfach nur Links-drehende, Rechts-drehende Impulse und einen Ausgang für die Tastfunktion (falls auch codiert) liefern?

Das hielte ich jedenfalls für einfacher es so z.b. an den GPIO eines Raspi o.a. Mikrokontrollers an zu schließen als das in Software zu versuchen (was ich für noch schwieriger hielte).

Mit so einer Hardware-lösung könnte man den Geber auch als Ersatz für Up/Down Taster in irgend etwas ein setzen. Denke ich mir mal so...

Bye/ /Kay

Reply to
Kay Martinen
Loading thread data ...

Das Ding nennt sich Quadratur-Dekoder.

Einen fertigen IC dafür kenne ich nicht, aber hier ein paar Ideen:

formatting link
formatting link
Gerrit

Reply to
Gerrit Heitsch

Am 21.09.2023 um 19:04 schrieb Kay Martinen:

Das ist bei einem Mikrocontroller in Software ziemlich simpel. Man schaltet beide Signale auf flankengetriggerte INT-Eingänge.

Kommt nun an A eine steigende Flanke wird der Pegel an B eingelesen. Ist B auf Low, wird der Zähler incrementiert, ist B auf High wird decrementiert. Anschließend wird die Flanke umgeschaltet, d.h. der nächste INT an A wird über die fallende Flanke ausgelöst (geht ja nicht anders weil A jetzt auf High ist). Ist bei der fallenden Flanke auf A der Pegel auf B = High, wird wieder incrementiert, ansonsten decrementiert. Dasselbe macht man mit den INTs, die durch das Signal an B getriggert werden.

Hier mal Pseudopascalcode:

Procedure INTA; // wird bei Flanke an A aufgerufen begin if B = High then inc(z) else dec(z); FlankenbitA = not(FlankenbitA); // reagiere beim nächsten mal auf andere Flanke end;

Procedure INTB; // wird bei Flanke an B aufgerufen begin if A = Hight then inc(z) else dec(z); FlankenbitB = not(FlankenbitB); end;

Die Anfangszustände der Flankenbits sind egal. Man kann sie natürlich initialisieren, aber nach den ersten Signalen an A und B "weiss" der Prozessor dann, wo es lang geht.

Wenn man auf beide Flanken triggern kann geht es auch so:

Procedure INTA; // wird bei Flanke an A aufgerufen begin if B = A then dec(z) else inc(z); end;

Procedure INTB; // wird bei Flanke an B aufgerufen begin if B = A then inc(z) else dec(z); end;

Reply to
stefan

Achtung: die mechanischen Encoder prellen ziemlich heftig, also ist vor der Logik eine saubere Entprellung nötig!

Der Microcontroller macht das nebenher. Die billigste Lösung für das Problem ist vermutlich ein ATTINY13 o.ä..

formatting link
Nach meiner Erfahrung ist die sinnvollste Variante für "handbediente" Encoder, wo man mit Pollfrequenzen im einstelligen kHz-Bereich auskommt, den Zustand der Eingänge periodisch zu pollen (z.B. per Timerinterrupt) und damit eine Statemachine zu füttern:

formatting link
cu Michael

Reply to
Michael Schwingen

Am 21.09.2023 um 20:40 schrieb Michael Schwingen:

Kommt darauf an, wie schnell die Störimpulse sind. Wenn der MC schnell genug ist, jeden Signalwechsel mitzubekommen, rechnet er das einfach mit raus, d.h. wenn das Signal kurz nach einem Wechsel von Low auf High kurz wieder auf Low geht, zählt der Zähler wieder rückwärts und beim folgenden Wechsel auf High wieder vorwärts. Ein einfaches RC-Glied sollte also ausreichen.

Könnte man damit machen.

Reply to
stefan

Das bezog sich auf den Vorschlag, das mit diskreter Logik zu machen.

Ja, für den uC gilt das, die Variante mit ausreichend schnellem Polling macht das so. Der Versuch, die ungefilterten Encodersignale per flankengesteuertem Interrupt auswerten zu wollen, kann leicht schiefgehen.

cu Michael

Reply to
Michael Schwingen

Dann, wenn eine Flanke übersehen wird. Solange jede "falsche" Flanke erfasst wird, stimmt das Ergebnis.

Reply to
stefan

Am 21.09.2023 um 19:04 schrieb Kay Martinen:

Quadraturencoder gibt es als Peripherie in so einigen Mikrocontrollern. Ich bastele gerade mit einem DSPIC. Der hat sowas.

Gruß Gunther

Reply to
Gunther Mannigel

Ja, der Encoder muß halt langsam genug prellen, so daß jeder Interrupt komplett bearbeitet werden kann, bevor die nächste Flanke kommt. Außerdem produziert das ordentlich Interruptlast und Latenz im System, da muß man sehen, ob das stört oder nicht. Zyklisches Polling vermeidet das.

cu Michael

Reply to
Michael Schwingen

Es gibt da viele Möglichkeiten.

Man könnte auch die Freigabe der INTs verzögern, d.h. wenn eine Flanke aufgetreten ist wird der INT gesperrt und nach einer fest eingestellten Zeit über einen Timer wieder eingeschaltet.

Reply to
stefan

Frage: wie schnell darf ein mechanischer Encoder überhaupt drehen, bevor die Kontakte abheben? Die sind doch nur für manuelle Bedienung geeignet, wo selbst eine falsche Zählung von dem korrigiert wird, der dran dreht. Eine Maus wird ja auch so lange verschoben, bis der Zeiger an der richtigen Stelle steht - da dürfen Impulse auch mal verschütt gehen, dafür würde auch Polling reichen. Für höhere Drehzahlen braucht man verschleißfreie (optische/magnetische) Encoder, die nicht-prellen können.

DoDi

Reply to
Hans-Peter Diettrich

Naja, rechnen...es ist eine PRogrammzeile.

Du koenntest sowas mit 3-4Gattern machen. Hab ich jedenfalls vor

20Jahren mal irgendwo gesehen.

Es gab auch mal ICs die haben das gemacht und hatten gleich den Zaehler drin. Da konnte man direct den Positionsstand auslesen. Ist aber lange obsolet.

Es ist sehr einfach das einfach nur im TimerIRQ einzulesen.

Es gibt auch Mikrocontroller die haben das in Hardware integriert, macht aber nur Sinn wenn man wirklich schnell arbeiten muss.

Da gibt es andere MEinungen zu. .-)

Fuer diese eine exotische Anwendung gab es obige Gatterloesung. ICh meine das war in einer Elektor. Musst du dir wohl mal selber die Zeiten aufmalen und ueber die schlatung nachdenken. Problem ist nur das du dann immer noch Fehltriggerungen hast wenn der Encoder mal prellt. Das wuerde dir eine Softwareloesung gleich mit entfernen.

Olaf

Reply to
olaf

formatting link
Aber wie schon gesagt. Die sind geschichte und koennen mehr als der TO will.

Olaf

Reply to
olaf

Klar gibt es da Grenzen, und wenn das selten genug passiert, ist das OK. Aber: man merkt das (bei Encodern mit mechanischer Rastung) schon recht deutlich, wenn Pulse nicht gezählt werden, auch bei schnellerem Drehen.

Auch dort merkt man dann, daß das ruckelt.

cu Michael

Reply to
Michael Schwingen

Ja, ich habe 2000..2001 eine Tastenentprellung am Arbeitsplatz entwickelt (uC; ohne Auftrag). Ich habe da im 1ms-Interrupt if (++keys >= 10) Keys(0), keys=0; programmiert. Also werden alle 10ms die Tastenzustände geprüft. Ein Zustand muß 10ms später immer noch gleich sein, damit er in Wirkung kommt.

Diese Entprellung hat sich bis 11.2014, meinem Ausscheiden, makellos bewährt.

Reply to
Helmut Schellong

Ich bevorzuge die Variante mit Schieberegister:

formatting link
2, "An Alternative"), bzw, unter
formatting link
cu Michael

Reply to
Michael Schwingen

Am 23.09.2023 um 11:57 schrieb Michael Schwingen: > On 2023-09-22, Hans-Peter Diettrich snipped-for-privacy@aol.com wrote: >> Frage: wie schnell darf ein mechanischer Encoder überhaupt drehen, bevor >> die Kontakte abheben? Die sind doch nur für manuelle Bedienung geeignet, >> wo selbst eine falsche Zählung von dem korrigiert wird, der dran dreht. >

Wenn man es richtig macht, ruckelt da nichts.

Auf jede fallende Flanke muss eine steigende Flanke folgen. Wenn es jetzt wie auf dem Bild in dem von dir verlinkten Artikel aussieht, könnte es theoretisch passieren, dass Flanken nicht erfasst werden. Das ist richtig, und sollte berücksichtigt werden, ist aber trivial.

formatting link
formatting link
Wenn es also eine fallende Flanke gibt, die einen INT auslöst und noch während dieser INT verarbeitet wird eine steigende Flanke kommt die dann keinen INT auslöst weil der Prozessor noch nicht bereit ist und danach eine weitere fallende Flanke, würde der Zähler einmal zuviel zählen. Wenn die Zahl der "verschluckten" Flanken geradzahlig ist, passiert das aber nicht.

Es kommt also drauf an, ob es vor der Flanke eine entgegengesetzte Flanke gab.

In dem folgenden Beispielcode reagiert der INT auf jede Flanke, also egal ob fallend oder steigend. Wenn eine Flanke verschluckt wurde, hat man also zwei gleichartige Flanken nacheinander. Das würde zu einem Zählfehler führen. Das passiert auch bei jeder ungeradzahligen Anzahl von verschluckten Flanken.

Wenn man das entsprechend berücksichtigt, gibt es keine Zählfehler. "Falsche" INT-Aufrufe belasten natürlich den Prozessor. Ob das ein Problem ist hängt von den Rahmenbedingungen ab.

Das Signal kann man vor der Auswertung natürlich noch verbessern, z.B. mit einem RC Tiefpass und Schmitt-Trigger.

Hier mal ein Code-Beispiel wo verschluckte Flanken berücksichtig werden:

Man kann das natürlich auch per Timer machen. Da "vernichten" sich die falschen Flanken dann automatisch.

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

int counter; // Zähler bool SigA; // alter Zustand von Eingang A bool SigB; // alter Zustand von Eingang B

void Interrupt_A() // Flankengetriggerter INT, reagiert auf // steigende und fallende Flanken an Signal A { InA = Encodersignal_A(); // Signal in InA speichern InB = Encodersignal_B(); if (InA != SigA) { // nur wenn es einen Signalwechsel gab wird das Bit verarbeitet if (InA == InB) { counter++; } else counter--; SigA = InA; // am Ende den Zustand des Bits speichern } }

void Interupt_B() // Flankengetriggerter INT, reagiert auf // steigende und fallende Flanken an Signal B { InB = Encodersignal_B(); InA = Encodersignal_A(); if (InB != SigB) // InB ist das Eingangsbit von Kanal B { // nur wenn es einen Signalwechsel gab wird das Bit verarbeitet if (InA == InB) { counter--; } else counter++; SigB = InB; // am Ende den Zustand des Bits speichern } }

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

Hier mit Timer, ist sogar noch etwas weniger Code:

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

void Timer_int() { InA = Encodersignal_A(); // Bit A einlesen InB = Encodersignal_B(); // Bit B einlesen

if (InA != SigA) // wenn Flanke an Signal A { if (InA == InB) { counter++; } else counter--; SigA = InA; // am Ende den Zustand des Bits speichern }

if (InB != SigB) // wenn Flanke an Signal B { if (InA == InB) { counter--; } else counter++; SigB = InB; // am Ende den Zustand des Bits speichern } }

Reply to
stefan

Am 23.09.2023 um 15:08 schrieb Michael Schwingen:

IRPT-Eingänge waren bei uns nicht belegt. Die Tasten-Bits lagen in einem Port-Register. Alle Tasten gleichzeitig bitweise zu verknüpfen, war also einfach.

Ich hatte die Tasten-Entprellung auch mit einem 4-stufigen Tasten-Autorepeat verknüpft, wobei die vierte Stufe ungefähr 60 Ticks pro Sekunde lieferte. Bei uns mußten Zahlen bis 999 durch Tastentippen (up/down) eingegeben werden. Deshalb habe ich diesen Autorepeat entwickelt.

Reply to
Helmut Schellong

olaf schrieb am Samstag, 23. September 2023 um 07:00:04 UTC+2:

Der legendäre THCT2000... ich hab damit mal ne Zählerkarte mit 3 Kanälen entwickelt, nicht nur für Inkrementalgeber, sondern auch für Frequenz- und Zeitmessung (konnte das Teil auch, einer der beiden Encoder-Eingänge wurde dann als Gate benutzt). Ist aber schon über 30 Jahre her, das Teil scheints tatsächlich nicht mehr zu geben.

Reply to
Winfried Bue

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.