Ich nutze einen handbetriebenen Drehgeber von ALPS an einem Atmel328p, kann aber für das Lesen keinen Timer einsetzen. Also musste ein anderer Weg für das entprellte Erkennen beider Drehrichtungen her.
Ich kam nach einigen Versuchen und dem Lesen des Datenblattes vom Drehgebers (macht das Leben so viel leichter) zu folgendem Verfahren.
Schauen wir uns exemplarisch die Schalterstellung als Bitfolge an (A schaltet hier vor B mit Prellen beider Schalter, Ausgangslage ist 00):
1
BA BA BA BA BA BA BA BA BA BA BA BA BA BA BA BA BA BA
A schaltet ab Schritt 2 und ist ab Schritt 6 stabil. Laut Datenblatt meines Drehgebers fängt B erst an zu Schalten, wenn A umgeschaltet hat (wichtig, geprüft per Oszilloskop). Im Beispiel schaltet B ab Schritt 10 und ist ab Schritt 16 stabil.
Ansatz: es reicht zu erkennen, dass A geschaltet hat und stabil ist, und darauf zu warten, das B anfängt zu prellen. Und natürlich anders herum bei geänderter Drehrichtung. Das reicht als Indikator.
Vorgehen: die Schalterstellung als 2-Bit-Folge bei Änderungen in eine 8-Bit-Queue schieben und die Queue für die Drehrichtungserkennung nutzen.
Wenn ich das obige Beispiel nehme, enthält die Queue als Ergebnis die Bitfolge xx000111 (Shift von Rechts, die beiden hohen Bits sind nicht von Belang). Wenn wir mit 11 starten und in die gleiche Richtung weiter drehen, enthält die Queue xx111000. Dieses Pattern zeigt mir eine Drehrichtung an. Wenn in die andere Richtung gedreht wird, sehen die Pattern so aus: xx001011 bzw. xx110100. Also reicht es, die Queue fortlaufend gegen die Änderungs-Pattern zu vergleichen und den Match als Drehrichtungserkennung zu werten.
Vereinfacht wird das Ganze, da die Pattern einer Drehrichtung genau gegenteilig sind. man schaut einfach auf Bit 6 und invertiert das Muster wenn das Bit auf 1 steht. Dann bedeutet Pattern xx000111 eine Drehrichtung und xx001011 die andere Drehrichtung.
Das Ganze läuft ohne Timer bei mir in meinem ziemlich proppevollen Code problemfrei. Die Variable ticks (siehe Code Beispiel) beinhaltet die Anzahl der Drehschritte und muss möglichst schnell ausgewertet werden. In meinem Projekt geschieht das ungefähr alle 80-120ms, das ist für die händische Nutzung bei mir völlig ausreichend.
Ich nutze einen handbetriebenen Drehgeber von ALPS an einem Atmel328p,
kann aber für das Lesen keinen Timer einsetzen.
Viele Probleme lassen sich lösen, wenn man einen Schritt zurückgeht und die vermeintlich unabänderlichen Rahmenbedingungen ändert. Wieso sollte Dein Atmega keinen Timer haben? Wieso sollte nicht in einer der von Dir vermutlich für andere Dinge genutzten Timerinterruptroutinen auch nebenbei das Pollen der zwei/drei I/O-Pins des Drehgebers eingefügt werden können?
Natürlich ist da implizit ein "Timer" mit drin: die Durchlaufzeit der mainloop. Und auf diese Art hast du dann auch Abhängigkeiten von der Plattform, auf der die SW läuft.
Das, was du da im Grunde machst, ist eine Flankenerkennung über ein Schieberegister. Oder eher über zwei ineinander verwobene Schieberegister.
Ein Tipp: "actual" stimmt hier eigentlich nicht, denn da drin steht nicht der "tatsächliche" Enoderzustand, sondern der "kürzlich" bzw. "zuletzt" eingelesene Wert. Die Worte "most recent" oder "latest" wären richtig, denn der "tatsächliche" Pegel an den Pins und damit der "tatsächliche" Encoderzustand kann sich schon wieder geändert haben.
Wieso sollte nicht in einer der von Dir
vermutlich für andere Dinge genutzten Timerinterruptroutinen auch
nebenbei das Pollen der zwei/drei I/O-Pins des Drehgebers eingefügt
werden können?
So isses!
Wenn nicht benötigt oder störend, kann man auch UART oder SPI für periodische Interrupts verwenden. Alles andere ist unötiges Gewürge.
Wenn nicht benötigt oder störend, kann man auch UART oder SPI für
periodische Interrupts verwenden.
Du meinst eine ungenutzte UART, in ihrer Tx-ISR immer wieder zum Senden angeregt, um mit Baudrate/10 einen regelmäßigen Interrupt zur Verfügung zu stellen?
Kann man natürlich auch machen, wenn es tatsächlich eine ungenutzte Uart geben sollte. Ähnlich ließe sich auch ein ungenutzter AD-Wandler nutzen ...
Also musste ein anderer Weg für das entprellte Erkennen beider
Drehrichtungen her.
Ein Drehgeber mit AB-Ausgang liefert einen 2-Bit Gray-Code. Der braucht prinzipbedingt keine Auswertung mit Entprellung, um sich nicht zu verzählen. Bei richtiger Auswertung springt der Ausgabewert durch das Prellen lediglich zwischen den beiden benachbarten Werten, da der andere Kanal einen stabilen Wert liefert, während der eine um Umspringen ist.
Ein Drehgeber mit AB-Ausgang liefert einen 2-Bit Gray-Code. Der braucht
prinzipbedingt keine Auswertung mit Entprellung, um sich nicht zu
verzählen. Bei richtiger Auswertung springt der Ausgabewert durch das
Prellen lediglich zwischen den beiden benachbarten Werten, da der andere
Kanal einen stabilen Wert liefert, während der eine um Umspringen ist.
So ist es.
@Wolfgang: Wenn du jeden Viertel-Schritt zählen möchtest UND alle Fehler erkenne willst, dann fällt das Prellen automatisch mit weg.
Übersetz die Pattern in Schritte s (00:0, 10:1, 01:2, 11:3), dann ist die Auswertung Trivial. mit ds = s(neu)-s(alt) (begrenzt auf 2 Bit unsigned int) ergibt sich
ds = 0: nix passiert
ds = 1: Viertelschritt++;
ds = 2: Fehler
ds = 3 (=-1): Viertelschritt--;
Für den Anfang ist es sinnvoll, die 4*4 Kombinationen einzeln durchzugehen. Danach passt das in ein Array und 2 Zeilen.
I2C ohne irgendein Gegenstück dürfte recht lange Timeouts erzeugen; WDT ist, sofern man ihn nicht dazu bekommt, nur 'nen normalen Interrupt auszulösen, nicht so die beste Idee ...
Einfach A und B jeweils auf einen Port legen und den Interupt bei steigender UND fallender Flanke auswerten. Entprellen ist unnötig (wie schon geschrieben wurde). Wenn Du willst, kannst Du aber die Eingänge noch bissl filtern (Tiefpass 1 kHz oder so).
Ob addiert wird oder subtrahiert hängt vom anderen Pegel und der Flanke ab. Einfach mal aufzeichnen, dann wird alles klar.
Z.B.:
A fallende Flanke, B low -> subtrahieren.
A steigende Flanke, B low -> addieren.
Polling war schon immer nicht besonders effektiv. Es blockiert vor allem andere Tasks.
Polling war schon immer nicht besonders effektiv. Es blockiert vor allem
andere Tasks.
In embedded SW ist es für viele Aufgaben genau andersrum: Polling verbraucht konstantere Zeit und hat nur geringen WorstCase.
Das ist der alte Disput Eventbasiert vs. SPS-Loop.
alles was prellen kann, ist eventbasiert eine Zeitbombe. Egal ob Tasten oder Drehgeber bis etwa 6000 Schritte pro Minute, im ms-Systemtakt 10 Zyklen sind gut investiert.
Mich wundert das dazu noch niemand etwas gesagt hat.
Das Ganze läuft ohne Timer bei mir in meinem ziemlich proppevollen Code
problemfrei.
Proppenvoller Code hat nichts zu sagen. Es wird nie jede Programmzeile in jedem Durchlauf abgearbeitet. Ist einfach zu unspezifisch.
Die Variable ticks (siehe Code Beispiel) beinhaltet die
Anzahl der Drehschritte und muss möglichst schnell ausgewertet werden.
Das beißt sich mit
In meinem Projekt geschieht das ungefähr alle 80-120ms, das ist für die
händische Nutzung bei mir völlig ausreichend.
80-120ms Durchlaufzeit. Für einen Handencoder sind max. 2ms sinnvoll. Wenn man wirklich langsam dreht meinetwegen auch 4ms. Aber niemals sind 80-120ms ausreichend. Nie und nimmer. Der kann gar nicht so reagieren wie man möchte. Ich würde mir erstmal die Frage stellen warum dauert ein Durchlauf so lange?
passende Routinen kann man kombinieren, Tasten und Encoder -prellen auch mit berücksichtigen, ich hatte PeDas Entprellroutinen für Tasten und Encoder sogar zusammen nutzen können, eigentlich kann man ALLES mit einem timer erschlagen, man muß nur die Ticks richtig und kurz auswerten und kann alles in der Main erledigen, mal ehrlich was ist so zeitkritisch das es nicht wenige µs bis ms warten kann, LCD aktualisierung, mehr als 10/s kann eh keiner lesen, ob eine Taste nach 10ms oder 20ms reagiert ist doch egal, so schnell drückt kein Mensch, außer in Elektronik WM Profispieler und irgendwann ist der RAM und Flash auch endlich um ein komplettes starkes Schach unterzubringen. Dem PET2001 reichte sogar 7kB für respektable Leistungen auf Hobbyniveau.
damit die Garbe an Mikro- bis Millisekundenimpulsen voll in den Interrupteingang reinhaut und Interrupt nach Interrupt auslöst damit der uC zu gar nichts anderem mehr kommt.
In embedded SW ist es für viele Aufgaben genau andersrum: Polling
verbraucht konstantere Zeit und hat nur geringen WorstCase.
Stimmt. Polling verbraucht garantiert 100% Zeit. Selbst wenn sich nichts ändert. Da ist nicht mal Zeit, die geänderten Werte anzuzeigen. Ausser macht Spaghetti-Code draus.
damit die Garbe an Mikro- bis Millisekundenimpulsen voll in den
Interrupteingang reinhaut und Interrupt nach Interrupt auslöst damit der
uC zu gar nichts anderem mehr kommt.
Beim polling werden dafür beinahe ständig die gleichen Werte gelesen. Das ist weitaus effektiver. In Deiner Welt.
Nochmal: Wer will kann einen Tiefpass davor setzen. Aber vorsichtshalber mal das Eingangssignal mit dem Oszi anschauen.
Falls Du wichtigere Interupts hast, es gibt Prioritäten dafür.
In meinem Projekt geschieht das ungefähr alle 80-120ms, das ist für die
händische Nutzung bei mir völlig ausreichend.
Dann darfst du aber ganz bestimmt nicht beherzt am Encoder drehen. Bei einem typischen Encoder mit 15 Impulsen pro Umdrehung auf jeder Spur (z.B. Alps 401590), d.h. 60 verschiedenen Zuständen auf 360°, müsstest du mehr als 60 mal pro Umdrehung abfragen. Die schnellste Drehung, die du mit deiner Abtastung von im worst case 120 ms erfassen kannst, müsste bei so einem Geber also über 7 (sieben) Sekunden dauern. Um damit irgendetwas mit normaler Handhabung eines Drehknopfes sinnvolles einstellen zu können und nicht das Abtasttheorem zu verletzen, bräuchtest du einen Feintrieb zwischen Drehknopf und Drehgeber, was ja wohl eher selten der Fall ist.
Wie kommst du darauf, dass so eine Abtastrate für händischen Betrieb ausreichend ist?
damit die Garbe an Mikro- bis Millisekundenimpulsen voll in den
Interrupteingang reinhaut und Interrupt nach Interrupt auslöst damit der
uC zu gar nichts anderem mehr kommt.
Das wäre dann der erste mechanische Drehgeber, der Mikrosekundenimpulse erzeugt. Hast du dir Pulse von so einem mechanischen Geber einmal mit einem Oszi/LA angesehen?
Es geht um prellende Kontakte. Ist der Drehgeber frisch, wird er noch
nicht so sehr prellen, nach einer Weile aber wird sich das ändern.
Wenn erst mal der Schleifkontakt kratzt, kommt der ein oder Andre evtl. doch noch auf die Idee, da ne Entprellung zu spendieren... Wir sind doch hier unter uns. Wir sind doch keine Profis, die auf so was verzichten können/wollten/sollen....
Prellen ist ein mechanischer Vorgang. Welche Beschleunigungswerte sollen denn auf die Kontakte wirken, damit die im Mikrosekundenbereich prellen?
Falls du nicht Prellen, sondern die Zunahme von Störungen auf Grund von Oberflächenoxidation meinst, ist vielleicht der Strom zu gering. Das ist aber ein völlig anderer Effekt.
Die Microsekunden sind nicht auf meinem Mist gewachsen, aber wir dürften uns darüber einig sein, daß auch Kontaktprellen die Interruptlast erhöht.
Und je nachdem, was der geneigte Programmierer meint, in der ISR alles veranstalten zu müssen, kann das ein Problem werden.
Vielleicht ist es ja am besten, wenn man auf so konfliktbelastete Eingabeelemente wie Drehgeber verzichtet, die rufen ja offensichtlich bei gleich mehreren Fraktionen Unwohlsein und Empfindungen hervor.
(Das ist jetzt nicht an Dich, sondern an die mitfühlende Allgemeinheit gerichtet)
Mechanik ist Heute doch eh viel zu teuer. Sensor-Tasten, WiFi... Da heizt dir dein Kaffeewärmer, nur solang dein Handy noch Saft hat. Aber das aufs 1/10 Grad genau. :DDD
Und je nachdem, was der geneigte Programmierer meint, in der ISR alles
veranstalten zu müssen, kann das ein Problem werden.
Er muss genau den Port lesen, die beiden Pins maskieren, die beiden Bits in die Variable mit dem alten Zustand schieben, die vier Bits (alten und neuen Zustand) maskieren, das als Index zum Auslesen eines 4x2 const Arrays verwenden und den Zähler entsprechend dem ausgelesenen Wert in Ruhe lassen, inkrementieren oder dekrementieren, ggf. noch ein Flag setzen, das in der Hauptschleife abgearbeitet wird - kein bisschen mehr.
Und je nachdem, was der geneigte Programmierer meint, in der ISR alles
veranstalten zu müssen, kann das ein Problem werden.
Ja, was passiert denn da schlimmes?
Polling:
Sieht das Kontaktprellen genauso wie eine ISR. Der Unterschied ist lediglich, dass die polling-Routine ausdrücklich darauf wartet, dass der Kontakt endlich mal schaltet oder prellt. Und ansonsten keinerlei Beitrag leistet, ausser andere Tasks zu blockieren.
ISR:
Die macht genau nur dann etwas, wenn tatsächlich was passiert. Ansonsten macht sie genau nichts. Sie wird nicht mal aufgerufen. Dieses nebulös behauptete zumüllen durch Interrupts findet nur genau in dem Maß statt wie im polling. Und ein INT kann nur einmal erzeugt werden, da gibt es keinen Stack oder queue. Der nächste kann erst dann kommen, wenn der vorhergehende bearbeitet wurde.
Polling verarbeitet also exakt den gleichen Müll wie INTs, nur mit deutlich mehr Aufwand indem es auf exakt die gleichen Signale blockierend wartet.
Aber evtl. liegt das Problem ja im "was der geneigte Programmierer meint, in der ISR alles veranstalten zu müssen"?
Was gedenkst Du denn da zu machen ausser Flanke feststellen, den anderen Port zu lesen und den Wert inkrementieren/dekrementieren? Was ist da so grundlegend komplizierter als im Polling? Oder ist eine ISR Neuland und Teufelszeug?
Oder ist das gar Konzept von mehreren "parallel" laufenden State-Machines noch unbekannt?
Im Endeffekt läuft das Polling darauf hinaus, dass man dann die Display-Rountine (oder was auch immer mit dem Drehgebersignal gemacht werden soll) in das Polling mit reinfrickelt. In der Zeit in der das Display (oder was auch immer) passiert (ja bitte, SPI über polling!), werden Signale vom Drehgeber ignoriert. Gewurschtel das keiner mehr kapiert, monolithischer Code, nicht wiederverwertbar. Hauptsache es läuft, irgendwie.
Fingerübung: Der TO möchte doch bitte noch einen velocity-Wert in seinen Code reinpfriemeln ...
Hinweis: Jetzt wird das Prellen von Interesse. Lässt sich aber auch in der ISR einfach behandeln/ignorieren.
Hinweis: Jetzt wird das Prellen von Interesse. Lässt sich aber auch in
der ISR einfach behandeln/ignorieren.
Dafür müsste die ISR die Zeit kennen, d.h. der Interrupt müsste z.B. von einem Timer kommen oder es müsste ein Uhr abgefragt werden. Wie willst du das sonst von einer normalen Änderung (Drehrichtungsumkehr) unterscheiden.
Wieder so ein (Freitags?-) Thread wo der TO ein paar "Tatsachen"
in den Raum wirft und danach sich einen (Sch....-) Dreck darum
kümmert was weiter passiert.
Die macht genau nur dann etwas, wenn tatsächlich was passiert.
Richtig und wenn es 1 Million mal die Sekunde sein MUSS...
Das Polling verarbeitet die 1 Million Zustandswechsel genauso. Und wenns 10 Wechsel / s sind auch, mit 100% der Zeit im polling. Die ISR verschwendet nur noch 1/10 der Zeit.
Fingerübung hab ich geschrieben. Das ist also eine Aufgabe für dich oder den TO. Tip: Lies den SysTimer aus, merk dir den Wert und ignorier den nächsten Impuls wenn zu wenig Zeit vergangen ist (= Prellzeit).
Dafür müsste die ISR die Zeit kennen, d.h. der Interrupt müsste z.B. von
einem Timer kommen oder es müsste ein Uhr abgefragt werden.
Ja, velocity ist Geschwindigkeit. Und die ist nun mal zeitbehaftet. Für die Zeit brauchts aber keinen Interrupt, es genügt ein frei laufender Timer der ohne CPU-Last in Hardware läuft. Schlimm?
Leute, denkt doch einfach mal selbst über das Thema nach! Warnung: Das ist nicht in 5 Minuten erledigt.
ich hatte PeDas Entprellroutinen für Tasten und
Encoder sogar zusammen nutzen können, eigentlich kann man ALLES mit
einem timer erschlagen
Ist mittlerweile Standard bei meinem Code. Und die Timer-ISR kann dabei noch beliebige andere Sachen bearbeiten, ohne das Encoder oder Knöpfchen dabei zu kurz kommen. Praktisch ist jede Timer ISR ein geeignetes Plätzchen.
Polling:
Sieht das Kontaktprellen genauso wie eine ISR. Der Unterschied ist
lediglich, dass die polling-Routine ausdrücklich darauf wartet, dass der
Kontakt endlich mal schaltet oder prellt.
Auch wenn andere schon mit Zaunpfählen gewunken haben:
Ah, neusprech!
Der code des TO frägt immer wieder 2 ports ab. Erst wenn sich was ändert tut er was. Für mich ist das "warten". Dumm rumstehen und warten, bis was passiert.
Wie ist jetzt Dein Wort dafür?
Wikipedia taugt aber nicht dafür:
"Ein möglicher Zweck des Pollings ist das aktive Warten auf Zustandsänderungen, auch Spinning genannt. Eine andere Form ist die Abfrage jeweils einmal in einem Abtastzyklus, oder die Abfrage nach jeweils einer anderen Aktivität."
Pollen an sich definiert noch überhaupt nicht ob und wie gewartet wird. Sondern nur die Eigenschaft, dass nicht etwas auf Zuruf von Extern passiert wie mit einem Interrupt, sondern von Intern eine Abfrage wie auch immer losgetreten wird.
Wir reden schon seit Tagen??? Von der Technik des Polling. Nicht über
die Fähigkeiten des TOs, dies auch korrekt umzusetzen!
Ah, jetzt kommen wir zusammen. Ich hab nur einen Hinweis gesehen, wie man das polling besser machen könnte. In einem timer-INT. Ja, das ist "non-blocking", im Gegensatz zum TO, das blocking ist. Für non-blocking tuts auch eine FSM die zyklisch aufgerufen wird*). Warum man das Polling in einen timer-INT setzen will, zusammen mit anderem Gedöns (gibt wieder Spaghetti-code), erhellt sich mir nicht. Dann doch gleich eine ISR die genau nur das Eine macht was man will und dadurch wiederverwertbar ist.
Ich geb zu, das ist ein verwegener Ansatz für Leute, bei denen ein Programm aus genau einer C-Datei besteht.
*) Das birgt aber die Gefahr, dass Schritte verloren gehen. Was wieder zur ISR führt. Aber die ist ja kompliziert und Teufelszeug. Jetzt bleibt euch nur noch ein RTOS ...
Ah, jetzt kommen wir zusammen. Ich hab nur einen Hinweis gesehen, wie
man das polling besser machen könnte. In einem timer-INT. Ja, das ist
"non-blocking", im Gegensatz zum TO, das blocking ist
Du hat keine Ahnung, hast das noch nie gemacht, es noch nicht einmal gesehen wie es richtig gemacht wird und ERZÄHLST UNS HIER EINEN.... Sag mal bist du Live auf Twitch?!
Und das ist nicht Warten. Es wird etwas gemacht und das kostet CPU Zeit.
Es wird nichts gemacht, nur Zeit verbraten, es wird gewartet um etwas machen zu können. Und das kostet Zeit. Immer wieder nachsehen, ob sich was geändert hat, statt zu sagen "Ruf mich an, wenn das passiert ist".
Die Referenz ist nun mal der code des TO. Polling in seiner (dümmsten) Reinstform. Etwas weniger dumm ist es, immer nur kurz nachzusehen, ob sich was geändert hat. Zerhacktes warten halt. Geht aber manchmal nicht anders, das geb ich zu. Dafür eignen sich non-blocking FSMs. Der code des TO ist aber nun mal weder eine FSM noch non-blocking.
dass die polling-Routine ausdrücklich darauf wartet
Was Phantasierst du da?!
Äh ... schau Dir den code des TO an. Da wartet er in der "while (1)" die
ganze Zeit drauf.
Ja. Das ist aber kein "Polling" sondern "busy waiting". Denn er macht in der Schleife nichts anderes. Ist ja auch nur ein Beispiel.
Polling - insbesondere in Verbindung mit der Auswertung von Tasten oder Drehgebern - nennt man das zyklische Abfragen der Schaltzustände. Unabhängig davon ob sich da irgendwas geändert hat oder nicht. Für manuell bediente Taster oder Drehgeber reichen 2ms Zykluszeit aus, oft auch 10ms. Da das Abfragen der Zustände nur ein paar Dutzend Taktzyklen braucht und die Taktfrequenz typisch bei 1Mhz oder noch höher liegt, braucht Polling wenig - und vor allem konstante - Rechenzeit.
Polling heißt auch nicht "keine Interrupts". Im Gegenteil. Das Polling macht man geschickterweise in einem Timerinterrupt. Aber wenn das nicht geht, dann eben in der Hauptschleife.
Polling heißt auch nicht "keine Interrupts". Im Gegenteil. Das Polling
macht man geschickterweise in einem Timerinterrupt.
Zeitverschwendung in Interrupts, statt einen INT wenns wirklich was zu tun gibt. Wo ist da jetzt der Zeitgewinn? Ja, Prellen, ich schenk dir 2 Widerstände und zwei Kondensatoren wenn dir das den Schweiß auf die Stirn treibt. Nebenbei: Prellen ist kein Dauerzustand, sondern eine Ausnahme.
Diese Diskussion gab es hier schon öfters,
und kehrt immer wieder, wo Hardware-Interrupts
verteufelt wird. Ich frage mich, wieso hat der
Hersteller das überhaupt in seine Controller
und Mikroprozessoren eingebaut, wenn daß solche
schlimme Sache ist? Für irgendwas muß das doch
gut sein.
Neben Interrupts gibt es lediglich die Technik des programmierten (zyklischen) Abfragens (Polling), um den Status von Ein-/Ausgabegeräten, Prozessen oder anderem zu erfahren. Diese Methode ist zwar einfacher und benötigt keine zusätzliche Hardware, ist allerdings sehr viel ineffizienter als die Arbeit mit Interrupts, da sie die CPU viel stärker in Anspruch nimmt. Zudem hängt die Reaktionsgeschwindigkeit beim Polling davon ab, wie viel Zeit zwischen den Abfragen vergeht – dies kann bei Situationen, die eine sofortige Reaktion verlangen, kritisch sein. Bei Multitasking-Betriebssystemen ist das Polling als alleinige Methode nicht möglich.
Die Standard-Analogie für Interrupts im Alltag ist eine Tür mit Klingel: Während man seine Aufgaben erledigt, kann man jederzeit durch die Klingel unterbrochen werden, wenn ein Gast eine „Abarbeitung“ wünscht, und sich ihm dann zuwenden. Beim Polling – also ohne Klingel – müsste immer wieder an der Tür nachgeschaut werden, ob Besuch da ist oder nicht. Beim Erhitzen von Milch hingegen ist es wohl besser, nicht erst auf den „Interrupt“ des Überkochens zu warten, sondern den Prozess regelmäßig zu überwachen.
Moin,
wenn ich mich richtig erinnere, habe ich nach der ersten fallenden Flanke von B in der ISR weitergezählt mit der Richtung von A. Gleichzeitig in der ISR den INT von B gesperrt. In der ISR von A dann nur den INT von B wieder eingeschaltet. Kein Pollen, kein Vergleichen mit vorigen Werten, kleines Programm, schnell und zuverlässig. Probleme gab es nur mit der steigenden Flanke von A und B, die anders als im Datenblatt beschrieben, eher zeitgleich kamen. Viel Erfolg
Gruß
Carsten
Das ist doch gar nicht wahr. Hardware Interrupts sind eben dann schlecht, wenn du einen prellenden Kontakt abfragen willst, was bei Encodern nun mal oft der Fall ist. So ein Kontakt feuert eben nicht nur einmal, sondern u.U. dutzende Male pro Schritt.
Wenn deine INT Quelle prellfrei ist, spricht nichts gegen Hardware Interrupts.
Die Timer Methode funktioniert zuverlässig auch bei alten und verdreckten Encodern, ist konfigurierbar und vorhersehbar in der Laufzeit. Warum also sollte man das Rad immer wieder neu erfinden?
Aber diese Diskussion muss man auch nicht immer wieder neu anfangen.
Ich sags nochmal (und Gott sei Dank zum letzten Mal):
Polling ist ineffektiv, es geht oft eleganter und einfacher.
Du verstehst offensichtlich unter pollen etwas anderes als die meisten hier.
Falls Du unter pollen das verstehst, was der TO tut, dann ist das nicht gemeint. Der Code ist der erste, lehrreiche Versuch eines totale Anfängers und dazu ok. Niemand würde sowas nutzen wollen.
Pollen ist das übliche Verfahren, um mit minimaler worst-case-Rechenleistung mit prellenden Signalen umzugehen. Dass es auch mit HW geht, geschenkt. Aber HW erfordert halt ... HW. und ist damit z.B. nicht flexibel.
Natürlich gibt es Grenzen. Z.B. dort, wo Signale mit dem SysTicker nicht mehr aufgelöst werden können (> 6000 / min oder 100/s).
Mache Dich einfach mal damit vertraut, Du wirst sehen, welche neuen Möglichkeiten sicher ergeben und wie einfach vieles wird.
Nebenbei: Prellen ist kein Dauerzustand, sondern eine
Ausnahme.
Das kommt drauf an, ob der Drehgeber gerade auf einer Signalwechselkante "steht" und wie die Spur abgetastet wird. Nur rastende Geber können sicher stellen, dass der Geber nicht an der Kante hängt. Bei optisch abtastenden ohne Rastung kann an der Kante viel passieren - je nach Hardware.
Nebenbei: Prellen ist kein Dauerzustand, sondern eine
Ausnahme.
Das kommt drauf an, ob der Drehgeber gerade auf einer Signalwechselkante
"steht". Nur rastende Geber können sicher stellen, dass das nicht der
Fall ist.
Darauf kommts doch gar nicht an. Wenn so ein Drehgeber prellt und kratzt, zählt das rasant auf und ab und wird zum Zufallsgenerator.
Darauf kommts doch gar nicht an. Wenn so ein Drehgeber prellt und
kratzt, zählt das rasant auf und ab und wird zum Zufallsgenerator.
Was heißt "Zufallsgenerator"?
Wenn das Signal hin und her springt, gibt es einen wohl definierte Position, die in dem Fall zwischen den beiden Zählerständen liegt. Da der Zähler digital arbeitet, kann er den Zwischenwert, der der tatsächlichen Position entsprechen würde, nun mal nicht anzeigen. Eine Möglichkeit wäre, die Springerei durch eine Hysterese für die Erkennung der Richtungsumkehr zu unterbinden.
Bei optisch
abtastenden ohne Rastung kann an der Kante viel passieren - je nach
Hardware.
Die Tage ist sogar einer explodiert. Der hatte vergessen, seine Hysterese einzustecken.
Zittern, Surren, Vibrieren, Jittern, Klingeln, Jauchzen, Frohlocken - da kann man nur noch Prollen.
Darauf kommts doch gar nicht an. Wenn so ein Drehgeber prellt und
kratzt, zählt das rasant auf und ab und wird zum Zufallsgenerator.
Was heißt "Zufallsgenerator"?
Wenn das Signal hin und her springt, gibt es einen wohl definierte
Da hats doch drei Kontakte die schleifen, wenn man denn das betätigt.......................... .....-.. ..
Wie oben schon verlinkt. Du kannst dir ein gut "funktionierendes" Beispiel für 3,95€ bei Temu bestellen. Ein paar mal hin und her gedreht (o. auch ein paar mehr), geben die verbauten Kontakte ihre wahre, dunkle Seele preis.
Man muss nur genügend Affen und Schreibmaschinen zur Verfügung haben, um einen Roman zu schreiben!
Da hats doch drei Kontakte die schleifen, wenn man denn das
betätigt.......................... .....-.. ..
Wenn der gemeinsame Kontakt macht was er will, würde der Zähler nicht definiert zwischen zwei Werten hin und her springen und auch Polling würde das Problem nicht lösen.
Da hilft dann nur /dev/nul
Wenn der gemeinsame Kontakt macht was er will, würde der Zähler nicht
definiert zwischen zwei Werten hin und her springen und auch Polling
würde das Problem nicht lösen.
Ach, ein klein wenig oversampling, in die Entprellung noch eine kleine Zustandsbestätigung* eingebaut, 3-5x reichen da dicke und du hast jahrelang, an den billigsten Alps, Spas bis zum abwinken. :)
Ich denke, mit meiner Einschätzung von heute richtig gelegen zu haben:
Vielleicht ist es ja am besten, wenn man auf so konfliktbelastete
Eingabeelemente wie Drehgeber verzichtet, die rufen ja offensichtlich
bei gleich mehreren Fraktionen Unwohlsein und Empfindungen hervor.
Damit die Flankeninterruptfraktion mal einen Eindruck davon bekommt, wie
wild ein Schaltvorgang bei einem mechanischen Encoder aussehen kann,
habe ich einen Panasonic-Encoder, wie es ihn es eine Zeit lang bei
Pollin zu kaufen gab, ans Oszi angeschlossen. In den Beispielen ffl5.png
und ffl6.png dauert das Prellen fast 30µs lang. Von den vielen Flanken,
die dabei entstehen, triggert die erste einen Interrupt. Tritt die
zweite Flanke auf, Während die Interruptroutine noch läuft, wird
zunächst das Interruptflag erneut gesetzt und nach Beendigung der
Interruptroutine diese sofort ein zweites Mal aufgerufen, d.h. auch die
zweite Flanke wird noch registriert. Tritt zeitnah aber noch eine dritte
Flanke auf, geht diese verloren, was zu einem Zählfehler führt. Treten
(wie in den Beispielen) weitere Flanken in kurzer Folge auf, können auch
diese (zumindest teilweise) verlorengehen, was den Zählfehler
entsprechend vergrößert.
Verwendet man eine periodische Abtastung statt der flankengetriggerten
Interrupts, tritt dieses Problem prinzipbedingt nicht auf.
Für die, die sich Sorgen wegen der dauerhaft verbrauchten CPU-Zeit
Sorgen machen: Für manuell betätigte Encoder ist eine Abtastperiode von
1ms völlig ausreichend. Die Dauer einer Abtastung inkl. Auswertung
beträgt auf einem 16MHz-AVR weniger als 2µs. Somit werden dafür gerade
einmal 2µs / 1ms = 0,2% CPU-Zeit benötigt, was nicht sonderlich ins
Gewicht fällt. Auch die 2µs, in der die CPU periodisch mit der
Auswertung beschäftigt ist, werden i.Allg. kaum stören, schon gar nicht
angesichts der fast 30µs, die die Flankeninterruptmethode im worst Case
mit der Auswertung eines einzelnen (prellenden) Schaltvorgangs
verbringt.
Mittels Tiefpässen an den A-und B-Signaleingängen kann man unter Nutzung
der Schmitttrigger-Charakteristik der AVR-Eingänge prinzipiell auch die
Flankentriggermethode zum Laufen bringen. Ich persönlich würde aber die
vier zusätzlichen Bauteile einsparen und bevorzuge die Softwarelösung.
Diese hat zudem den Vorteil, dass sie auch für Mikrocontroller ohne
Hysterese an den Eingängen funktioniert.
Vielleicht ist es ja am besten, wenn man auf so konfliktbelastete
Eingabeelemente wie Drehgeber verzichtet, die rufen ja offensichtlich
bei gleich mehreren Fraktionen Unwohlsein und Empfindungen hervor.
Dabei eignen die sich wunderbar, um geplante Obsoleszenz geschickt in Produkten zu verstecken.
Die Auswertung aus dem Timer-Interrupt funktioniert einfach dauerhaft, auch wenn der Drehgeber seine 100000 Umdrehungen aus dem Datenblatt hinter sich hat. Und danach vermutlich noch 10-mal so lange.
Die Auswertung mit Flanken-Interrupts funktioniert die Garantiezeit des Geräts ausreichend gut, wird dann schnell immer schlechter, und kurz nach Garantieablauf springt der Stellwert wild durch die Gegend, mal hoch mal runter, gerne auch mal 20 Schritte in einer Rastung, egal in welche Richtung man den Drehgeber dreht. Oder das Gerät stürzt gleich ab. Der Kunde kauft dann entnervt ein Neues.
Also: Aus BWL-Sicht ist die Flanken-IRQ-Lösung deutlich besser. Und was für große Firmen gut ist, kann doch für uns kleine Bastler nicht schlecht sein, oder?
Ich hatte schon mal eine Steuerung für eine Flügelzellenpumpe, die durch Drehgeber-Interrupts sogar abgestürzt ist: da war ein optischer Encoder mit einer Auflösung von 2048 Strichen für die Positionsermittlung einer Pumpenachse zuständig. Weil das ein elektronischer Ausgang war, prellte da also nicht mal was. Das ging dann auch alles gut, solange das Getriebe spielfrei war und das zu pumpende Medium eine ausreichend hohe Viskosität hatte. Wenn dann aber Alterung und ein dünnflüssiges Medium zusammenkamen, konnte bei sehr langsamen Geschwindigkeiten der Regler ein wenig hektisch werden und leicht ins Schwingen kommen. Wenn das dann grade an einem Pegelwechsel war, dann wurde der Rechner mit Interrupts zugetextet, bis der Stack überlief und das Ding einen Reset machte. Weil der Reboot weniger als eine Sekunde dauerte, störte es die User nicht weiter. Und das Vibrieren hörte auf, weil die Pumpe beim Starten zum Gebertest ein paar Striche weiterfuhr.
Und weil das niemanden störte, haben wir diesen Fehler erst nach 30 Jahren bei einem Redesign dieser Steuerung gesehen, gefunden und behoben.
Ich frage mich, wieso hat der Hersteller das überhaupt in seine
Controller und Mikroprozessoren eingebaut, wenn daß solche
schlimme Sache ist? Für irgendwas muß das doch gut sein.
Historisch sind Interrupts für Unterbrechungsanforderungen aus anderen elektronischen Bausteinen oder von anderen Softwaremodulen heraus vorgesehen (DMA, Timer, Serielle Schnitte, Interfaces, BIOS-Interrupts...). Dass man da auch unkonditionierte, prellende manuelle Signalgeber anschließen kann, auf diese Idee wäre zum damaligen Zeitpunkt keiner der Entwickler gekommen.
Für irgendwas muß das doch gut sein.
Es liegt immer im Ermessen des Entwicklers, wofür er die Ressourcen seines Bausteins verwendet. Und auch, ob diese Lösung für die gestellte Aufgabe gut ist.
Die Auswertung mit Flanken-Interrupts funktioniert die Garantiezeit des
Geräts ausreichend gut, wird dann schnell immer schlechter, und kurz
nach Garantieablauf springt der Stellwert wild durch die Gegend, mal
hoch mal runter
Ich persönlich bekomme die Galle, wenn ich wieder mal so ein herumzickendes Gerät mit Drehgeber habe und ich den Programmierfehler in dessen Software direkt vor meinem geistigen Augen sehe. Und dann wünsche ich diesen und überhaupt allen Softwareentwicklern, dass sie lauter Geräte mit ebensolch guter Software bekommen, wie sie selber ihre Software schreiben.
Ich persönlich bekomme die Galle, wenn ich wieder mal so ein
herumzickendes Gerät mit Drehgeber habe
Hmm. Im Büro hatten wir einen ganzen Stapel einfacher Hameg-Oszilloskope, die wegen ihrer Drehgeber unbrauchbar wurden. Bei einigen haben wir dann den Aufwand getrieben, die Dinger zu ersetzen, aber das ist eine zeitraubende Aktion ... die anderen kamen in den Keller. Der ist bei uns die Vorstufe für den Elektroschrott.
Ich persönlich würde aber die
vier zusätzlichen Bauteile einsparen und bevorzuge die Softwarelösung.
Diese hat zudem den Vorteil, dass sie auch für Mikrocontroller ohne
Hysterese an den Eingängen funktioniert.
Ein sehr interessanter Aspekt, den ich gerne nachvollziehen möchte. Gut informiert, wie Du immer bist (kein Scherz!), kannst Du mir bestimmt einen handelsüblichen µC empfehlen, der an seinen Eingängen keine Schmitttrigger hat. Ich brauche noch dringend ein Weihnachtsgeschenk für mich!
Als Festtagsmenü kommen dieses Jahr übrigens Angsthasen auf den Teller - anders wird man die wohl nicht los.
Bereits eingangs wurden dem TO Lösungsmöglichkeiten für sein Problem gezeigt. Ich hoffe, er ist längst fertig, obwohl in seinem 'proppenvollen' Programm sicherlich noch zwei bis drei Bit einzusparen wären. Mach mal ein Foto!
Wir können derweil noch darüber sprechen, warum UPN die einzig sinnvolle Eingabemethode bei Taschnerechnern, FORTH die einzig wahre Programmiersprache und Festkommaarithmetik 'float'-Berechnungen in der praktischen Anwendung haushoch überlegen sind.
Das hatten wir jetzt schon länger nicht mehr.
Kaputte Drehgeber war bei mir der Grund, ein HiFi Gerät zu entsorgen. 1x konnte ich ihn erneuern. Beim zweiten mal habe ich mit einem anderen getauscht der nur selten benutzt wurde. Beim dritten mal habe ich kein Ersatzteil mehr gefunden. Eigentlich schade umd Gerät.
Die Auswertung mit Flanken-Interrupts funktioniert die Garantiezeit des
Geräts ausreichend gut, wird dann schnell immer schlechter, und kurz
nach Garantieablauf springt der Stellwert wild durch die Gegend, mal
hoch mal runter
Ich persönlich bekomme die Galle, wenn ich wieder mal so ein
herumzickendes Gerät mit Drehgeber habe und ich den Programmierfehler
in dessen Software direkt vor meinem geistigen Augen habe. Und dann
wünsche ich diesen und überhaupt allen Softwareentwicklern, dass sie
lauter Geräte mit ebensolch guter Software bekommen, wie sie selber ihre
Software schreiben.
Dem kann ich nur zustimmen. Mein Philips DAB Radio (AJB3552/12) nervt mich beim Weckzeit einstellen genau damit. Es wird zum Geduldsspiel.
Das ging dann auch alles gut, solange das
Getriebe spielfrei war und das zu pumpende Medium eine ausreichend hohe
Viskosität hatte. Wenn dann aber Alterung und ein dünnflüssiges Medium
zusammenkamen, konnte bei sehr langsamen Geschwindigkeiten der Regler
ein wenig hektisch werden und leicht ins Schwingen kommen.
Modellbauservos haben das schon seit langer Zeit durch eine Hysterese für die Richtungsumkehr (aka tote Zone) gelöst.
Ich hatte schon mal eine Steuerung für eine Flügelzellenpumpe, die durch
Drehgeber-Interrupts sogar abgestürzt ist: da war ein optischer Encoder
mit einer Auflösung von 2048 Strichen für die Positionsermittlung einer
Pumpenachse zuständig.
Selber hatte ich auch einmal einen UKW-Empfänger eines dt. Edelherstellers, wo ein optischer Encoder mit ca. 200 'Strichen'/Umdrehung verbaut war. Durch Drehdynamik und etwas Masse des Schwungrades, war die Bedienung so angenehm wie seinerzeit bei einem Röhrenradio mit Seilzug und Skala.
Alles ermöglicht per Flankeninterrupts am µC. Der µC war ein 8051-Derivat, der C-Compiler von Keil und das Programm dafür habe ich auch noch.
Angenehm und nützlich: wenn keine Bedienung erfolgte, lag der µC im Tiefschlaf und störte nicht den Empfang ;-)
kannst Du mir bestimmt
einen handelsüblichen µC empfehlen, der an seinen Eingängen keine
Schmitttrigger hat. Ich brauche noch dringend ein Weihnachtsgeschenk für
mich!
Tja, dann war Weihnachten wohl schon.
Bei den Picos kann man in den PAD Einstellungen den Schmitt-Trigger pro GPIO gezielt ein- und aussschalten.
Frohes Fest.
Edit:
Eine RC-Kombination und beim Durchgang bei 1/2 der Versorgungsspannung gibt's ein wildes 1/0/1/0/… Lesen.
Gut informiert, wie Du immer bist (kein Scherz!), kannst Du mir
bestimmt einen handelsüblichen µC empfehlen, der an seinen Eingängen
keine Schmitttrigger hat.
Die meisten mir bekannten µC (isnbesondere AVR, RP2040 (deaktivierbar)
und CH32Vxxx) haben tatsächlich Schmitttriggereingänge. Die wenigen mir
bekannten Ausnahmen sind ESP8622, ESP32, ESP32-S[23] und ESP32-C3, die
aber alle noch sehr handelsüblich sind (du wolltest ja nur /eine/
Empfehlung ;-)). Neuere ESPs (ESP32-C5, ESP32-C61, ESP32-H2 und
ESP32-P4) haben eine softwaremäßig (de)aktivierbare Hysterese.
wolle_wolle interessiert das Thema seit seiner Thread-Eröffnung wohl nicht mehr.
Schön losgetreten, bei der Drehgeber-Auswertung kommen immer wieder interessante, gegenseitige Anfeindungen hoch.
Langsam glaube ich wirklich, dass hier Soziologen o.ä. Studien betreiben :-)
Wir können derweil noch darüber sprechen, warum UPN die einzig sinnvolle
Eingabemethode bei Taschnerechnern, FORTH die einzig wahre
Programmiersprache und Festkommaarithmetik 'float'-Berechnungen in der
praktischen Anwendung haushoch überlegen sind.
Der Liste hinzuzufügen wäre, printf unabhängig von den verfügbaren Ressourcen zu vermeiden, wie das Weihwasser durch Teufel. Oh, und auch nie, niemals nie einen Debugger zu verwenden, sondern "Debugausgaben".
Die meisten mir bekannten µC (isnbesondere AVR, RP2040 (deaktivierbar)
und CH32Vxxx) haben tatsächlich Schmitttriggereingänge. Die wenigen mir
bekannten Ausnahmen sind ESP8622, ESP32, ESP32-S[23] und ESP32-C3
Die ESP kenne ich garnicht. Da habe ich mir die Datenblätter wiederholt angesehen und festgestellt, daß diese Controller für meine Anwendungen nur suboptimal sind. Wenn in den Datenblättern eine Eingangshysterese nicht explizit erwähnt ist, würde ich trotzdem vermuten, das eine vorhanden ist. Ein linearer Betrieb von digitalen Schaltungen ist sicher nicht gewünscht.
Testen könnte man die Eingänge, indem man einen RC-Oszillator aufbaut: Eingang mit C gegen GND und Widerstand zu einem anderen Ausgang, der das Eingangssignal invertiert.
Mit Deinem Oszilloskope kannst Du bestimmt die Hysterese am Eingang sehen, ohne Explosionsgefahr ;-)
Unbeabsichtigt ist mir das auch bei einem ..1G04 Inverter begegnet, wo ca. 100 mVss zu sehen waren.
Wenn Dir Teile fehlen, kann ich Dir gerne Rs und Cs im 0805 Gehäuse zuschicken. Die brauchst Du allein schon, um die Schaltkontakt 'freizubrennen'.
Ja, der RP2040 hat seine Eingangshysteresen nach dem Einschalten aktiviert. Dafür hat der Hersteller bestimmt wichtige Gründe. Die Hysterese abzuschalten sollte man daher Profis überlassen, die eine passende LIB schreiben können. Ich traue mich da nicht dran.
Wenn in den Datenblättern eine Eingangshysterese nicht explizit
erwähnt ist, würde ich trotzdem vermuten, das eine vorhanden ist.
Selbst wenn das der Fall wäre, könnte man sich ohne entsprechende
Angaben im Datenblatt nicht darauf verlassen.
Um die Hysterese der GPIOs zu testen, habe ich mal für den ESP32-C3 und
den RP2040 ein Progrämmchen geschrieben, das nichts weiter tut als
ständig von einem Digitaleingang ein Signal zu lesen und dieses auf
einem Digitalausgang auszugeben. An den Eingang habe ich ein
Dreiecksignal mit 10 Hz und 0,0V..3,3V angelegt. Das Eingangs- und das
Ausgangssignal habe ich ans Oszi geschickt, wo man die Hysterese (falls
vorhanden) erkennen und messen kann. Die 10 Hz sind langsam genug, um
die Verzögerung des Ausgangs- gegenüber dem Eingangssignal durch die
Software vernachlässigen zu können.
esp32-c3-1.png: Die Schaltschwellen für das ansteigende und das
abfallende Signal sind gleich -> keine Hysterese.
esp32-c3-2.png: Wie zuvor, aber mit anderer Zeitbasis. Man erkennt dass
der erfasste Logikpegel im Bereich der Schaltsachwelle stark zappelt.
rp2040-mh-1.png: Die Schaltschwellen für das ansteigende und das
abfallende Signal liegen etwa 500 mV auseinander -> Hysterese.
rp2040-mh-2.png: Wie zuvor, aber mit anderer Zeitbasis. Die Hysterese
sorgt für einen sauberen Low-High- und High-Low-Übergang.
rp2040-oh-1.png: Die Hysterese wurde softwaremäßig deaktiviert, die
Schaltschwellen für das ansteigende und das abfallende Signal sind
gleich -> keine Hysterese.
rp2040-oh-2.png: Wie zuvor, aber mit anderer Zeitbasis. Man erkennt dass
der erfasste Logikpegel im Bereich der Schaltsachwelle stark zappelt.
Durch das recht deutloche Übersprechen des Ausgangs auf den Eingang
dauert das Gezappel sogar noch deutlich länger als beim ESP32-C3.
Danke!
Fazit für mich: die ESP geben ein schlechtes Bild ab, da ja wohl alle GPIO-Eingangsignale nicht richtig aufgearbeitet werden. Im Datenblatt und im technischen Referenzhandbuch ist kein "hysteres" zu finden.
Ein Grund mehr für mich, sich nicht mit diesen Teilen anzufreunden.
Wenn in den Datenblättern eine Eingangshysterese
nicht explizit erwähnt ist, würde ich trotzdem vermuten, das eine
vorhanden ist. Ein linearer Betrieb von digitalen Schaltungen ist sicher
nicht gewünscht.
Warum sollte ein nicht linearer Betrieb von digitalen Schaltungen eine Eingangshysterese implizieren?
Das eine hat mit dem anderen doch nichts zu tun. Solange du eine digitale Schaltung mit digitalen Signalen ausreichender Flankensteilheit ansteuerst, geht es auch ohne Schmitt-Trigger.
Fazit für mich: die ESP geben ein schlechtes Bild ab, da ja wohl alle
GPIO-Eingangsignale nicht richtig aufgearbeitet werden.
Die Eingangssignale werden schon richtig aufgearbeitet. Wie Rainer
bereits schrieb, wird halt erwartet, dass an den DIGITALeingängen
entsprechend ihrer Bestimmung DIGITAL- und nicht beliebige ANALOGsignale
anliegen. Dazu gehört insbesondere eine hinreichende Flankensteilheit.
Auch ich bin nicht der allergrößte Fan der ESPs, aber /damit/ hatte ich
noch nie irgendwelche Probleme.
Man findet im Netz Tausende zuverlässig funktionierender Schaltungen mit
ESPs. Ganz so schlimm kann die fehlende Eingangshysterese also nicht
sein. Probleme haben allenfalls diejenigen, die entgegen aller guten
Ratschläge mechanische Drehgeber mittels Flankeninterrupts auswerten
wollen, dabei feststellen, dass sie dies nicht zuverlässig hinbekommen,
und dann zu Work-Arounds wie externen RC-Filtern zurückgreifen ...
... womit wir wieder beim Thread-Thema angelangt wären :)
und dann zu Work-Arounds wie externen RC-Filtern zurückgreifen ...
Immerhin funktioniert der Workaround.
Korrekt funktioniert es nur, solange der daraus resultieren langsamen Flanke keine Störungen überlagert sind, die zu Klingeln in der Nähe der Schwelle führen. Nur mit einer Hysterese, die größer als die Störsignalamplitude ist, kannst du das verhindern.
Oder die Flanke muss eben so schnell sein, das der Frequenzgang der GPIO-Signalkonditionierung verhindert, dass Störungen auf der Flanke am GPIO Input so stark verstärkt werden, dass sie als digitale Zustandänderung weitergeleitet werden.
Man findet im Netz Tausende zuverlässig funktionierender Schaltungen mit
ESPs. Ganz so schlimm kann die fehlende Eingangshysterese also nicht
sein.
Was man im Netz so findet, ist für einige die Erfüllung und für andere nur grauenhaft. Beim RP2040 ist das richtig gut gelöst, sich die Eingangspins nach Bedarf konfigurieren zu können, und selbst mit eingeschalteter Hysterese ist der Kaufpreis nicht höher.
Schön sind dann zum Beispiel die STM32: MIT Hysterese und Quadraturdekodern.
Ich könnte jetzt noch einige Kommentare schreiben, was bekanntlich aber sowieso nicht fruchtet. Was mir immer wieder auffällt, daß die Polling-Fraktion wohl nie mit Interrupts gearbeitet hat und auf alles schimpft, was sie nicht kennt: "Das machen wir immer so!"
Damit diese Leute nicht völlig an ihrer Engstirnigkeit verzagen müssen, gibt es hier zur Kompensation das 'Bewertungssystem'.
;-)
Was mir immer wieder auffällt, daß die Polling-Fraktion wohl nie mit
Interrupts gearbeitet hat und auf alles schimpft, was sie nicht kennt:
"Das machen wir immer so!"
Nun, es ist halt schön, ein Auswerteverfahren zu haben, das auf jedem
Mikrocontrollertyp (auch ohne Schmitt-Trigger) zuverlässig funktioniert
und ohne externe RC-Glieder auskommt. Warum sollte man sich das Leben
unnötig schwer machen und ein anderes Verfahren einsetzen, das diese
beiden Vorteile nicht hat?
Wenn der Mikrocontroller einen hardwaremäßigem Quadraturdecoder/-zähler
hat, ist das natürlich eine feine Sache. Der arbeitet übrigens exakt so,
wie die softwaremäßige Pollingmethode, nur sehr viel schneller.
Dass das mit der Flankenauswertung nicht zuverlässig funktioniert, haben
schon die Entwickler der legendären Quadraturdecoder/-zähler-ICs
HCTL-20xx von HP/Agilent/Avago erkannt. Auch diese ICs tasten das A- und
B-Signal periodisch ab, was daran zu erkennen ist, dass sie einen
externen Takt benötigen. Ich habe mich damals zunächst selber gefragt,
warum die das so kompliziert machen und nicht einfach die Signalflanken
direkt auswerten, so dass kein externer Takt erforderlich wäre. Recht
bald wurde mir aber klar, dass die Entwickler dies nicht aus Dummheit
taten ;-)
Dass das mit der Flankenauswertung nicht zuverlässig funktioniert, haben
schon die Entwickler der legendären Quadraturdecoder/-zähler-ICs
HCTL-20xx von HP/Agilent/Avago erkannt. Auch diese ICs tasten das A- und
B-Signal periodisch ab, was daran zu erkennen ist, dass sie einen
externen Takt benötigen.
Wenn Du es brauchst, von LS2000 bis THCT12024 habe ich noch einige Teile vorrätig. Vergiss bei mechanischen Gebern nicht, RC-Glieder vor die Eingänge zu setzen ;-)
Bei dem weiter oben von mir verlinkten Projekt/Programm kann man den ATmega übrigens im Interruptmodus oder mit 400 kHz periodischer Abfrage betreiben.
Nur so, falls es von Interesse sein sollte.
Nochmal auf die Hardware Quadraturdekoder zu kommen: die gibt es kaum noch oder teuer zu beschaffen. Als Alternative kann man jedoch den guten RP2040 verwenden: Abtastrate von ganz schnell bis ganz langsam, bis zu vier Kanäle mit Index-Eingang und mit Arduino IDE auf eigene Bedürfnisse anpassbar:
http://mino-elektronik.de/mt12_iic/mt12_iic.htm#qcnt_pico
Nur so, falls es von Interesse sein sollte ;-)
Vergiss bei mechanischen Gebern nicht, RC-Glieder vor die
Eingänge zu setzen ;-)
bevor Du nachfragst, will ich das noch einmal erläutern.
Es ist eine praktische Erfahrung, daß mechanische Geber an schnellen Dekodern Fehlzählungen erzeugen. Meine Vermutung dabei ist, daß ein Prellen selten aber gleichzeitig auf beiden Kanälen stattfindet, was als schneller Schritt ausgewertet wird. Ein kleiner Tiefpass kann das unterdücken.
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese Störung zu erwischen. Bei 100 Hz ist allein schon rein rechnerisch die Wahrscheinlichkeit deutlich niedriger und sofern der Drehgeber nur eine relative Bewegung wiedergeben soll, fällt das auch garnicht auf.
Quadratursignale von optischen oder magnetischen Gebern haben in der Regel eine nahezu 90° Phasenlage zwischen den Kanälen, weshalb hier die Dekoder nicht 'überumpelt' werden.
Was mir immer wieder auffällt, daß die
Polling-Fraktion wohl nie mit Interrupts gearbeitet hat
Stimmt ja gar nicht. Als ich es noch nicht besser wusste, habe ich auf dem alten 8051 auch mit INT gewurschtelt und mich gefreut, das es mit einem nagelneuen Encoder gut funktionierte. Aber als der Encoder in die Jahre kam in der Bassanlage, wurde das immer mehr ein Geduldsspiel. Der 8051 ist nun Geschichte und ich bin froh, das es eine Plug-In Variante mit Timer gibt, die auf so gut wie alle MC zu portieren ist und selbst mit alten Encodern gut funktioniert.
Muss das mal auf Micropython übertragen...
Finde den Fehler!
Mi N. schrieb im Beitrag #7983870:
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese
Störung zu erwischen. Bei 100 Hz ist allein schon rein rechnerisch die
Wahrscheinlichkeit deutlich niedriger und sofern der Drehgeber nur eine
relative Bewegung wiedergeben soll, fällt das auch garnicht auf.
Oder warum machen "wir" den deiner Meinung nach, den ganzen "Straggle" mit dem Polling? Was ist "unsere" größte Motivation, dies zu tun?
@Yalu X.
Und dabei heist es doch immer "Dummheit tut nicht weh". :=)
Was mir immer wieder auffällt, daß die
Polling-Fraktion wohl nie mit Interrupts gearbeitet hat
Stimmt ja gar nicht.
Ich weiß jetzt nicht, warum gerade Du Dich angesprochen fühlst. Soweit ich Deine Beiträge kenne, machst Du das, was sinnvoll ist, und weißt auch, wie es jenseits vom Tellerrand aussieht.
Mir kommt es etwas auffällig vor, daß Peter D. Vorschläge und Beispiele hier nicht erwähnt werden. Ohne auf diesen Faden einzugehen, sind meine Erfahrungen mit Peters Design immer extrem gut gewesen und lassen für meine Zwecke keine Wünsche offen. Meist aus einer 1ms Timer ISR operierend funktioniert es absolut zuverlässig. Ich habe sein Konzept bis jetzt mit guten Erfolg auf PIC, AVR/Arduino, 8051, MSP430, Zilog Encore! und früher einmal auf STM32F103 getestet. Auch Multikanal ist möglich. Sein Konzept ist auch sehr Ressourcen schonend. Was mich betrifft, brauche ich nicht mehr über den Zaun schauen.
Mir kommt es etwas auffällig vor, daß Peter D. Vorschläge und Beispiele
hier nicht erwähnt werden.
Hallo Gerhard,
ich hatte es versucht. Diese Argumente verhallen jedoch schnell.
Beitrag "Re: Handbetriebenen Drehgeber ohne Timer auswerten"
Es wird lieber ein RC Glied empfohlen, welches bei immer mehr ausgeleierten Kontakt wirkungslos wird, statt es richtig zu machen. Im Gegenteil, 1MHz Abtastung und RC Glied passt so überhaupt nicht zusammen. Zu viele Widersprüche in sich, jedoch wird auf denen beharrt. Statt mit Argumenten zu kommen, kommen dann allgemeine Sprüche, dass alle anderen blöd sind. Was will man dazu noch sagen.
Egal was hier einige schreiben oder denken. Die beste Methode ist eine zyklische Zustandsabfrage, wie es Peter D. macht. Ob das Zyklische mittels Timer Interrupt oder Polling gelöst wird, spielt keine Rolle, solang die Abtastrate passt.
Wenn man dagegen auf Pin Interrupts reagiert, wundert mich es nicht das es Horror wird und dann mit RC Glied als Nicht-Dauerlösung ausgewichen wird. Man muss nur den Unterschied verstehen wollen und sich vor Augen führen, was in beiden Varianten passiert und den Unterschied macht.
Was mir immer wieder auffällt, daß die Polling-Fraktion wohl nie mit
Interrupts gearbeitet hat und auf alles schimpft, was sie nicht kennt:
"Das machen wir immer so!"
Im Gegenteil.
Die Leute haben aus ihren Fehlern gelernt.
Du hast noch nichts gelernt (und weigerst dich dazuzulernen weil du dich ja schon für ein allwissendes Genie hältst).
Es ist eine praktische Erfahrung, daß mechanische Geber an schnellen
Dekodern Fehlzählungen erzeugen. Meine Vermutung dabei ist, daß ein
Prellen selten aber gleichzeitig auf beiden Kanälen stattfindet, was als
schneller Schritt ausgewertet wird. Ein kleiner Tiefpass kann das
unterdücken.
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese
Störung zu erwischen. Bei 100 Hz ist allein schon rein rechnerisch die
Wahrscheinlichkeit deutlich niedriger und sofern der Drehgeber nur eine
relative Bewegung wiedergeben soll, fällt das auch garnicht auf.
Mir kommt es etwas auffällig vor, daß Peter D. Vorschläge und Beispiele
hier nicht erwähnt werden. Ohne auf diesen Faden einzugehen, sind meine
Erfahrungen mit Peters Design immer extrem gut gewesen und lassen für
meine Zwecke keine Wünsche offen. Meist aus einer 1ms Timer ISR
operierend funktioniert es absolut zuverlässig.
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese
Störung zu erwischen.
Ja, und dann? Dann zählt der einfach um 1 weiter und gleich danach wieder zurück.
Quadratursignale von optischen oder magnetischen Gebern haben in der
Regel eine nahezu 90° Phasenlage zwischen den Kanälen, weshalb hier die
Dekoder nicht 'überumpelt' werden.
Störungen haben die unangenehme Eigenschaft, sich nicht an Phasen zu halten.
daß die Polling-Fraktion wohl nie mit Interrupts gearbeitet hat und auf
alles schimpft, was sie nicht kennt
Man sollte seine Werkzeuge kennen. Und Interrupts sind keine Werkzeuge zum einlesen quasianaloger und per Definition gestörter Signale. Bestenfalls zum Aufwecken aus dem Sleepmode taugen sie, denn da macht es nichts aus, wenn sie 1 oder 20 mal schnell hintereinander das Aufwachen antriggern.
Was mir immer wieder auffällt, daß die
Polling-Fraktion wohl nie mit Interrupts gearbeitet hat und auf alles
schimpft, was sie nicht kennt:
Normalerweise gibt es 4 Stufen:
Neuling: While-Schleife in main und alles nacheinander. Geht nur mit einer Aufgabe (sowas wie Tasten auswerten und dann ein LED-Muster weiterschalten).
Anfänger: Interrupts. Quasi statt RTOS.
Allwissend: RTOS und Interrupts. Aber "Erdstrahlen" aka Race Conditions
Erfahren: Zyklisch (aka SPS-Loop, aka Timerinterrupt). Und weil man den Rest kennt, nutzt man ihn da, wo er sinnvoll ist. Aber aus 20 Tasks werden 2 oder 3. Und Tasten oder Drehgeber nur selten mit Interrupts)
Wir hatten einen sehr guten SW-Entwickler, PC und embedded, der SPS tatsächlich erst nach 20 Jahren verstanden hat.
Neuling: While-Schleife in main und alles nacheinander. Geht nur mit
einer Aufgabe (sowas wie Tasten auswerten und dann ein LED-Muster
weiterschalten).
Wenn man die Aufgabe damit zufriedenstellend erledigen kann, spricht nichts dagegen.
Anfänger: Interrupts. Quasi statt RTOS.
Wenn man die Aufgabe damit zufriedenstellend erledigen kann, spricht nichts dagegen.
Allwissend: RTOS und Interrupts. Aber "Erdstrahlen" aka Race
Conditions
Wenn man die Aufgabe damit zufriedenstellend erledigen kann, spricht nichts dagegen.
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese
Störung zu erwischen.
Ja, und dann? Dann zählt der einfach um 1 weiter und gleich danach
wieder zurück.
Eben leider nicht!
Da zappelt es, früher oder später, wie wild auf allen Kanälen wild rum. Man muss einen ruhigen Moment erwischen, um das sicher zu erfassen.
Eben leider nicht!
Da zappelt es, früher oder später, wie wild auf allen Kanälen wild
rum. Man muss einen ruhigen Moment erwischen, um das sicher zu erfassen.
Es ist ja ein "Grey-Code", der Wert schwankt z.B. zwischen 123456/4 oder 123455/4. Natürlich kann man argumentieren, dass der angezeigte Wert irgendwann zwischen 999 und 1000 hin und her schwankt, was übel wäre. Es hindert Dich aber niemand daran, eine Hysterese von 2 oder 3 Viertelschritten einzubauen. So wie bei jedem anderen Digitalwert auch.
Es ist ja ein "Grey-Code", der Wert schwankt z.B. zwischen
Ja dann mach hinne und mach deine eigenen Erfahrungen. Evtl. lernst du ja, das der Zufall, recht gut mit dem Grey-Code zurecht kommt. :)
Es ist ja nicht so, da ich nicht auch mal auf deinem Standpunkt war. Ich hatte wahrscheinlich nur viel Glück, durch einen recht üblen Alps Encoder, das in ~2-3 Wochen lernen zu dürfen... Den benutze ich heute noch bei der Entwicklung von SW!
Ja dann mach hinne und mach deine eigenen Erfahrungen. Evtl. lernst du
ja, das der Zufall, recht gut mit dem Grey-Code zurecht kommt. :)
Wo siehst Du denn ein Problem? Wie viele hier schon sagten, der polling-Ansatz funktioniert fehlerfrei und tadellos (solange pro Viertelschritt abgetastet wird).
Wenn der Drehgeber über den kompletten Schritt prellt, geht es auch mit Vodoo nicht.
die üblichen Handdrehencoder erzeugen von Rastung zu Rastung 4 Phasenwechsel. Die muss man nicht alle letztlich auswerten, sonst zählt es immer um 4 weiter von Rastung zu Rastung. Das wird er meinen mit Viertelschritte - je Rastung.
Bevor Missverständnisse auftreten. Die Software detektiert und verarbeitet schon alle Phasenwechsel, dass Ergbniss wird jedoch je nach Encodertyp korrigiert, sodass man pro Rastung wieder nur +/- 1 hat.
Um das allerletzte Wackeln auf Rastung komplett zu eleminieren, müssten die Handdrehencoder mechanisch präziser gefertigt werden. Dann sind sie nicht mehr billig. Die "eine wacklige" Phasenänderung darf dabei nicht auf den Rastpositionen liegen, sondern muss davor oder danach sein. Das sollte man den Herstellern vielleicht einmal sagen. :-)
Das wird er meinen mit Viertelschritte - je Rastung.
Ja. Einen vollen Zyklus AB=00, 01, 10, 11.
Die Abtastrate muss so schnell sein, dass jeder Viertelschritt einmal erkannt werden kann, egal wie viel Gezappel oder Prellen im Übergang passiert. Bei z.B. max. 400 Viertelschritten pro Sekunde (=2.5ms) reicht der 1ms-SysTicker zum Pollen.
Prellen und "Zappeln" muss man unterscheiden: Ein Kanal darf beim Drehen beim Übergang (01 oder 10) bis zu 1.5ms prellen, ohne dass es zu einer Fehlzählung kommt.
"Zappeln" (im Stillstand "zwischen" zwei Positionen) darf er unendlich lange, ohne dass es zu Fehlzählungen kommt. Man kann zwar eine Hysterese einbauen, aber einfache (straight) runterprogrammierte SW zappelt dann mit 25% Wahrscheinlichkeit. Das ist o.k., es zeigt (korrekt) an, dass der Drehgeber genau auf der Grenze ist. So, wie ein AD genau auf der Grenze um 1LSB toggelt.
Gleichzeitiges Prellen auf beiden Kanälen bekommst du, wenn der
gemeinsame Kontakt wackelig ist.
Der wesentliche Punkt ist: wenn beide Kanäle so sehr prellen, das sich im Zyklus der Bewegung das Prellsignal der beiden Kanäle überlagert, ist mit ABSOLUT keiner Methode mehr eine sinnvolle Abfrage möglich...
So einfach ist das eigentlich.
Und ja: auch Peter D's Code liefert dann nur noch sinnlosen Bullshit...
Jeder, der etwas anderes behauptet, ist ein Vollidiot, der die Naturgesetze ignoriert.
wenn beide Kanäle so sehr prellen, das sich im Zyklus der Bewegung das
Prellsignal der beiden Kanäle überlagert
Es ist, auch ohne jemanden als Vollidioten zu bezeichnen, noch viel einfacher: wenn sich zwischen 2 Abtastungen beide Kanäle ändern, dann ist die Drehrichtung nicht mehr bestimmbar. Und das ist der Fall, wenn zum Kontaktprellen noch eine verschmutze Kontaktbahn hinzukommt. Oder die Kontakte allein sind schon so verdreckt, dass nur noch beliebiger Käse reinkommt.
wenn beide Kanäle so sehr prellen, das sich im Zyklus der Bewegung das
Prellsignal der beiden Kanäle überlagert
Es ist, auch ohne jemanden als Vollidioten zu bezeichnen, noch viel
einfacher: wenn sich zwischen 2 Abtastungen beide Kanäle ändern, dann
ist die Drehrichtung nicht mehr bestimmbar. Und das ist der Fall, wenn
zum Kontaktprellen noch eine verschmutze Kontaktbahn hinzukommt. Oder
die Kontakte allein sind schon so verdreckt, dass nur noch beliebiger
Käse reinkommt.
Moin,
Irgendwie komme ich nicht mehr ganz mit. Anhand meiner Erfahrungen hatte ich immer gute Ergebnisse mit mechanischen Hand-Drehgebern. Sollte sich eventuell wirklich dauerhafte Unzuverlässigkeit einstellen, wechselt man die Billig Dinger einfach aus. Wir sprechen hier doch selbstverständlich von In-House Bauten und nicht Reparaturen von schwierig zu beschaffenden speziellen Drehgebern kommerzieller Gerätschaften. Wenn bei mechanischen DG manchmal selten ein Schritt nicht macht was er soll, dann lebt man eben damit und das ist auch nicht weiter sehr störend.
Wer absolute Zuverlässigkeit braucht, soll eben optische QE wählen. Wer absolut keinen Schritt verlieren möchte, sollte HW QE machen (LS7066 u.co., LS3183/4). Sich in solchen Fällen nur auf SW zu verlassen wollen sehe ich da eher als sportliches Unterfangen an. Es gibt schliesslich uC mit QE Eingängen der Zähler (STM32 z.B.)
Ironischerweise ärgert mich schon seit vielen Jahren der Drehgeber in meinem HP33120A FG. Das Ding ist eine Krankheit.
Jedenfalls funktionieren mechanische DG in den meisten Fällen problemlos genug. Wer sich selber DG Anwendungen bauen will, beschaffe sich halt bessere Qualität dann geht es schon. Von der uC DG SW erwarten zu wollen, daß sie mit dem Signal-Gewurschtel minderwertiger DG ohne Fehler fertig werden sollen, empfinde ich als unrealistischen Unfug. Jede Technik und SW hat ihre Grenzen. Wenn eine sauber entworfene Auswertungs-SW dann versagt, beschaffe man sich gefälligst bessere HW. RC-Filter und Beschwörungen gehen nur so weit.
Es nervt mich hier diese endlosen Auslassungen zu lessen, wenn doch jeder wissen sollte was man vom Technikstandpunkt und Theorie- und Lokikverhalten aus erwarten kann.
ich entschuldige mich bei der gesamten Gemeinde dafür, so kurz vor Weihnachten so einen Thread ausgelöst zu haben. Das hier ist ein gutes Forum, dass mir schon oft geholfen hat. Ich wollte wirklich keinen Streit hervor rufen!
Das Projekt läuft schon erfolgreich, aber auf zwei gekoppelten 328Ps (einfach wegen der Menge an Ports die ich brauche, diverse Taster, Drehgeber und kaskadierte MAX7219-Displays), da hatte ich Timer im Überfluss und konnte die Drehgeber-Abfrage sehr einfach bauen. Da ich Spaß am Basteln habe, schreibe ich den Code neu (in C, war ursprünglich Assembler) und multiplexe die Schalter und Taster, damit ich mit einem 328P auskomme. Und da ich 4 PWMs brauche (die ich nicht einfach multiplexen kann) und der verbliebene Timer für 3 Zeitsteuerungen her halten muss, wollte ich keine weitere Logik in die Interrupt-Routinen einbauen.
Und ja, mit einem Raspberry Pi war das alles kein Problem, aber ich fand, dass das mit weniger gehen muss. 7-Segment-Anzeigen machen mir auch mehr Spaß als ein Touch Display.
Nach den Feiertagen werde ich mir den Thread in Ruhe durchlesen. Ich vermute zwar, das ich mit meinem Lösungsansatz über die Runden komme, aber Code zu vereinfachen ist immer schön. Und ein paar feine Gedanken hab ich beim Überfliegen schon gesehen.
Also Danke nochmals für die konstruktiven Beiträge! Wenn ich was lernen kann, ist der Ton Nebensache. Und da ich nicht das ganze Projekt beschrieben habe, sind natürlich Fragen offen geblieben, dafür entschuldige ich mich!
Und da ich 4 PWMs brauche (die ich nicht einfach
multiplexen kann)
Aber einer der PWM Timer kann doch problemlos die Drehgeber mitbedienen. Die PWM Erzeugung kostet ja keinerlei Rechenzeit - höchstens zwischendurch mal das Nachladen eines neuen PWM Wertes.
Aber einer der PWM Timer kann doch problemlos die Drehgeber mitbedienen.
Hm. Ich gebe zu, dass ich das Datenblatt des 328p anders verstanden habe, sprich die PWM den Timer exklusiv in Beschlag nimmt. Danke für die Anregung, ich schau mir das nochmal genauer an.
sprich die PWM den Timer exklusiv in Beschlag nimmt.
Nö, tut sie nicht. Du kannst Interrupts bei beiden OCR Events auslösen, musst du aber nicht. Weiterhin gibts immer noch den OVF Interrupt.
Die PWM Erzeugung selber läuft in Hardware und beansprucht keine Rechenzeit.
Ich gebe zu, dass ich das Datenblatt des 328p anders verstanden
habe, sprich die PWM den Timer exklusiv in Beschlag nimmt.
Was meinst du damit?
Wenn der Timer läuft und dabei ein PWM-Signal erzeugt, kann er durchaus nebenbei noch einen Interrupt zum Auslesen von Drehgebern auslösen. Einzige Einschränkung ist, dass die Auslesefrequenz nicht höher als die PWM-Frequenz sein kann.
Doppelte PWM Frequenz sitzt drin, da eben min 2 Kanäle pro Timer.
Allerdings ist das Timing dann nicht mehr konstant, weil die OCR Interrupts kommen, wenn die Flanke des PWM passiert und das ist ja variabel.
Also besser den OVF benutzen, der kommt immer gleich schnell.
Hm. Ich gebe zu, dass ich das Datenblatt des 328p anders verstanden
habe, sprich die PWM den Timer exklusiv in Beschlag nimmt.
Beim ATmega328 kann jeder einzelne IO-Pin bei +/- Flankenwechseln einen Interrupt auslösen. Dafür braucht man garkeine Timer.
Wenn man in diesem Forum Fragen zum Schutz von Eingängen stellt, werden typischerweise Schaltungen gezeigt, die nur so mit Widerständen/Kondensatoren/Schutzdioden bestückt sind. ADC-Vref muss unbedingt per Drossel und weiteren Kondensatoren gefiltert werden, auch wenn es für die popeligen 10 Bit völlig egal ist.
Aber, wenn mechanische Schalter/Taster kein sauberes Signal liefern darf auf keinen Fall ein RC-Glied verwendet werden. Das muß gefälligst per Software ausgefiltert werden. Vermutlich müssen auch ESD-Impulse an den Eingängen per Software geschützt werden.
Wie doof ist das denn alles?
Wie es die Zeit mit sich bringt, ist auch ein Weihnachtswunder geschehen. Aus:
Es ist, auch ohne jemanden als Vollidioten zu bezeichnen, noch viel
einfacher: wenn sich zwischen 2 Abtastungen beide Kanäle ändern, dann
ist die Drehrichtung nicht mehr bestimmbar.
Aber, wenn mechanische Schalter/Taster kein sauberes Signal liefern darf
auf keinen Fall ein RC-Glied verwendet werden. Das muß gefälligst per
Software ausgefiltert werden. Vermutlich müssen auch ESD-Impulse an den
Eingängen per Software geschützt werden.
Wie doof ist das denn alles?
Ganz schön polemisch. Für wieviele ms willst denn das RC Glied auslegen? Nur um dann später festzustellen, dass die "Entprellzeit" irgendwann nicht ausreichend ist. Dir ist vermutlich noch immer nicht klar was eine zyklische Zustandsabfrage im Unterschied zur Pin-Interruptabfrage ist.
Dir ist vermutlich noch immer nicht klar was eine
zyklische Zustandsabfrage im Unterschied zur Pin-Interruptabfrage ist.
Was soll denn dieser Stuss?
Ich habe mehrere Beispielprogramme gezeigt, die mit verschiedenen Verfahren arbeiten.
Nicht gelesen? Ja, das dachte ich mir.
Wie es die Zeit mit sich bringt, ist auch ein Weihnachtswunder
geschehen. Aus:
Lothar M. schrieb:
Tastet man mit >= 1 MHz ab, hat man eine hohe Wahrscheinlichkeit, diese
Störung zu erwischen.
Ja, und dann? Dann zählt der einfach um 1 weiter und gleich danach
wieder zurück.
Wurde dann:
Lothar M. schrieb:
Es ist, auch ohne jemanden als Vollidioten zu bezeichnen, noch viel
einfacher: wenn sich zwischen 2 Abtastungen beide Kanäle ändern, dann
ist die Drehrichtung nicht mehr bestimmbar.
Ein Fachmann, zwei Meinungen ;-)
Dein Beitrag, auf den sich Lothars erste Antwort bezog, war missverständlich. Um es ganz klar zu sagen (mit t = Abtastzeit):
der einfache Poll-Ansatz ist fehlerfrei, wenn nur ein Kanal prellt und das Signal für mindestens t stabil ist (Viertelschritt-Zeit - Prellzeit > t)
Wenn beide Kanäle gleichzeitig prellen, wird es zur Kaffeesatz-Leserei.
Jede Auswertung muss individuell auf das Signal angepasst werden.
Im einfachen Poll-Ansatz zeigt der Fehlerzähler (Anzahl der Abtastungen mit 2 Flanken) das Ausmaß der Probleme. Das reicht meist aus, da 99,99% der Zeit nix passiert, wenn die HW prinzipiell geeignet ist.
Wenn beide Kanäle gleichzeitig prellen, wird es zur
Kaffeesatz-Leserei.
Man könnte für diesen Fall einen Algorithmus programmieren,
der daß als ungültig erkennt und verwirft, also
dann gar nichts macht.
Die beste Entprellmethode die ich kenne und am liebsten
mag, ist wenn der Kontakt ein Umschaltekontakt ist und
damit ein RS-Flip-Flop angesteuert wird.
Die optisch Abtastung einer Sektorscheibe, wie zum Beispiel
bei einer Computermaus, finde ich auch noch gut, da gibt es
auch kein Prellen und keine Kontaktprobleme.
Ich weiß nicht ob es sowas auch bei Handbetriebene Drehgeber
gibt.
Man könnte für diesen Fall einen Algorithmus programmieren,
der daß als ungültig erkennt und verwirft, also
dann gar nichts macht.
Genau das ist ja der Fall. Es gibt bei jeder Abtastung (nach der allerersten) genau 4 Fälle
steht (beide Signale unverändert)
links (ein Signal verändert)
rechts (ein Signal verändert)
Fehler (beide Signale verändert)
Prinzipiell kann beim Prellen alles passieren, auch 4 falsche "links" ohne einen "Fehler". Ist aber sehr sehr unwahrscheinlich.
Die 90-Grad-Signale gibt es genau darum: Minimaler Aufwand (in Sender und Empfänger, keine Entprellung erforderlich), maximale Sicherheit. Und (ggf. mit HW-Entprellung) auch per Zähler oder sogar Up/Down-Zähler auswertbar (1 Signal Richtung, das andere Zählflanke).
Ich bin zwar immer noch der Meinung, daß Peters Lösung für die Praxis "die" perfekte Lösung darstellt. Wenn Peters Lösung mit der Zeit nicht mehr funktionieren sollte, ist es eben an der Zeit den Drehgeber zu entsorgen.
Falsche Sprünge habe ich noch nie beobachten können. Entweder es funktioniert oder es tut sich gar nichts - Fehlerhaftes herumspringen gibt es nicht. Für Frontplatten Drehgeber mehr als ausreichend.
Der Code wurde zwar verlinkt und "Peter D" mehrfach erwähnt, aber quasi nicht zusammen. (Darum mache ich das mal)
Der Code von Peter Danneger ist für mich in soweit schwierig (wie auch seine meisterhafte Tastenentprellung), dass er jahrelange Erfahrung und maximale Funktionalität in minimaler Weise komprimiert. Ein Anfänger kann die Tricks und Kniffe nur verstehen, wenn er sie selbst prinzipiell "erfahren" hat.
Der Code wurde zwar verlinkt und "Peter D" mehrfach erwähnt, aber quasi
nicht zusammen. (Darum mache ich das mal)
Der Code von Peter Danneger ist für mich in soweit schwierig (wie auch
seine meisterhafte Tastenentprellung), dass er jahrelange Erfahrung und
maximale Funktionalität in minimaler Weise komprimiert. Ein Anfänger
kann die Tricks und Kniffe nur verstehen, wenn er sie selbst prinzipiell
"erfahren" hat.
Genau. Der zeitliche Overhead in der Timer ISR ist minimal. Auch Mehrfachkanal Operation funktioniert gut. Der Code ist insofern schwer verständlich, weil man zeitlich multi-dimensional denken muß weil die logischen Ergebnisse seiner Bearbeitung immer vomherigen Sample Punkt abhängig und verknüpft sind. Linear lässt sich sein Code nicht intuitiv verstehen bzw. lesen.
Ein Anfänger
kann die Tricks und Kniffe nur verstehen, wenn er sie selbst prinzipiell
"erfahren" hat.
Oder du wendest es einfach an.
Aber ich habe damals mit dem alten Simulator in AVR Studio 4 den Code mal untersucht und es ist wie beim Märchen: "Ich sags dreimal und es ist wahr". Viel mehr passiert da nicht. Und ja, nicht zweimal wie im Märchen sondern eben dreimal. Der Code ist allerdings so gut dokumentiert und mit Beispielen untermauert, das man ihn einfach verwenden kann. Das gilt für die Entprellung genauso wie für den Drehgeber.
https://www.mikrocontroller.net/articles/Entprellunghttps://www.mikrocontroller.net/articles/Drehgeber
Es ging genau um regelmäßige Abfrage der Pins, um Pin-Interrupts zu
vermeiden.
Es gibt keinen Grund, PCINTs zu vermeiden!
Schon klar, Du gehst jede Minute ans Telefon, um zu hören, ob jemand anruft.
Ich warte einfach, bis es klingelt ;-)
Es ging genau um regelmäßige Abfrage der Pins, um Pin-Interrupts zu
vermeiden.
Es gibt keinen Grund, PCINTs zu vermeiden!
Schon klar, Du gehst jede Minute ans Telefon, um zu hören, ob jemand
anruft.
Ich warte einfach, bis es klingelt ;-)
Du weißt das der Vergleich hinkt?
Du rennst bei jedem Spaßvogel zum Telefon.
Dir ist schon klar das es hier um mechanische Encoder geht?
Das ist ganz einfach falsch. PCINT kann man gut verwenden wenn der Input von Drehgebern mit Hall Sensoren o.ä. kommt. Bei allem was mechanisch bedient wird ist Polling die weitaus bessere Methode, da sie absolut berechenbar ist. Da gibt es in meinen Augen auch nichts zu diskutieren. Über Zeitfaktoren brauchen wir hier nicht reden, das liegt immer im unrelevanten Bereich. Und Blockieren tut da auch niemals etwas.
Schon klar, Du gehst jede Minute ans Telefon, um zu hören, ob jemand
anruft.
Ich warte einfach, bis es klingelt ;-)
Das ist auch falsch. Die Hauptlast in jedem µC Programm wird meistens durch eine main-Loop verursacht. Wir sind hier nicht auf einem PC. Um bei deinem Vergleich zu bleiben. Du läust ständig im Kreis und lässt dich von dem Stein überraschen den dir jemand ans Fenster wirft. Ich drehe bei jeder hundersten Runde mal kurz den Kopf zur Tür um zu sehen ob einer da ist.
Mich kann da nichts überraschen. Bei dir wird es kritisch wenn du gerade in der Nase popelst und den Stein vor die Hand kriegst.
Es macht einen Unterschied ob ich alles stehen und fallen lasse und zum Telefon hechte(Interrupt) oder es halt 10 Sekunden klingeln lasse und fertig mache was ich angefangen habe(polling).
Wenn du regelmäßig SCAM-Anrufe bekommst die nur 1-2 Sekunden läuten lassen, rennst du jedes mal los.
Mein Telefon klingelt auch in ner Sekunde noch. Du rennst sofort los.
Eher selektivens Lesen. Denn eine Störung ist etwas anderes als eine bis zur Unbrauchbarkeit verschlissen Kontaktbahn. Und beides zusammen ist was anderes als das Prellen eines Kontaktes. Aber in allen drei Fällen ist die Interrupt-Lösung weniger deterministisch.
Bei Contollern, deren Interruptstruktur etwas komplexer als die der alten AVR mit ihrer einen blockierenden Interruptebene sind, kann die vielfache, schnell aufeinanderfolgende Interruptgenerierung in beiden Fällen zudem zu eigenartigen Stack- und Semaphorenproblemen führen.
Kann man nichts machen. In jeder Generation "Maker" gibts wieder welche, die den komplizierten Standard-Code zur Drehgeber-Auswertung nicht verstehen, sich aber für klüger halten als die ganzen alten Säcke, die den verwenden oder gar in Hardware gegossen haben.
Die werfen dann einen Blick auf das idealisierte Phasen-Diagramm im Datenblatt und kommen als Allererste auf die glorreiche Idee, dass man ja auf A einen Flankeninterrupt legen kann, und auf B dann direkt auslesen kann ob Hoch- oder Runtergezählt wird.
Dieser bahnbrechende und geniale Durchbruch wird dann auf Tiktok, Youtube und µC.net verbreitet, und von dort leider auch zum Trainieren von KI-Modellen verwendet.
Den einzelnen Kindergarten-Coder wird man nicht bekehren können, der hält sich selber für den Einstein der Drehgeber-Auswertung.
Aber man kann ein wenig Kontra im Thread hinterlassen, damit der Müll zumindest nicht unwidersprochen in den KI-Trainingsdaten landet.
Bei Contollern, deren Interruptstruktur etwas komplexer als die der
alten AVR mit ihrer einen blockierenden Interruptebene sind, kann die
vielfache, schnell aufeinanderfolgende Interruptgenerierung in beiden
Fällen zudem zu eigenartigen Stack- und Semaphorenproblemen führen.
Da ich kein Freund davon bin, mich diesem Verhalten 'auszuliefern', habe ich kein Problem damit, die Bandbreite vor dem Eingang zu begrenzen. Ferner bietet es sich an, die vorgefundenen Eingangspegel dem RC-Glied am Eingang separat aufzuprägen, wodurch nachfolgende Pegeländerungen wieder die volle Einschwingzeit benötigen.
Natürlich doch, die Vielzahl die bei prellen entsteht, davon einige so schnell hintereinander dass sie verloren gehen werden weil der vorherige noch nicht abgearbeitet ist. Aber das wirst du nie verstehen, lernrenitent wie du bist. Stattdessen kommt dann externe Entprellung über extra Bauteile.
All die Nachteile, die ein Pin-Change-INT so mit sich bringt:
HW mäßige Aufbereitung der Signale nötig. Braucht Platz und kostet Geld.
Daher die Verwendung teuren Gebern, die nur auf einem Kanal klingeln können oder welche die 4 Schritte pro Rastung ausgeben, nötig. Was auch nur eine kläglicher HW Ersatz zur SW Entprellung darstellt (Nur wer bis 4 Zählt hat recht).
Die Voraussetzung eines Schmitt-Trigger am o. vor dem Eingang. Zusätzliche Widerstände u. Kondensatoren.
Weitere Maßnahmen in SW. Ein vollkommener Mumpitz, der letztendlich nichts anderes darstellt wie simples Pollen (Wird aber laut Aussage, ja eh nicht benötigt).
Deine Vorteile von PinChange waren noch mal?
(Kommt nun wieder was mit "Strom sparen"?)
Mir wird aber nun immer klarer, warum es so gut wie keine Professionell entwickelten Geräte, mit gut und lang funktionierenden Drehgebern gibt.
...
Das muss noch eine Tradition aus Zeiten sein, wo Controller noch Teuer und langsam waren!?
Bewundernswert, wirklich bewundernswert ist die Hartnäckigkeit und extreme Beratungsresistenz, die hier im Thread zum Vorschein kommt. Das nimmt ernsthaft weltanschauliche Züge an.
Und dann werden noch zusätzliche Klimmzüge mit Zusatzbeschaltung gemacht, nur um das eigene Glaubensmodell nicht in Frage stellen zu müssen.
Beeindruckend! Weiter so! Elektronik mit Glauben statt Wissen, das brauchen wir!
Leider habe ich keine Exemplare davon vorrätig, sonst würde ich sie
gerne mal auf Herz und Nieren testen ;-)
Diese ICs scheinen im Wesentlichen flankengetriggert zu arbeiten, was
sich darin zeigt, dass sie (anders als bspw. die HP-Typen) keinen
Takteingang haben.
Zwei Indizien sprechen dafür, dass deswegen auch sie Probleme mit
Kontaktprellen haben:
Zitat aus dem Datenblatt:
"The LS7183N and LS7184N are CMOS quadrature clock converters.
Quadrature clocks derived from optical or magnetic encoders, […]"
Von mechanischen Encodern ist hier (bewusst?) nicht die Rede.
Erst am Ende des Datenblatts, nämlich im Schaltungsvorschlag in
Figure 7, kommt ein mechanischer Encoder ins Spiel (RE11CT), und hier
sind (aus gutem Grund?) RC-Glieder vor die Eingänge A und B
geschaltet.
Ich bin zwar immer noch der Meinung, daß Peters Lösung für die Praxis
"die" perfekte Lösung darstellt.
Die wirklich perfekte Lösung ist die Verwendung von Mikrocontrollern
mit Encoder-Auswertung in Hardware. Da dies mittlerweile selbst mit
Billigsttypen wie dem CH32V003 (<20ct) möglich ist, sind nicht einmal
mehr die Kosten ein Argument für eine Softwarelösung.
Ich hoffe, dass sich diese Erkenntnis trotz dem flankenunabhängigen
Abtastverfahren zukünftig auch bei der Flankenfraktion in den
Entwicklungsabteilungen durchsetzen wird, so dass Geräte mit
unzuverlässig arbeitenden Eingaberädern (über die auch ich mich immer
wieder ärgere) allmählich vom Markt verschwinden werden.
so dass Geräte mit
unzuverlässig arbeitenden Eingaberädern (über die auch ich mich immer
wieder ärgere) allmählich vom Markt verschwinden werden.
Da möchte ich mal meine Mikrowelle "lobend" erwähnen. Sie hat sich, über die Jahre, zu dem nervigsten Gerät in meinem Umfeld entwickelt.
Wenn das in dem Maße so weiter geht ist sie in in ein paar Monaten unbedienbar.
Kontaktspülungen helfen etwas/kurzfristig, sind aber arg lästig.
Die wirklich perfekte Lösung ist die Verwendung von Mikrocontrollern
mit Encoder-Auswertung in Hardware.
Vor Urzeiten hatte ich Hitachi H8/3003 und zuletzt H8S/2392 verwendet, die wohl gleiche bzw. ähnliche Quadraturdekoder verwenden. Auch mit neuen mechanischen Drehgebern gibt es Zählfehler.
Es hat mich gewundert, aber so sieht die Praxis aus.
Vielleicht probiert mal jemand einen STM32..., was ich mangels Bedarf nicht mehr gemacht hatte, und berichtet, wie es damit aussieht.
Das Programm mit RP2040 und PIO-Dekoder liefert auch Zählfehler (Abtastrate ca. 10 MHz) die verschwinden, wenn die Abtastrate reduziert wird.
Gib Dir einen Ruck und schalte einen winzig kleinen TP vor die Eingänge. Vielleicht mit Bauteilen 0201 und auf der Rückseite der Platine - das sieht dann auch keiner und ich petze nicht ;-)
Vor Urzeiten hatte ich Hitachi H8/3003 und zuletzt H8S/2392 verwendet,
die wohl gleiche bzw. ähnliche Quadraturdekoder verwenden. Auch mit
neuen mechanischen Drehgebern gibt es Zählfehler.
Um der Sache auf den Grund zu gehen und zu wissen, ob die Ursache im µC,
im Encoder oder in den dazwischenliegenden Signalleitungen lag und wie
du den ggf. vorgeschalteten Tiefpass dimensionieren musst, hast du
sicher die Encoder-Signale mit dem Oszi aufgenommen. Ich gehe mal davon
aus, dass du keine Screenshots mehr davon hast, aber vielleicht kannst
du die Signale noch aus dem Kopf heraus skizzieren?
Gab es (auf Grund von Kontaktproblemen) den Fall, dass Pegelwechsel auf
beiden Signalen gleichzeitig auftraten? Das würde das Fehlverhalten
erklären. Tiefpässe können das Problem dann zwar mindern, aber nicht
vollständig beseitigen. Bei einem relativ neuen Encoder sollte der Fall
aber nicht auftreten, da jeder Kontakt üblicherweise (wie auch bei einem
Schleifring) aus mehreren redundanten Kontaktzungen besteht, sodass
zwischen zwei Übergängen (nach Beendigung der Prellphase) der Kontakt
entweder zuverlässig offen oder zuverlässig geschlossen ist.
Gib Dir einen Ruck und schalte einen winzig kleinen TP vor die Eingänge.
Könnte ich machen, aber ich könnte die positive Wirkung nicht erkennen,
weil ich bisher das Problem noch nie hatte und es zu Testzwecken auch
nicht ohne weiteres nachstellen kann. Falls es doch irgendwann einmal
auftreten sollte, würden dem Einsatz von Tiefpässen erst zwei andere
Schritte vorangehen:
Finden der Ursache (s.o.)
Beheben der Ursache
Erst wenn beides fehlschlägt und ich mit meinem Latein wirklich am Ende
bin, kommt
Bekämpfen der Symptome (bspw. durch Hinzufügen von Tiefpässen)
Was hier in diesem Thread während dieser Erörterungen noch nicht wirklich berücksichtigt worden ist, ist die Gesamtintegration von uC Peripherie und Anwendung spezifische Betrachtungen. Das Folgende erhebt den Anspruch, daß sporadische Unregelmässigkeiten im praktischen Gebrauch des Drehgebers als Eingabe Element in Menu gestützten Eingabeszenarien vernachlässigbar sind und Anomalien in der Regel unbemerkt bleiben. Dies stützt sich, was mich betrifft, auf langjährige Erfahrungen. Die Analysis in nur statisch linearer Progression führt zum Übersehen des dynamischem Verhaltens als Ganzes einer Real World Anwendung.
Abgesehen davon sind mechanische Drehgeber nur als manuelle Eingabe Elemente vorgesehen und nicht zur absoluten fehlerfreien Schrittverfolgung wo optische oder magnetische Drehgeber notwendig sind. Bei mechanischen Drehgebern nimmt man seltene Eingabefehler schon von vornherein in Kauf.
In praktischen Anwendungen wo Displayanzeige und Drehgeber vorkommen, wird auch das Programskelett nicht unbeachtet bleiben müssen. In meinen Anwendungen habe ich immer eine Zeitbasis 1ms Timer ISR am Laufen die die Arbeitsablaufdynamik der Anwendung bestimmt. Diese ISR ist auch für das Pollen der Drehgeber Signale verantwortlich. Die Zeitbasis bestimmt wie oft HW bedient werden muß und viel Logik wird in Zustandsmaschinen stetig anhand Logik abgearbeitet. Da die ISR ohnehin läuft, fallen die paar us die der Poll Algorithm benötigt überhaupt nicht ins Gewicht und sind ein Bonus.
Da das händische Drehen im Vergleich zum 1ms Pollen im Vergleich zur regelmässigen ISR Timing sehr unregelmässig und gezogen vorkommt, gibt es in der Zeitskala viele Poll Zustände wo sich die Datenlogik des Encoders nicht ändert. Sollte nun hin und wieder Prellen vorkommen stört das die Auswertelogik nur sporadisch. Da aber die Auswertelogik von Peter nur gültige Datenzustandsprogressionen berücksichtigt, gehen die sporadischen "Logikfehler" einfach als Einzel Event "Noise" unter und ergeben eine Art zeitliche Redundanz. Da typische LCD Updates nicht im ms Takt vorkommen, hat die ISR Poll Logik im Gesamtablauf der Anwendung aus gesehen genug Zeit und Möglichkeit sporadische Einzelfehler zu unterdrücken und der Bediener merkt in der Regel nichts davon, nicht zuletzt, weil LCD und Daten Updates relativ zur Timer ISR eine gänzlich andere Zeitskala haben.
Wenn man jetzt am Drehgeber dreht, folgen die angezeigten Werte schön ruhig der Drehaktivität. Da der Bediener in der Regel einen bestimmten Wert erhalten möchte dreht er eben bis er ihn am Display sieht. Ein verlorener oder extra Schritt, stört da in der Praxis nicht unbedingt auffällig und wird meist nicht einmal bemerkt.
Jedenfalls sind das meine (positiven) praktischen Erfahrungen. Da ich nur Peter Ds Algorithm verwende, funktioniert das in der Praxis in anscheinender Perfektion. In keinen meiner Projekte fielen Prellungen fehlerhafter Drehgeber Performanz jemals praktisch negativ auf. In der Praxis ist sein Ansatz ein sehr guter Kompromiss zwischen Performanz und uC Belastung und Einfachheit. Am Ende zählt die praktische Eignung einer Anwendung. Aber vielleicht sind meine guten Erfahrungen einfach nur auf die Tatsache gestützt, daß ich meist nur Markenfabrikate, wie z.B Grayhill verwende und von Firmen wie Digikey bezogen habe. Mit Produkten von Ali habe ich keine Erfahrungen. Wer weiß...
Es gibt viele Möglichkeiten ein Problem zu lösen. Aber meist ist es ein Tradeoff zwischen vielen Design Betrachtungen. Ich habe aufgehört über den Zaun zu gucken und wähle Ansätze die erwiesenermassen einen guten Track Record haben.
Bekämpfen der Symptome (bspw. durch Hinzufügen von Tiefpässen)
Ich würde hier anfangen, nachdem ich mal einen Kanal eines wenig benutzten Drehgebers mit einem Pullup-Widerstand versehen habe und mit ein bisschen Drehen beispielsweise angefügtes Bild erhalte.
Ich würde hier anfangen, nachdem ich mal einen Kanal eines wenig
benutzten Drehgebers mit einem Pullup-Widerstand versehen habe und mit
ein bisschen Drehen beispielsweise angefügtes Bild erhalte.
Auf dem Screenshot ist ein Zeitraum von 20 µs zu sehen. Wann kommt die
Flanke des zweiten Kanals? Wie sieht das Signal des ersten Kanals bis
dahin aus?
Mach doch mal einen Screenshot, auf dem man beide Kanäle sieht.
Es ist hilfreich die nicht-Gold Kontakte zwecks Selbstreinigung mit zwischen 2-5mA zu bestromen. Speziell wenn die Kontakte nicht vergoldet sind führt Kontaktstrom weit unter 1mA langfristig meist zu Verschlechterungen und Tendenz zum übermässigen Prellens. Die internen uC Pullups sind da nicht wirklich ausreichend. Behutsame Bemessung von RC TP ist auch nützlich, um Mikro Prell-Transitionen etwas abzuschwächen. Optimales Design kann holistischen Charakter annehmen.
Bei 3-5V rate ich Werte zwischen 1.5 bis 3.3K zu wählen.
Obwohl nicht explizit für 3-5V angegeben, werden dort 1.5mA als Minimalwert angegeben. Andrerseits spricht gegen meinen Argumentation, daß Grayhill die Kontaktflächen vergoldet. Aber kann man das bei billigen Fernost Produkten auch annehmen? Da ist etwas mehr Kontaktstrom eher günstig.
Es ist auf alle Fälle wichtig die jeweiligen Datenblätter zu konsultieren und Markenfabrikate und zuverlässige Beziehungsquellen zu bevorzugen und danach vorzugehen. Bei unbekannter Ware kann es unliebsame Überraschungen geben. Ich verwende immer Markenfabrikate von zuverlässigen Quellen bezogen und die Praxisergebnisse bei mir sprechen für sich selbst. Potenziell grottige Drehgeber sollte man nach Möglichkeit vermeiden.
Das Folgende erhebt
den Anspruch, daß sporadische Unregelmässigkeiten im praktischen
Gebrauch des Drehgebers als Eingabe Element in Menu gestützten
Eingabeszenarien vernachlässigbar sind und Anomalien in der Regel
unbemerkt bleiben.
Benutzergeführte Anwendungen sind meistens unkritisch. Selbst Prellen und damit "hängen" (durch zu viele Interrupts) ist nur unschön.
Es gibt aber auch Anwendungen als mechanischer Drehgeber, wo Zuverlässigkeit wichtig ist (also im Bereich << 1 Fehler auf 10^6). Da sind Bastelansätze (womöglich ohne Fehlererkennung) und austarierte R-C-Glieder ein beliebter Quell von Erdstrahlen (als Synonym für Fehler, die "keine systembedingte" Ursache haben).
Nach den Feiertagen werde ich mir den Thread in Ruhe durchlesen. Ich
vermute zwar, das ich mit meinem Lösungsansatz über die Runden komme,
aber Code zu vereinfachen ist immer schön. Und ein paar feine Gedanken
hab ich beim Überfliegen schon gesehen.
Benutzergeführte Anwendungen sind meistens unkritisch. Selbst Prellen
und damit "hängen" (durch zu viele Interrupts) ist nur unschön.
Also ich finde es schon etwas störend, wenn Drehgeber wie Zufallsgeneratoren arbeiten.
Das mag manch anderer offensichtlich anders empfinden aber ich spiele dann doch lieber Tetris.
Angespornt durch diese Fadenkette, reparierte ich heute nach vielen Jahren den mechanischen Drehgeber des HP33120A. Das Abnehmen der Frontplatte und der Leiterplatte war auch zum Fluchen anspornend. Naja, nachdem ich mir den Drehgeber ansah, stand fest, ich werde versuchen hineinzusehen, da man den Achsenteil nach vorsichtigen Aufbiegen der vier Befestigungs-Laschen, ohne ihn auszulöten müssen, abnehmen kann.
Zuerst mit Alkohol gesäubert und danach mit einer prophylaktischen Dosis Cramolin versehen, spielt er jetzt wieder wie neu und wird sich das hoffentlich hinter die Ohren schreiben. Bin gespannt wie lange die Kur anhalten wird. Über zwanzig Jahre erduldete ich aus Faulheit diese Leidensgeschichte. Also macht es nicht so wie ich - Rangehen, öffnen, repariert!
Man könnte in der fehlerkorrigierenden Software sogar berücksichtigen, dass ein Wechsel der Drehrichtung nicht beliebig schnell möglich ist. So könnte man z.B. 360 Grad pro Sekunde zulassen, aber Richtungswechsel erst nach 50 ms Stllstand. Wenn ein schnellerer Richtungswechsel erkannt wird, wird er korrigiert. Finden jedoch viele Impulse hintereinander in die "andere" Richtung statt, sind sie doch plausibel und werden nicht korrigiert.
Mach doch mal einen Screenshot, auf dem man beide Kanäle sieht.
In der gezeigten Kurve kann Flankenwechsel < 1 µs mit kritischen Amplituden sehen, die wohl einen Hardwaredekoder (black box) außer Tritt bringen können.
Um eine volle Periode des Gebers zu erfassen, bräuchte man einen (motorischen) Antrieb mit gleichbleibender Drehzahl. Zeichne ich 10 s auf, wird die Auflösung vermutlich zu schlecht.
Was ich beim Drehen sehe: bei langamen Drehen kann das gezeigte 'Bratzeln' des Signal auch 1 ms dauern; bei schnellem Drehen sind die Flankenabstände >= 5 ms.
Insgesamt ein Signal, was problemlos auszuwerten ist, egal welches Verfahren man anwendet. Wenn es - wie vom TO in der Überschrift vorgegeben - ohne Timer sein soll, dann eben ohne Timer.
an könnte in der fehlerkorrigierenden Software sogar berücksichtigen,
dass ein Wechsel der Drehrichtung nicht beliebig schnell möglich ist.
Las dir den momentanen Zustand, je nach Abtastrate(!), einige male bestätigen und du erschlägst auch dieses konstruierte Problem, einfach mal so neben bei.
"Fehler korrigieren" würde ich das aber nicht nennen. Bei Fehler gehts zurück auf Anfang.
Entprellen ist simpel, nur die Leute denken zu kompliziert!
Es ist nichts anderes als alle fünfe grade sein lasen und bis (zB) drei zählen.
Ein altes .ino-Programm für den 328 hatte ich noch gefunden und damit die Signale am Drehgeber direkt (blau) und am Port-Pin (gelb) aufgezeichnet. Dabei habe ich nach möglichst schlechten Schaltvörgängen für das Öffen und Schliessen des Kontaktes eines Kanals gesucht. Die RC Zeitkonstante beträgt 1 ms und alles ganz ohne Verwendung eines Timers.
Wer mit solchen sauberen Eingangssignalen nicht umgehen kann, soll meinetwegen weiter jammern.
Das ist der Zeitpunkt, wo der Schmitttrigger am Eingang einen PCINT auslöst und in der ISR der Eingangskondensator auf vollen '0' oder '1'-Pegel gebracht wird. Das vergößert die Eingangshysterese und sorgt dafür, daß für einen folgenden Pegelwechsel wieder >= 0,7 ms benötigt werden, um einen neuen PCINT auszulösen.
Selbst bei hoher ISR-Auslastung durch andere Quellen wird der µC nicht 'überrannt'.
Mach doch mal einen Screenshot, auf dem man beide Kanäle sieht.
In der gezeigten Kurve kann Flankenwechsel < 1 µs mit kritischen
Amplituden sehen, die wohl einen Hardwaredekoder (black box) außer Tritt
bringen können.
Wenn währenddessen der zweite Kanal einen konstanten Pegel (high oder
low) liefert, sollte dies kein Problem sein.
Um eine volle Periode des Gebers zu erfassen, bräuchte man einen
(motorischen) Antrieb mit gleichbleibender Drehzahl. Zeichne ich 10 s
auf, wird die Auflösung vermutlich zu schlecht.
Mich würde nur interessieren, was der zweite Kanal macht, während der
erste umschaltet. Dazu reicht es, wenn die Zeitbasis des Oszis so
eingestellt ist, dass die komplette Prellphase des ersten Kanals
gerade noch erfasst wird. Das Umschalten des zweiten Kanals, das
natürlich sehr viel später stattfindet, muss nicht erfasst werden.
Das ist der Zeitpunkt, wo der Schmitttrigger am Eingang einen PCINT
auslöst und in der ISR der Eingangskondensator auf vollen '0' oder
'1'-Pegel gebracht wird.
D.h. du schaltest den Interrupt-Pin in der ISR auf Ausgang, so dass
dieser über den Kondensator kurzzeitig kurzgeschlossen wird. Ok, das
kann man so machen, aber so ganz die feine Englische ist das nicht ;-)
D.h. du schaltest den Interrupt-Pin in der ISR auf Ausgang, so dass
dieser über den Kondensator kurzzeitig kurzgeschlossen wird. Ok, das
kann man so machen, aber so ganz die feine Englische ist das nicht ;-)
Erst darf man keinen Kondensator verwenden und dann darf man einen Pin nicht zwischen Eingang und Ausgang umschalten?
Den Witz mußt Du mir erklären.
Man darf schon. Der Fehler liegt ja nicht im Kondensator (bzw.dem
RC-Glied), sondern im Festhalten an einem ungeeigneten Lösungsansatz
(der Encoderauswertung mittels Flankeninterrupts), der diesen
Kondensator überhaupt erst erforderlich macht.
und dann darf man einen Pin nicht zwischen Eingang und Ausgang
umschalten?
Auch das darf man. Man /sollte/ aber mit einem Ausgang nicht einen halb
geladenen Kondensator voll- oder entladen, denn das verstößt gegen den
im Datenblatt unter "Absolute Maximum Ratings" angegebenen Maximalstrom
per I/O-Pin von 40 mA. Tatsächlich fließen 70-80 mA. Das dieser Strom
nur kurzzeitig fließt, wird der AVR zwar nicht kaputtgehen, aber unschön
ist die Sache dennoch. So wird im Datenblatt nirgends garantiert, dass
sich der kurzzeitige Stromstoß nicht störend auf andere Komponenten des
µC auswirkt.
Interessant, zumal ich meine Schaltung garnicht gezeigt habe.
Und das alles ohne Timer funktioniert, könnte zwar möglich sein, scheint aber doch ernorm zu stören :-(
Interessant, zumal ich meine Schaltung garnicht gezeigt habe.
Dafür, dass du deine Schaltung nicht gezeigt hast, kann ich wirklich
nichts ;-)
Vielleicht hast du ja noch einen Widerstand hinzugefügt, der den
Lade-/Entladestrom des Kondensators begrenzt. Dann wären wir inzwischen
bei mindestens 2·4=8 externen Bauteilen, die mit dem Pollingverfahren
(egal, ob mit oder ohne Timer) allesamt wegfallen können.
Erst darf man keinen Kondensator verwenden und dann darf man einen Pin
nicht zwischen Eingang und Ausgang umschalten?
Den Witz mußt Du mir erklären.
So langsam wird es absurd. Pollen geht mit etwa 5 Zeilen Code und erfordert einfache Eingänge ohne jede HW-Aufbereitung.
Du suggerierst, dass es per Interrupt einfacher geht und präsentierst uns dann (ohne auf deren Nachteile überhaupt einzugehen) ein ganzes Pfund Salami.