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.
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
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.
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.
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