ich nutze einen optischen Encoder um die Drehzahl eines Motors zu erfassen. Dabei handelt sich um folgenden Encoder:
Zum Auslesen benutze ich einen Due, der den Ecoder in einer Interrupt-Schleife bei 10khz ausliest. Das ist mehr als das doppelte der nötigen Abtastfrequenz bei der Geschwindigkeit die ich fahre. Trotzdem kommt der Encoder nicht hinterher und verliert massig an Schritten bei hohen Geschwindigkeiten.
Laut dem Datenblatt kann der Encoder aufjedenfall eine höhere Drehzahl lesen als ich sie momentan fahre. Momentan wird nur einen Kanal des Encoders ausgelesen, da ich die Encoder Lib von Paul Stoffregen nutze: Encoder/examples at master · PaulStoffregen/Encoder · GitHub
Ich gehe stark davon aus, dass sich die Performace mit allen drei Kanälen verbessern würde.
Kann mir jemand einen Tipp geben, wie man alle drei Kanäle (A, B, I: siehe Datenblatt) zu einem sinvollen Signal verarbeitet? Mit der genannten Lib ist das meines Wissens nach nicht möglich mehrere Kanäle zu kombinieren.
Ich weiß dass die/der Timer des DUE Quadrature Decoder eingebaut haben.
Die wurden speziell für solche Drehencoder geschaffen.
Damit sollte sich das A, B und Index Signal korrekt auswerten lassen.
Auch bei recht hohen Drehzahlen.
Es macht aus meiner Sicht keinen Sinn, eine Software zu bemühen, wenn es doch die Hardware alleine schon abhandeln kann.
Ob die Pins herausgeführt sind, kann ich dir leider nicht sagen, dass müsstest du selber herausfinden.
Eine Abtastrate von 10kHz kommt mir komisch vor, die Interrupts sollten nicht vom Timer sondern von den Signalen ausgelöst werden. Aber combie scheint mehr über den DUE zu wissen als ich.
Das B Signal wird benötigt für die Drehrichtung, und ggf. I für eine 0° Referenz.
ItsUnreal:
... Trotzdem kommt der Encoder nicht hinterher und verliert massig an Schritten bei hohen Geschwindigkeiten. ...
Als ich mein Langzeitgebastel mit einer elektronischen Achse ausgestattet habe, hatte ich das Problem, dass die mechanischen Toleranzen der Getriebe so groß waren (obwohl gefühlt total gut), dass mein Gefährt zu „stottern“ angefangen hat. Eine niedrigere Geschwindigkeit hat Wunder gewirkt und mein Fahrding fährt jetzt schnurgerade.
Sind hohe Geschwindigkeiten bei Deinem Gebastel denn wirklich nötig oder nur ein nice-to-have?
meine bescheidene Meinung. Zur Drehzahlerfassung benötigt man nicht zwingend einen Encoder. Aber wenn du schon einen dran hast würde es ausreichen das Signal einer Phase zu detektieren. Du machst also eine Frequenzmessung. Oder anders gesagt zählst Impulse pro Zeiteinheit. Bei 5000 U/min erhälst du aller 0,2ms ein Impuls. Das ist schon sportlich.
gregorss:
Als ich mein Langzeitgebastel mit einer elektronischen Achse ausgestattet habe, hatte ich das Problem, dass die mechanischen Toleranzen der Getriebe so groß waren (obwohl gefühlt total gut), dass mein Gefährt zu „stottern“ angefangen hat. Eine niedrigere Geschwindigkeit hat Wunder gewirkt und mein Fahrding fährt jetzt schnurgerade.
Sind hohe Geschwindigkeiten bei Deinem Gebastel denn wirklich nötig oder nur ein nice-to-have?
Hetz' nicht so
Gregor
Geschwindigkeit ist leider nicht nur ein nice-to-have sondern das entscheidende Kriterium in diesem Projekt..
Doc_Arduino:
Hallo,
meine bescheidene Meinung. Zur Drehzahlerfassung benötigt man nicht zwingend einen Encoder. Aber wenn du schon einen dran hast würde es ausreichen das Signal einer Phase zu detektieren. Du machst also eine Frequenzmessung. Oder anders gesagt zählst Impulse pro Zeiteinheit. Bei 5000 U/min erhälst du aller 0,2ms ein Impuls. Das ist schon sportlich.
Wenn ich dich richtig verstanden habe, dann habe ich doch exakt genau das gemacht. Aber das ganze funktioniert nicht zuverlässig genug bei höheren Geschwindigkeiten mit einem Kanal.
ItsUnreal:
... dann habe ich doch exakt genau das gemacht.
Hast Du wirklich? In den bisherigen Postings dieses Threads kann ich keinen Code entdecken. Vielleicht zeigst Du mal den Code, mit dem Du Probleme hast. Andernfalls ist wohl Stochern im Nebel angesagt.
DrDiettrich:
Eine Abtastrate von 10kHz kommt mir komisch vor, die Interrupts sollten nicht vom Timer sondern von den Signalen ausgelöst werden.
Man kann das schon mit einem Timer machen. Und im Interrupt die Eingänge Pollen. Hat den Vorteil dass man so auch sehr gut mehrere Encoder auslesen kann ohne die Interrupt-Last zu erhöhen
ItsUnreal:
Wenn ich dich richtig verstanden habe, dann habe ich doch exakt genau das gemacht.
da muss ich Gregor schon recht geben. Wir alle hier sehen nur das was du uns schriftlich mitteilst. Die Glaskugel hat begrenzte Fähigkeiten je nach Sonnenschein. Du hast bisher immer nur vom Encoder und Encoder Lib gesprochen. Wir wissen nicht wie du diese nutzt. Wenn man nur 200µs Zeit hat bei Maximaldrehzahl, würde ich auf fremde Libs ganz verzichten und eine schlanke ISR selbst schreiben. Man lernt auch viel dabei.
Ob man nun mit konstanter oder dynamischer Interruptlast arbeitet, darüber vermag ich mich nicht auslassen was besser ist. Bei Einzelimpulsen mag dynamisch Vorteile bringen bei mehreren würde das Pendel wohl zu statisch ausschlagen, so meine Meinung.
mit der Auswertung von 2Kanälen bekommst die obere Frequenz nicht höher sondern lediglich die Auflösung kann besser werden. Theoretisch kann man ja die Flanken der 2 bzw 4 Spuren auswerten dann hat man 2 oder 4 fache Impulszahlen.
Wenn Du die ISR Routine selbst machst reicht es doch darin einen Kanal zu zählen , wenn man dann den anderen Kanal noch dazu verundest hast Du auch noch beide Richtungen. vor und zurück. Das sind 2-4 Zeilen Code. Wenn der Encoder eine Nullspur hat kannst Du ja evenuell auch nur die auswerten falls die Auflösung dann noch reicht, aber auch da ist dann die Impulslänge eventuell zu kurz.
wieviel I/Umdr hat der Encoder denn eigentlich , ich hab dazu nichts gefunden.
Motor 5000Umdr/min= 83Umdr/s
wenn der Encoder jetzt 1000 I/ Umdr hat (gäniger Wert angenommen )sind das 83Kz die Du messen willst. Du schreibst das Du eine 10KHz Messschleife hast. Soll das heißen das mit 10KHz gepollt wird oder wie ist das zu verstehen.
80KHz entspricht 12us
ein UNO arbeitet mit 16Mz wenn ich jetzt richtig gerechnet habe bedeutet das das zwischen den Signalen des Encoders etwa 200 Prozessortakte liegen. Das ist jetzt mal nicht viel um auch noch was andres zu machen.
@Doc_Arduino Frage wie bist Du an die 200us gekommen ?
agmue:
Das paßt nicht zueinander: Due 84 MHz clock.
Stimmt hatte ich übersehen , dann sind es gut 1000 Takte zwischen zwei Encodersignalen wenn der 1000 I/Umdr hat und 5000U/min dreht , damit kann sicher man schon ehr was machen.
Zudem schreibt der TO ja das die 10 KHz doppelt so hoch sind wie sein fmax dann sollte es abe ja eigendlich gehen. Aber er verrät uns ja keine weiteren Fakten mehr, also hab ich mal Kaffesatz gelesen ud damit gerechnet.
Rentner: @Doc_Arduino Frage wie bist Du an die 200us gekommen ?
Die Abtastfrequenz ist mit 10kHz mehr wie doppelt so hoch, wurde vom TO gesagt.
Demnach ist die maximal zu messende Frequenz die Hälfte, 5kHz. Das "mehr" kann ich nicht genau deuten.
t = 1 / 5000Hz = 0,2ms
Allerdings würde das einer Drehzahl von 5000Hz * 60s entsprechen was 300.000 U/min wären ... ???
Was ist das für ein Motor?
Wenn man von 5000 U/min ausgehen würde, dann hat man gemütliche 83,3 Impulse je Sekunde.
Das macht der µC mit 40 Fieber.
Ich vermute der TO hat sich mit den Zahlen oder Einheiten verhauen.
Sofern die Richtung während der Geschwindigkeitsmessung unwichtig ist (der Motor wird wohl nicht bei 5000/min plötzlich die Drehrichtung wechseln ...), hätte man 100 Takte (160kHz zu 16MHz) 'Zeit', den nächsten Impuls zu erfassen.
Das macht man immer x ms lang und bildet aus den so gewonnenen Werten die Summe 'Impulse pro Sekunde' (oder ähnlich).
Wenn's nur eine Anzeige werden soll, stört Es auch nicht, daß man 'in der Zwischenzeit' das Zählen sein lässt, um das Display zu aktualisieren.
Der danach gestartete Zähl-Zyklus dauert wieder die x ms (also immer die gleiche Zeit), wodurch sich ein gleitender Mittelwert ergeben sollte.
Da der Arduino für Display und User-Kommunikation nicht all zu viele ms unterwegs ist, sollte Das kaum bei den Mittelwerten auffallen.
Zu Beginn der Drehung kann man mittels des Encoder die Drehrichtung feststellen, danach muß man nur drauf achten, daß der Motor nicht stehen bleibt - oder unterhalb einer gewissen Frequenz eben den Encoder auswertet um damit die Drehrichtung festzustellen - sollte der Motor runter gebremst und in Gegenrichtung beschleunigt werden, wäre halt in der Zeit, wo der Motor keine 100/min macht die Encoder-Abfrage, drüber die Impuls-Summe 'am Zug'.
stimmt, die Auflösung vom Encoder habe ich komplett unterschlagen. Damit verschärft sich das Timing. Allerdings finde ich keine Angabe zur Auflösung im einseitigen Datenblatt.
Ich tendiere dazu dem TO folgendes zuempfehlen.
2 Magneten auf die Welle wegen möglicher Unwucht und diese mit Hallsensor erfassen. Dann wird das auslesen ein Spaziergang.
Oder Encoder zerlegen und alle Löcher einer Phase bis auf eins zukleben.
Weder ob der Encoder auf Motorwelle sitzt ,noch die Wertigkeit des Encoders , nicht mal die Drehzahl des Encoders.
Das was wir wissen ist das der Encoder mit 5 kHz Signale an einer Spur abgibt. Die anscheinend mit einer Frequenz von 10 kHz abgefragt werden. Mit der Aussage kann eigendlich kein Impuls verloren gehen und das Problem sollte nicht bestehen . Da das anscheinend aber doch der Fall ist scheint an den Angaben was nicht zu stimmen .