Guten Tag zusammen, folgendes Szenario liegt mir vor: Ich möchte mit einem Getriebemotor mit integriertem Inkremental Drehgeber an meinem STM32L152 die Umdrehungen der Welle messen. Der Motor ist ein billig Teil aus China und besitzt zwei Hallsensoren, welche ein um 90° versetztes Rechtecksignal ausgeben. Die zwei Leitungen der Signale habe ich an den Encoder(Timer 4) des µC angeschlossen. Der Counter wird in Uhrzeigerrichtung hoch und gegen den Uhrzeiger runtergezählt. Soweit funktioniert auch alles, allerdings verschieben sich meine Endlagen der Welle, womit ich bei mehrmaligen hin und herfahren mit dem gleichen Counterwert für bei Richtungen, nicht mehr an den Positionen stoppe wo ich es eigentlich möchte. Im Grunde möchte ich die Drehrichtung gar nicht ermitteln, sondern wirklich nur ein genaues anfahren von zwei Endlagen erreichen. Dazu sei noch gesagt dass ich CubeMX und die HAL Library verwende. Kann mir damit jemand weiterhelfen? Habe ich evtl. den Sinn hinter dem Encoder oder den Signalen des Motors falsch verstanden? Vielen Dank im Voraus! MFG, DerHasenHerbert
Anhand der Fehlerbeschreibung brauchst Du doch nur noch checken wann der Zählerstand/Positionswert nicht mehr mit der realen IST Position überein stimmt. Vermutlich läuft das beim Wechsel der Richtung aus dem Ruder. Einzelstep vor zurück - und genau hinschauen.
Hab jetzt nicht rauslesen können ob du den internen Quadratur Controller nutzt oder deine eigene Funktion dazu geschrieben hast.
DerHasenHerbert schrieb: > allerdings verschieben sich meine > Endlagen der Welle Es wäre nicht verkehrt, sich die Encodersignale auf einem Oszi anzuschauen, ob es auch "schöne" Rechtecke sind. Georg
Kann das vielleicht am Spiel im Getriebe liegen ? Spielfreie Getriebe gibt es nicht, höchstens welche, die wenig Spiel haben.
Eigentlich sind die Voraussetzungen, Hallsensor und Hardware-Decoder, optimal. Daher tippe ich auf Störungen durch die Motoransteuerung, deren Kollektorfunken und fehlende Funkentstörung.
Vielen Dank erstmal für die vielen Antworten in der kurzen Zeit! Zunächst mal die Init des Timers für den Encoder (Controller wird mit der MSI auf 4,193 MHz betrieben): static void MX_TIM4_Init(void){ TIM_Encoder_InitTypeDef sConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim4.Instance = TIM4; htim4.Init.Prescaler = 419; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 65535; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; sConfig.EncoderMode = TIM_ENCODERMODE_TI1; sConfig.IC1Polarity = TIM_ICPOLARITY_RISING; sConfig.IC1Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC1Prescaler = TIM_ICPSC_DIV1; sConfig.IC1Filter = 0; sConfig.IC2Polarity = TIM_ICPOLARITY_RISING; sConfig.IC2Selection = TIM_ICSELECTION_DIRECTTI; sConfig.IC2Prescaler = TIM_ICPSC_DIV1; sConfig.IC2Filter = 0; if (HAL_TIM_Encoder_Init(&htim4, &sConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) { Error_Handler(); } } @NichtWichtig: Werde ich mal testen. Allerdings verwundert es mich, dass die Verschiebung der Endlagen immer nur in eine Richtung geschieht. --> Evtl noch ein Wichtiger Hinweis <--- @Nico: Ich verwende den internen, die Funktionen für die Initialisierung habe ich von CubeMX generieren lassen. Ich muss dann nur noch den Encoder an der passenden stelle starten und stoppen und TIM4->CNT auslesen. @Georg: Das hab ich schon gemacht, die Signale sind m.M.n. einwandfrei, lediglich beim stoppen des Motors "zieht" sich das Signal über ein paar ms auf dem jeweiligen high oder low stand des Signals. -> hier könnte ich mir die Fehlerquelle vorstellen, würde zu NichtWichtig´s Vermutung passen, das der Fehler beim Richtungswechsel stattfindet... @Schorsch: Diese Vermutung hab ich auch, falls ich heute nicht weiter komme, werde ich mal noch einen höherwertigen Motor bestellen... @MaWin: Wie könnte ich das denn Abfangen? Im Anhang meine Motorschaltung, an dem 1x2 Header werden die Stromversorgungsleitungen des Motors angeschlossen.
Ich bin mit der HAL nicht so Firm. Aber sehe ich das richtig, dass du nur steigende Flanken auswertest? Wenn die Dinger Prellen sollte da ja alles mögliche bei rumkommen. Ich würde einmal auf BOTH stellen. Dann müsste der Encoder das intern ja richtig machen.
Kann leider nicht zur Lösung des Problems beitragen, und es ist nur ein frommer Wunsch von mir, mal mit dem STM32 umzugehen und Motorsteuerungen zu bauen, ich möchte aber an dieser Stelle schon mal eine Verständnisfrage stellen: Ist es so, daß der STM32 einen ausgewiesenen Harware-Quadraturencoder hat? Also daß sich ein Zähler und zwei Eingangspins so konfigurieren lassen, daß sie ohne wenn und aber, ohne Interrupt, ohne Programmcode, ohne Polling den Positionswert zählen, der dann im Programm nur aus einem bestimmten Register rausgelesen werden muß? Das ganze Konfigurieren, Setzen von Flankenauswertungen und Timings verunsichert mich jetzt etwas...
@Nico: Habe ich alles schon ausprobiert, nur ein Channel Rising, Falling und Both und beide Channels mit Rising, Falling und Both.... Alles mit dem gleichen Resultat @Tom: Wie Johannes schon geschrieben hat, ja haben sie. Du kannst dir mal das PDF AN4013 - STM32 cross-series timer overview anschauen, da steht die Funktionsweise des Encoders unter 4.3.4 beschrieben.
Hab ein ähnliches Problem allerdings mit einem optischen Drehgeber. Hab mal das Oszi angeschlossen und siehe da: beim Fahren auf Block (schwingt dann wahrscheinlich etwas) und das kommt dabei heraus:
Wenn du genug RAM hast kannst ja einmal Testweise bei jedem Interrupt die Position abspeichern und dir nach jeder Runde auslesen lassen. Ich lege dann gerne einfach den Debugger an und schreib mir den Speicher direkt in eine Datei. Kann man dann sehr einfach z.b. mit Python analysieren.
Tom schrieb: > Ist es so, daß der STM32 einen ausgewiesenen Harware-Quadraturencoder > hat? Ja, zumindest einiger STM32 Modelle.
Guten Morgen, zunächst einmal vielen Dank nochmal an alle! Ich habe jetzt mal den Richtungswechsel, bzw. das stoppen des Motors genauer betrachtet. Das Problem ist wohl tatsächlich, dass die Magnetscheibe des Drehgebers zu viel spiel hat. Beim stoppen dreht die noch ein paar runden, was an sich nicht schlimm wäre, wenn sie in beide Richtungen nicht verschieden lange ausdrehen würde.... Selbst wenn ich per PWM die letzten Drehungen minimal laufen lasse, schafft es der Motor nicht exakt zu stoppen. Werde es jetzt mit einem selbst gebastelten Drehgeber aus einem Minimagneten in einer Spule und einem Reedkontakt probieren.
>Beim stoppen dreht die noch ein paar runden,
Mach doch mal bitte ein Foto des mechanischen Aufbaus. Ein paar
"Runden", was soll das sein?
Rund schrieb: > Mach doch mal bitte ein Foto des mechanischen Aufbaus. Ein paar > "Runden", was soll das sein? Die Welle dreht vorwärts und rückwärts leicht verschieden, der Unterschied wird später durch das Gewicht welches der Motor hochziehen soll wahrscheinlich noch größer. Und die schwarze Magnetscheibe an der Platine des Motors dreht noch einige Runden nach, dadurch zählt der Sensor weiter, daher ist über den Sensor auch keine 100%ig genaue Position festzustellen.
die Position sollte damit trotzdem exakt erfasst werden, nur beim Stoppen hält der Motor nicht da an wo du möchtest weil der nachläuft. Das kann man veringern indem man den beim Abschalten kurzschließt.
DerHasenHerbert schrieb: > Die Welle dreht vorwärts und rückwärts leicht verschieden Das ist doch mechanisch Unsinn. Aber abgesehen davon: Bei einem korrekt ausgewerteten Drehgeber gibt es keinen sich steigernden Fehler, weil der auch bei Spiel und Hin- und Herwackeln genausoviele Schritte vorwärts wie zurück zählt. Je nach Spiel zeigt der Zählerstand also nicht genau die tatsächliche Position an, aber der Fehler addiert sich nicht auf und wird bei wiederholten Positioniervorgängen nicht grösser. Kann man das Spiel nicht ausreichend verringern, so kann man in vielen Fällen das Problem lösen indem man die Position immer aus der gleichen Richtung anfährt. Wird der Fehler immer grösser so muss es im System Schlupf geben, z.B. rutschende Riemen. Georg
DerHasenHerbert schrieb: > Das Problem ist wohl tatsächlich, dass die > Magnetscheibe des Drehgebers zu viel spiel hat. Beim stoppen dreht die > noch ein paar runden, Was? Eine nachdrehende Scheibe? Das ist ein mechanischer Defekt. Mach das Dingen auf der Welle fest!
vielleicht sieht das auch nur so aus als ob die Scheibe lose dreht. Das ist ja ein Getriebemotor, die Motorwelle dreht da locker um einiges weiter wenn da nix gebremst wird.
DerHasenHerbert schrieb: > Die Welle dreht vorwärts und rückwärts leicht verschieden Kaum. Halt doch mal die Motorwelle vorne fest, und versuche hinten das schwarze Rad zu drehen. Es wird fest sein. Wenn der Motor nach dem abschalten weiterläuft, dann wegen der Trägheit (es wurde schon geschriebene: kurzschliessen bremst heftiuger, geht aber auch mehr alf's Getriebe), und das muss der Incrementalencoder trotzdem richtig zählen.
>Je nach Spiel zeigt der Zählerstand also nicht genau die tatsächliche >Position an, aber der Fehler addiert sich nicht auf und wird bei >wiederholten Positioniervorgängen nicht grösser. Kann man das Spiel >nicht ausreichend verringern, so kann man in vielen Fällen das Problem >lösen indem man die Position immer aus der gleichen Richtung anfährt. Von der gleichen Richtung anfahren geht nicht, da ich eine Klappe hoch und runterfahren möchte, daher muss ich in beide Richtungen fahren. Und da er immer in eine Richtung weiter fährt, wie in die andere, addiert sich der Fehler in diesem Sinne schon. > Halt doch mal die Motorwelle vorne fest, und versuche hinten das > schwarze Rad zu drehen. > > Es wird fest sein. > > Wenn der Motor nach dem abschalten weiterläuft, dann wegen der Trägheit > (es wurde schon geschriebene: kurzschliessen bremst heftiuger, geht aber > auch mehr alf's Getriebe), und das muss der Incrementalencoder trotzdem > richtig zählen. Das schwarze Rad ist definitiv nicht fest ;) kann es auch so mit den Fingern drehen ohne das sich die Motorwelle dreht. Kurzschließen halte ich für eine relativ unsaubere Lösung. Ich werde eher noch einen etwas hochwertigeren Motor mit Drehgeber testen, ansonsten die selbst gebastelte Lösung...
DerHasenHerbert schrieb: > Das schwarze Rad ist definitiv nicht fest ;) kann es auch so mit den > Fingern drehen ohne das sich die Motorwelle dreht. Siehe: Arduino Fanboy D. schrieb: > Das ist ein mechanischer Defekt. > > Mach das Dingen auf der Welle fest!
DerHasenHerbert schrieb: > Und > da er immer in eine Richtung weiter fährt, wie in die andere Das tut er ganz bestimmt nicht, sonst würde er über kurz oder lang an die nächste Wand stossen. Georg
DerHasenHerbert schrieb: > > Das schwarze Rad ist definitiv nicht fest ;) kann es auch so mit den > Fingern drehen ohne das sich die Motorwelle dreht. Ohne Worte :x
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.