"Rotary Decoder" ist vermutlich als Suchbegriff ungeeignet; jemand, der nach der Funktionalität sucht, sucht wohl am ehesten nach Timer + Rotary Encoder support.
Gruß, Johannes
"Rotary Decoder" ist vermutlich als Suchbegriff ungeeignet; jemand, der nach der Funktionalität sucht, sucht wohl am ehesten nach Timer + Rotary Encoder support.
Gruß, Johannes
Am 21.09.2019 um 20:57 schrieb Sieghard Schicktanz:
Dann muß man eben von Hand entprellen, da sind Interrupts nur hinderlich.
Wie lange prellen denn die Kontakte?
DoDi
snipped-for-privacy@aol.com (Hans-Peter Diettrich) am 22.09.19 um 04:08:
Ich imitiere das so, wie man das von einfachen SPS kennt: Zyklisch abfragen und letzten und aktuellen Zustand vergleichen. Bei händisch betätigten Drehgebern kein Problem. Bei "schnellen" Gebern ist das latürnich problematisch, aber die sind ja eher nicht mechanisch und prellen nicht.
Wobei ich vor Jahren mal eine Maus hatte, bei der das Mausrad tatsächlich einen mechnischen Geber hatte. Mit zunehmendem Alter und Verschleiß verhielt die sich schon sehr knuffig. Da hat der Mausprogrammierer wohl auch beim Entprellen geschlampt ;-)
Rainer
Hi Andreas,
Nicht wirklich. ein 1,5V Block an eine Netzspannungsglühbirne wird trotz allem nix, selbst wenn es eine amerikanische Glühbirne ist.
Marte
Auf allen Echtzeitsystemen, die in einem Zugriff mehr als nur ein Byte (oder was auch immer der native Datentyp ist) wegschreiben müssen. Aber es geht doch auch gar nicht darum, jetzt einen Fall zu konstruieren, der trivial mit diesem oder jenem Ansatz lösbar ist. Es geht darum, zu veranschaulichen, daß Multithreading und sonstige Nebenläufigkeiten prinzipiell zu den schwierigeren Programmieraufgaben gehören. Denn sonst wäre das nicht in einem von mir einigermaßen willkürlich gewählten Beispiel danebengegangen und seit Jahren (wenn nicht Jahrzehnten) ohne Fix geblieben.
Wer unter euch ohne Sünde ist, der werfe den ersten Stein!
Volker
Am 23.09.19 um 13:52 schrieb Volker Bartheld:
Comic in dem Berliner Stadtmagazin Zitty, so vor 30 Jahren:
Rüdiger (Knollennase, doof): Kieselchen nehm - vorsichtig werf -
Publikum: Oh, die arme Sau! Nicht mal eine klitzekleine Sünde!..
Würde ich sogar noch einen Tick allgemeiner sehen: Auf Systemen, auf denen Multiprozessor-Skalierbarkeit wichtig ist, gilt das ja nämlich auch. Linux hat richtig hart gearbeitet, das BKL (Big Kernel Lock) loszuwerden:
Gruß, JOhannes
Am 23.09.19 um 13:52 schrieb Volker Bartheld:
Wer zuerst trifft, lebt länger.
... und anscheinend über keine Interrupt-Abschaltung verfügen? Die halte ich aber für essentiell für so kleine Systeme wie hier genannt, die einfach nur Encoder abfragen sollen. Wenn jemand für diese Aufgabe ein OS und weiteren Pipapo benötigt, dann kann er das gerne in einem neuen Thread diskutieren, unter "Mit Kanonen auf Spatzen schießen".
Unbestritten, aber solche Systeme betrachte ich nicht als Mikrocontroller. Wenn ein Prozessor Multithreading etc. erlaubt, und gleichzeitig Anspruch auf Echtzeitfähigkeit erhebt, dann hat der gefälligst auch Befehle für atomare Zugriffe zu implementieren, sonst ist das alles nur Marketinggeschwätz.
Ich weiß nicht ob es Intel war, die ein LOCK Prefix eingeführt haben. Für die Tasksynchronisation etc. gibt es noch CMPXCHG und ähnlich komfortable Befehle für Semaphore etc. Und wenn es die schon auf ordinären Controllern gibt, die keinen Anspruch auf Echtzeitfähigkeit erhebenn dann sieht man, wie weit dieses Thema vom Topic und der hiesigen NG weg ist.
DoDi
s
der
darf dann
digkeit einlesen kannst. Das geht so: Im schnellen Timerinterrupt werden di e A und B Signale eingelesen und in ein Byte geschoben. Dieses Byte enth? ?lt also nicht nur die aktuellen Signale, sondern auch die A und B Signal e zu den vergangenen drei Zeitpunkten. Dieses Byte wird nun als Eingangssig
hat. In die Erstellung dieser Tabelle musst du ein Bisschen Gehirnschmalz reinstecken und kannst dabei die Tatsache nutzen, dass sich die Drehgeschwi
en mit dieser Methode kompensiert werden.
Michael
Du schaltest also den Interrupt ab. Und serialisierst eine etwas größere Datenstruktur. Währenddessen kann Dein Echtzeit(!)system aber nicht mehr zeitgerecht reagieren. Also zerhackst Du die Datenstruktur und führst einen Mutex, eine Critical Section oder sonst einen Synchronisierungsansatz ein. Das blockt dann aber die Threads, die möglicherweise auf den Ablageort der Datenstruktur zugreifen müssen. Ergo erfindest Du Schattenkopien, ein Dirty-Bit, grübelst über Write-Through und Write-Back, usw. Ich will damit sagen: Multithreading ist schwierig.
Aber vermutlich überkopfe ich das auch nur und es gibt eine ganz einfache Lösung, wie man die Echtzeitanforderung bei abgeschalteten Interrupts sonst abbildet. Ich bin ja ausbildungsmäßig Physiker und kein IT-Profi.
Das Usenet ist aber leider kein Wunschkonzert. Für den Task "Quadrature-Encoder abfragen" würde ich - verzeih - {Quadrature, Encoder, Arduino} in der Suchmaschine meines geringsten Mißtrauens eingeben und mir anschauen, wie das - vermutlich - schon 1001x gelöst wurde. Als da wären:
Je nun. Ich baute mal einen Klon des Photoduino:
Irgendwann ist mir aufgefallen, daß in einem anderen Anwendungsfall - nämlich der Hochgeschwindigkeitsfotografie - ein gewisser Jitter vorhanden ist, der das Timing zwischen Triggerevent und Auslösung des Blitzes versaut. Der ADC vielleicht? Irgendwas in der Auslöselogik? Die Verschlußsteuerung der Kamera selbst? Fragen über Fragen. Schließlich war es von allem ein bißchen und natürlich auch der Hintergrundbeleuchtungsinterrupt, wo eigentlich nur andere Interrupte deaktiviert und ein simples Bit an den PWM-Ausgang des Arduino geschrieben wurde.
Blöd gelaufen.
Volker
Nicht verkopft, sondern den Nagel voll und ganz auf den Kopf getroffen.
Der unschlagbare Vorteil vom Sperren von Interrupts ist, dass es die aller, allereinfachste Synchronisationsprimitive ist, die man verwenden kann. Funktioniert absolut sicher. Die Nachteile sind aber eben genauso gravierend und erfordern dann (wie in deinen Beispielen geschildert) eventuell entsprechende Gegenmaßnahmen, die dann die Komplexität extrem aufblasen können.
Viele Grüße, Johannes
Kommt auf die Anforderungen an. "Echtzeit" heißt ja nur, daß man eine garantierte Antwortzeit hat, aber nicht, welche das ist. Wenn der kurzzeitig abgeschaltete Interrupt innerhalb einer klar definierten (und nicht zu großen) Zeit wieder da ist, und hardwaretechnisch gewährleistet ist, daß keine Interrupts verloren gehen, kann das schon mit geringem Aufwand zielführend sein.
Mit verschiedenen und überlappenden Interrupts wird es dann wieder schwierig. Allerdings in jedem Fall.
Hanno
Ja.
Nein. Interrupts ändern immer nur kleine Dateneinheiten, alles andere wäre Murks. Deine Einwände deuten offensichtlich in diese Richtung...
DoDi
Die Welt braucht mehr CPUs. Jede nur für einen überschaubaren Zweck.
Im BeagleBoneBlack hat das für mich sehr schön funktioniert. Ein GHz-ARM für Linux und 2 PRUs für die Drecksarbeit. Die PRUs sind andere RISCs ohne Pipeline, die man stallen könnte. Dafür nur 200 MHz, aber man kann im 5 ns-Raster Flanken erzeugen. Alles geht taktgenau. Jede PRU hat 32-Bit-Register mit denen man fast direttissima auf einige Pins und Devices zugreifen kann. Interrupts gibt's nicht wirklich für die PRUs, aber dual port buffers zum ARM.
Mit einem popeligen Coolrunner2-IF kann ich 3 LTC2500-32 ADCs mit jeweils 100 MHz-SPI auslesen, ohne dass was verloren geht.
Passiert auch den Besten. Tektronix hatte mal ein ultraschnelles sampling scope, wo der Aperturjitter im Takte einer nicht sehr wichtigen Warn-LED um ein paar ps herumgetanzt ist.
Gruß, Gerhard
Michael Koch snipped-for-privacy@t-online.de:
Jo danke, genau so mache ich es schon. :-)
M.
--
snipped-for-privacy@bartheld.net (Volker Bartheld) am 24.09.19 um 10:43:
Echtzeit bedeutet nicht "jederzeit" oder "unfaßbar schnell" oder "zwischen jedem einzelnen Professortakt reaktionsfähig", sondern nur "stets mit vorhersagbarer maximaler Reaktionszeit".
Wenn eine Uralt-SPS einen eine ms langen oder gar noch langsameren Zyklus schafft, diesen aber /garantiert/, dann ist das halt "Echtzeit" mit einer ms Auflösung.
Wer mit einem 8-bit-AVR nun unbedingt 48-bittig rechnen will, der kann halt keine "Echtzeit" zwischen jedem Registerzugriff bei einer Plutimikation garantieren, sondern eben nur alle 384 (Hausnummer!) Prozessortakte. Wenn der Zwerg halt fertig ist mit der Bitumherschieberei. Gerät der Kleine ins Stottern, muß man was dickeres nehmen und/oder schlauer programmieren.
Aber dieses Thema hatten wir hier schon dermaßen oft, daß mich wundert, daß es da immer noch Verständnisprobleme gibt.
Rainer
Am 24.09.2019 um 19:01 schrieb Rainer Knaepper:
Letzteres gefällt mir noch nicht so richtig, denn man kann jedes System mit zu vielen häufigen Interrupts überlasten. Tatsächlich kann nur vorgegeben werden, wie lange die Bearbeitung eines Interrupts maximal dauern darf. Für länger dauernde Operationen muß die Priorität des Handlers heruntergesetzt werden, oder noch besser die lange Verarbeitung in eine normale Task ausgelagert werden, damit der Handler keine Probleme mit Reentrancy bekommt.
Immer wieder gern ;-)
DoDi
snipped-for-privacy@aol.com (Hans-Peter Diettrich) am 24.09.19:
Genau in so eine Falle bin ich ja mal in einem früheren Leben hineingerannt. Das ganze System basierte auf einem Taktgeber aus einer RTC und interruptete halt mit 64 Hz. Die komplette Ablaufsteuerung steckte in der ISR.
Funktionierte auch gut, aber dann kam $Chefänderungswunsch1, $Kundenerweiterungswunsch2 und "können wir nicht jene Funktion noch hinzupacken" sowie "$GanzAnderesGerät können wir doch auch auf der Basis steuern" - und schwupps reichten die 16ms nicht mehr zur Abarbeitung.
Was dann einen großzügigen Umbau des gesamten Konzepts erforderte :-)
Ich schaue halt aus Elektrikerperspektive auf die Thematik, nicht informationstheoretisch.
Rainer
Ein Bekannter hat dafür noch eine Lösung aus BASIC Zeiten: verwendet wird ein Ringpuffer, in dem immer nur unterschiedliche Einträge gelesen und geschrieben werden. Das geht auch mit einem Wechselpuffer, wenn der Consumer via Flag den gerade beschriebenen Puffer auf read-only schaltet, und der Producer in den anderen - jetzt write-only - Puffer schreibt.
Es muß ja nur derjenige Interrupt blockiert werden, der (s)einen Teil der Daten ändert. Das kann nicht zum Verlust von Interrupts führen, denn was könnte ein Interrupt-Handler in der Zeit erledigen, die der Hauptthread für das Kopieren von ein paar Bytes in Register braucht?
Es kann doch keinen großen Unterschied ausmachen, ob jetzt ein Interrupt von einer Kopieraktion oder einem anderen Interrupt vorübergehend blockiert wird? So viel Zeit muß in einem ausreichend schnellen Echtzeitsystem übrig sein.
DoDi
Have something to add? Share your thoughts — no account required.
Ask the community — no account required