Für Eingaben von variabelen Werten am µC eignen sich vielfach mechanische Drehgeber, die angenehme Rastpunkte bei der Eingabe haben. Bei einem großen Wertebereich kann es allerdings sehr lästig werden, viele Umdrehungen mit geringer Auflösung zu machen, ohne dabei selbst 'durchzudrehen' :-) Ein optischer Drehgeber mit bis zu 1024 Schritten/Umdrehung könnte die Lösung für dieses Problem sein, wenn nicht der deutlich höhere Preis bei Hobbyanwendungen im Wege stünde. Als Zwischenlösung mit Rastpunkten und höherer Auflösung kommt man schnell auf Schrittmotore, die als Generator zwei um 90° verschobene Ausgangssignale liefern, welche die Drehrichtung auswerten lassen. Da die Ausgangsspannung von der Drehgeschwindigkeit abhängt, sind die geringen Signalpegel bei langsamen Drehungen recht schlecht zu erfassen. Folglich sucht man sich Schrittmotore mit möglichst hoher Ausgangsspannung und Auflösung aus, um auch langsame Drehungen fein auswerten zu können. Das sind Motore mit hoher Strangspannung (typ. 12V) und hohem Innenwiderstand (>50 Ohm), die recht günstig als Restposten angeboten werden und für anspruchsvolle Antriebe eigentlich völlig ungeeignet sind. Dabei ist die Leistung ohne Bedeutung; eine praktische, kleine Bauform spielt die entscheidene Rolle bei der Auswahl. Das angehängte Schaltbild zeigt den einfachen Anschluß an einen AVR. Die Eingänge am AVR sind auf Vcc/2 vorgespannt, um schon auf kleine Amplituden reagieren zu können. Das Programm wertet alle vier Flanken der beiden Phasen aus. Die Grundfunktion dazu ist an anderer Stelle beschrieben: Beitrag "Drehgeber per Interrupt auswerten, AVR" Hier nun werden die Eingangsimpulse nicht direkt in einem Zähler gezählt, sondern die in einem Zeitfenster (hier sind es rund 80ms) neu eingetroffenen Impulse bewertet. Dabei werden kleine Werte (< CNT_SCHWELLE) ignoriert. Die Division temp_cnt /= CNT_SCHWELLE; unterdrückt das 'Rauschen'. Liegen die absoluten Zähleränderungen von 'temp_cnt' im Bereich >= 1 bis < DYN_SCHWELLE, werden sie 1:1 zum Gesamtzähler 'stepp_count' addiert. Bei Werten >= DYN_SCHWELLE werden die Werte quadriert und unter Beibehaltung des Vorzeichens addiert. Hiermit ergibt sich eine Drehdynamik, die schnelle Zähleränderungen ermöglich. Damit zu schnelle Drehungen nicht zu allzu großen Zählersprüngen führen, wird diese Dynamik auf <= DYN_LIMIT begrenzt. Die Parameter sind für den verwendeten 7,5° Schrittmotor (48 Schritte/U) brauchbar, müssen aber an die eigenen Bedürfnisse angepaßt werden. Auf der einen Seite soll eine gute Feinabstimmung möglich sein, auf der anderen Seite bei schneller Drehung eine deutliche Änderung des Zählerstandes erfolgen. Das Programm kann auch für optische Drehgeber verwendet werden, die vermutlich ein angenehmeres Drehgefühl vermitteln, da keine Mindestdrehzahl notwenig ist. Durch die 'Rauschunterdrückung' kann der Zählerstand trotz fehlender Rastpunkte nicht weglaufen.
Um die Spielerei abzurunden, hänge ich noch die .ino-Datei für einen UNO R3 an. Bei der Umstellung auf die Arduino Funktionen fällt auf, dass aus nicht ersichtlichen Gründen Timer0 schon verwendet wird, sodass hier dann Timer2 genommen werden mußte. Auch die Ausgabe des aktuellen Zählerstandes ist trotz 19,2kBd recht schleppend, als ob mit nur 300Bd gesendet würde. Mein Fazit: die Arduino Hardware ist ja ganz nett, aber sobald etwas Sinnvolles damit erledigt werden soll, ist das Arduino-spezifische Programmierumfeld leider für die Tonne :-(
M. N. schrieb: > Die Grundfunktion dazu ist an anderer Stelle > beschrieben: Beitrag "Drehgeber per Interrupt auswerten, AVR" Schlechte Ideen werden auch durch ständige Wiederholungen nicht besser.
Marek schrieb: > M. N. schrieb: >> Die Grundfunktion dazu ist an anderer Stelle >> beschrieben: Beitrag "Drehgeber per Interrupt auswerten, AVR" > > Schlechte Ideen werden auch durch ständige Wiederholungen nicht besser. Das ist das mit Abstand beste wie man einen Drehgeber auswerten kann. Flankengesteuerte Interrupts sind das A und O - die Grundlage einer jeden Encoderauswertung! Bei Tastern ist das was anderes aber für den Encoder gibt es sonst nur noch schlechtere Lösungen. Willst du Pollen ??? Nicht ernsthaft ....
Drehgeber, die von Menschen per Hand bedient werden, die kann man ganz locker durch Pollen einlesen. Alle Probleme mit Zittern um einen Rastpunkt sind damit aus der Welt. Warum sollte man das anders machen?????
132 schrieb: > Das ist das mit Abstand beste wie man einen Drehgeber auswerten kann. > Flankengesteuerte Interrupts sind das A und O - die Grundlage einer > jeden Encoderauswertung! Ah ja. Wenn dem so ist, warum wird es dann nicht in allen kommerziellen Produkten so gemacht? Schon mal darüber nachgedacht?
spontan schrieb: > Alle Probleme mit Zittern um einen > Rastpunkt sind damit aus der Welt. Das große "Zittern" um den Rastpunkt? Eine schöne Erfindung oder ein schlechter Rastpunkt: such Dir was aus. Marek schrieb: > 132 schrieb: >> Das ist das mit Abstand beste wie man einen Drehgeber auswerten kann. >> Flankengesteuerte Interrupts sind das A und O - die Grundlage einer >> jeden Encoderauswertung! > > Ah ja. Wenn dem so ist, warum wird es dann nicht in allen kommerziellen > Produkten so gemacht? Gute Frage. Aber gegen Engstirnigkeit ist es schwer zu argumentieren, wie hier immer wieder zu lesen ist. Herumzuschreien ist eben einfacher, als sich mit anderen Meinungen sachlich auseinanderzusetzen. Die Engstirnigkeit stammt aus einer Zeit, wo der einzige externe Interrupt eine /IRQ-Leitung war, die Reaktionszeiten im 10µs-Bereich bot. Zudem war dieser /IRQ vielfach so "böse", dass man ihn am besten nicht angetastet hat. Seinerzeit war man froh, einen 10ms Timer in irgendeinem IO-Baustein zu finden, um nicht noch mit Warteschleifen arbeiten zu müssen. Diese Zeiten sind lange vorbei! Bei langsamen Vorgängen oder Tasterabfragen kann man ruhig zyklisch pollen. Da gibt es sogar den Vorteil, dass gedrückte Tasten einen Repeat-Code liefern, solange sie aktiv sind. Ein Beispiel findet sich hier: Beitrag "Entprellung von Tastern" :-)
m.n. schrieb: > Diese Zeiten sind lange vorbei! Um noch ein wenig zu schwätzen: Valvo hatte Ende der 80er den 80C552 herausgebracht. Ein Edel-µC für damalige Verhältnisse. 1991 hatte ich eine Radioabstimmung entwickelt, womit man u.a. auch mit einem Drehrad die PLL-Frequenz einstellen konnte. Verwendet wurde ein opischer HP-Encoder (die Auflösung weiß ich nicht mehr), von dem die Flanken eines Kanals über einen Capture-Eingang von Timer2 per Interrupt ausgewertet wurden. Ferner wurde der Capture-Wert für die Messung der Drehgeschwindigkeit genutzt. Die Frequenzeinstellung war sehr angenehm wie bei einem alten Radio mit DrehKo. Es ist lange her, aber, wie beschrieben, war es seit Anfang der 90er mit vertretbaren Mitteln möglich, eine Encoder-Auswertung per Interrupt zu machen. Wer das damals verschlafen hat, sollte spätestens heute wach werden!
Ich denke, man sollte das Problem Interrupt/Pollen nicht so einfach über einen Einheitskamm scheren. Hat ein Programm sehr viel Zutun, vor allem Asymmetrisch, so sind Unterbrechungen das einzig sinnvolle. Hat ein Programm Zeit, und ist die Zykluszeit weit weg von der der Impulse, so kann man einfacher durch Pollen zum Ziel kommen.
Was macht deine Schaltung wenn man den Motor sehr langsam dreht? Ich habe schon einige Schaltungen aus Elektor und Internet ausprobiert, aber keine funktionierte bei sehr niedrigen Drehzahlen vernünftig. Für ein Eingabeelement mag das vielleicht hinzumehen sein, aber schön ist das trotzdem nicht. Mit freundlichen Grüßen Thorsten Ostermann
Thorsten Ostermann schrieb: > Was macht deine Schaltung wenn man den Motor sehr langsam dreht? M. N. schrieb: > Da > die Ausgangsspannung von der Drehgeschwindigkeit abhängt, sind die > geringen Signalpegel bei langsamen Drehungen recht schlecht zu erfassen. Diesen Umstand habe ich als "Rauschen" beschrieben, welches bei direkter Auswertung dazu führt, dass die Richtung sogar verkehrt herum gewertet werden kann. Zu kleine Zähleränderungen werden bei der zyklischen Auswertung durch die Division/CNT_SCHWELLE unterdrückt. Somit ist es möglich, den Motor ganz langsam zu drehen, ohne die Anzeige zu verändern. Bei schnellerer Drehung ist die Signalspannung ausreichend hoch und entsprechend auswertbar. Generell ist mit einem Schrittmotor keine genaue Positionsbestimmung möglich! Mein 7,5° Motor ist das größte Schrottteil, was ich in der Kiste finden konnte, aber er hat halt die 12V Wicklungen. Besser ist es, einen 1,8° Motor mit entsprechend hochohmigen Spulen zu verwenden, weil damit noch besser zwischen Stillstand und langsamer Drehung unterschieden werden kann. CNT_SCHWELLE kann dann bei 4 oder höher liegen. Was an einem Schrittmotor gut ist, ist die mechanische Festigkeit und die hohe Impulsrate bei schnelleren Drehungen. Damit bekommt man eine sehr dynamische Änderung der Werte. Die angehängte .log-Textdatei zeigt die Änderung von 0.00 auf 5.00; anschließend wird auf -5.00 eingestellt. Abschließend auf 10.00 und -10.00. Als Drehrad dient ein 16mm Keilriemen-Alurad, welches auf der Achse montiert ist. Die Einstellungen habe ich mit der linken Hand gemacht, ohne auf große Zielgenauigkeit zu achten. Man kann sehen, dass sowohl kleine als auch große Änderungen sehr direkt eingestellt werden können. Wie gesagt, ist die Dynamik dem vorhandenen mechanischen Aufbau anzupassen.
M. N. schrieb: > Mein Fazit: die Arduino Hardware ist ja ganz nett, aber sobald etwas > Sinnvolles damit erledigt werden soll, ist das Arduino-spezifische > Programmierumfeld leider für die Tonne :-( Hier wird mal wieder ein vorschnelles Urteil gefällt, was durch wenig Sach- kenntnis untermauert ist. Selbstverständlich kann man im Arduino Umfeld anspruchsvolle (sinnvolle) Anwendungen schreiben. Davon kann man sich anhand vieler Beispiele auf Arduino.cc und vieler anderer veröffentlichen Projecte im Internet leicht selbst überzeugen. Wenn eine Arduino Funktion nicht für die eigene Anwendung passt oder nicht ausreicht, schreibt man sich eben eine eigene Funktion in C oder C++ notfalls auch in ASM, die man als Library in die Arduino Umgebung einbindet. Hier hat man alle Freiheiten und Möglichkeiten. Ob einem die Arduino Umgebung gefällt ist letztlich Geschmackssache, mangelnde Leistungsfähigkeit kann es jedenfalls nicht sein. Zum Timer1: der wird für Arduino interne Zeitfunktionen z.B. millis() verwendet, die die ms seit dem letzten reset zählt.
wega52 schrieb: > Zum Timer1: der wird für Arduino interne Zeitfunktionen z.B. millis() > verwendet, die die ms seit dem letzten reset zählt. Wie, Timer1 wird auch verwurschtelt? Meine Probleme bezogen sich auf Timer0. Bei der ISR(TIMER0_OVF_vect) wurde der Fehler gemeldet, dass der Vektor 16 bereits belegt wäre. Timer0_OVF wird allerdings über Vektor 17 gehandhabt. Das passt doch nicht zusammen. Ein Anfänger, dem soetwas passiert, ist damit doch völlig überfordert. Bevor ich "Sachkenntnis" von dieser Gurkerei erwerbe, habe ich das Programm längst direkt in C gelöst, wobei der Speicherverbrauch deutlich geringer ausfällt und genau das gemacht wird, was ich brauche. Eigentlich war ich dem Arduino gegenüber eher wohlwollend eingestellt; anders hätte ich die IDE davon garnicht erst angefaßt.
Auch wenn es sehr spät ist...... (ich kann das halbgare Arduino gebashe nicht leiden) 1. Arduino nutzt Timer0 für seine Zeitbasis. 2. Wenn man das nicht will, lässt man setup() und loop() weg und legt eine main() an, ganz klassisch. Das ist beides hinreichend dokumentiert. Wer nicht lesen kann, oder will, hat halt verloren. PS: Den Drehwertgeber finde ich übrigens klasse! Eine gute Idee. Robust, preiswert und langlebig.
Ulrich F. schrieb: > Auch wenn es sehr spät ist...... > (ich kann das halbgare Arduino gebashe nicht leiden) Laß mich raten, Du kommst aus dem südwestdeutschen Raum ;-) Aber erkläre mir doch bitte, was "gebashe" ist. Ulrich F. schrieb: > Das ist beides hinreichend dokumentiert. Wer nicht lesen kann, oder > will, hat halt verloren. Sag doch einfach, wo es steht. Dort, wo es stehen müßte, steht es zumindest nicht.
m.n. schrieb: > Dort, wo es stehen müßte, steht es > zumindest nicht. Da wo du es gerne sehen würdest..... Anderer Blickwinkel. Mehr nicht.... Arduino Jünger interessieren sich (in der Regel) nicht für Hardware Timer0. Das wird erst spannend, wenn sie mit PWM Frequenzen spielen müssen. Und genau da findest du dann auch Aussagen zu den Seiteneffekten (mit millis() usw.) und wie man sie kompensiert. Da du schon gefunden hast, dass eine ISR für den Timer gibt, hättest du evtl. auch in die Arduino Core Dateien schauen können... Es ist ja nicht gerade geheim, was die Arduinos da tun..... Auch google("arduino timer0") führt zu unendlich vielen Seiten, wo das Thema durchgekaut wird. m.n. schrieb: > Du kommst aus dem südwestdeutschen Raum ;-) Und mein Eindruck ist, du möchtest die Arduino Idee schlecht reden, ohne zu wissen was da, und warum es da genau so passiert. Betrachte mich als Bote, welcher dir berichtet: "Erst verstehen, worüber man redet. Dann ist immer noch Zeit zum Schimpfen." (so, und jetzt darfst du dem Boten Ohren und Nase abschneiden)
Ulrich F. schrieb: > Betrachte mich als Bote, welcher dir berichtet: Eine Antwort auf meine Fragen hast Du leider nicht gegeben. Dein nebulöses Blabla kannst Du Dir sparen.
Also wenn man das Thema wieder aufwärmt, dann doch bitte mit ein paar positiven Erfahrungen bzw. konstruktiver Kritik. Ich habe Gestern Mittag schnell einen Stepper an ein FPGA-Board angeschlossen (Ich weiss, total überdimensioniert, habe aber meine Anwendung im FPGA), aber im ggs zum Post#1 die 2 Eingänge per Transisitorschaltung digitalisiert, die Stepper-Spannung wird per Poti dimensioniert. Die Daten werden mit 10kHz abgetastet (d.h. für akt. uCs leicht mit Timer-IRQ zu implementieren). Eine einfache FSM macht dann aus den Quadratursignalen einen einfachen Zähler, mit dem ich meine Anwendung steuere. Dazu kommt noch eine simple Fehleranalyse, die gültige und ungültige Übergänge zählt. Die Anzahl Fehler bewegt sich im 1/10000-1/1000000er Bereich. Verwendet wird ein Sankyo MSAF200A91 mit 1.9er Schritt und ein alter 4x4x4cm-Stepper mit ebenfalls 1.9er Schritt (keine Bezeichnung vorhanden). Die Steuerung der Anwendung ist ein absoluter Traum extrem fein, die Rasterung ist bedingt durch die Magnete wesentlich angenehmer als durch Federrasterung von z.B. Avago etc.
Grundig hatte vor Jahrzehnten eine sehr schöne Lösung für ihre Tunerabstimmung entwickelt. Der Enkoder ist eine Art großes Zahnrad aus Eisen. Ein Magnet sorgt für eine weiche Rasterung, mit etws mehr Schwung kann man flüssig weiterdrehen. Abgetastet wird mit zwei Lichtschranken. Das war haptisch perfekt.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.