Hallo,
Am STM32F407 will ich 2 Motoren mit Quadraturencoder betreiben.
(Lageregelung). Um die Drehzahl zu erfassen brauche ich ja InputCapture.
Beim Quadratur-Encoder ist der Timer ja die Zählbasis, also muss ich mit
allen Signalen noch zusätzlich auf andere Pins, und auf andere Timer ?
JanK.
Einfach A und B signal von Encoder anschliessen an die richtige timer
pins, Timer configurieren und das soll functionieren. Der Timer counter
entspricht dan genau die erfasste pulsen von Encoder.
@JanK. (Gast)
>Ja. Das Zählen geht. Aber für die Drehzahlerfassung brauche ich doch den>Zeitpunkt der Flanken. Also zusätzlich InputCapture. Oder nicht ?
Oder nicht. Du musst mit einem (sowieso benötigte) Timer in
regelmässigen Abständen deinen Quadraturdecoder auslesen. Die Differnz
der Zählerstände geteilt durch die Zeitspanne ist deine Drehzahl. Nix
mit Input Capture.
Na dann hab ich doch keine Auflösung mehr.
Wenn so ein Encoder bei max. Drehzahl vielleicht 3kHz hat (4-fach
Auswertung).
Dann hätte ich in einer Regelung in der 1ms Task Drehzahlen von 0 bis 3
Einheiten (bei vmax). Bei kleineren 0 oder 1.
JanK. schrieb:> Na dann hab ich doch keine Auflösung mehr
Das Problem ist doch alt wie die Welt (der Elektronik). Wenn die
Frequenz zu niedrig ist um zu zählen, schaltet man um auf
Periodendauermessung.
Georg
>was du brauchst ist keine Encoder Auswertung>sondern eine PWM-Input Messung
Ich will eine Lageregelung (unterlagerte Drehzahlregelung).
Dazu brauch ich den Encoder.
PWM ist immer 50%, da es ja 2 um 90% phasenverschobene Signale mit 50%
Tastverhältnis sind.
>Das Problem ist doch alt wie die Welt (der Elektronik). Wenn die>Frequenz zu niedrig ist um zu zählen, schaltet man um auf>Periodendauermessung.
Ja. Will ich ja machen. Mit InputCapture.
Die Frage war, muss man dazu beim STM32 alle Signale auf 2
unterschiedliche Timer mit jeweils 2 unterschiedlichen Pins legen ?
JanK. schrieb:> muss man dazu beim STM32 alle Signale auf 2> unterschiedliche Timer mit jeweils 2 unterschiedlichen Pins legen ?
Ich kenne den STM nicht. Aber wenn da ein Encoder drin ist, dann ist das
nächste Problem, dass du den Encoder-Ausgang als Capture-Eingang
brauchst. Ich weiss nicht ob man da dran kommt.
Georg
JanK. schrieb:> Ja. Will ich ja machen. Mit InputCapture.>
für was brauchst du denn dann noch den Encoder ?
du hast doch selbst gesagt, das er zu langsam für deine Zwecke ist
falls du nicht noch die Richtung auswerten musst,
genügt ein Eingangspin auf einen Input-Capture Eingang
von einem Timer
damit kannst du die Frq und den Duty-Cyle (der immer 50% ist) messen
und diese Betriebsart des Timers wird im RefManual von ST
als "PWM input mode" beschrieben
einfach dort mal nachlesen
Gruss Uwe
Hi,
> Um die Drehzahl zu erfassen brauche ich ja InputCapture.
eher nicht weil du beim Pendeln falsche Drehzahlen bekommen würdest.
Was du aber machen kannst ist beim Auftreten eines Inc im
Quadraturencoder
einen Timer auslesen (fast wie Input-Capture)und beim Auftreten des
nächsten Inc mit der selben Richtung die Diff bestimmen... müsste
eigentlich gehen.
Viel Erfolg, Uwe
Also ich will die Quadratur-Dekodierung nicht im Interrupt machen.
Ich will nicht bei jedem Event ein Interrupt auslösen.
Sondern den Quadratur-Encoder vor sich hin zählen lassen und in jeder
(1ms) Task auslesen. Dort findet auch die Regelung statt.
Gleichzeitig will ich die Zeit der letzten Flanke wissen (Input
Capture).
Dann weiss ich, in der letzten Task stand der Zähler bei 3. Jetzt bei 5.
Bei 3 war der Zeitstempel noch 1000µs. Jetzt bei 5 steht er bei 1024µs.
Dann hat der Motor also eine Drehzahl von 2Steps/24µs*K.
>weil du beim Pendeln falsche Drehzahlen bekommen würdest.
Nein. warum ?
Man muss allerhöchstens nach dem lesen des InputCapture Wertes nochmals
prüfen, ob sich inzwischen nicht die Position verändert hat, da man
nicht beides gleichzeitig lesen kann.
Eine Drehzahl Erfassung mit einen update jeden ms ist wenig Sinnfoll :
Drehzaehlen aendern sich nicht schlagartig jeden ms. Die Periodendauer
messen ist auch nicht so genau : meistens ist die duty cycle nicht exact
50%, und das versatz zwischen A/B spur ist auch nicht exact 90°. Damit
hat men verschiedene Periodendauer bij gleiches Drehzahl ! Auch wen die
Periode laenger ist als 1 ms, muss die Regelung die vorher gemessene
Periode nutzen !
Einfachste Lösung : Nur jeden 25 oder 50 ms einen Update machen, oder
hochauflosende Encoder nutzen (1024 Polungen/Umdrehung).
Uebrigens functioniert eine Positionsregelung nicht nur auf basis von
Drehzahlregelung : da wird eine vergleich gemacht zwischen Ist und Soll
Position, diesen Wert wird dan mit eine P-regelung auf die Motor
gegeben.
>Drehzaehlen aendern sich nicht schlagartig jeden ms.
Also Servomotoren haben mechanische Zeitkonstanten von etwa 1ms.
Und DC Getriebemotoren liegen auch um 10ms Bereich.
>Die Periodendauer>messen ist auch nicht so genau : meistens ist die duty cycle nicht exact>50%, und das versatz zwischen A/B spur ist auch nicht exact 90°. Damit>hat men verschiedene Periodendauer bij gleiches Drehzahl ! Auch wen die>Periode laenger ist als 1 ms, muss die Regelung die vorher gemessene>Periode nutzen !
Das stimmt. Aber die kann (während des Betriebes) gelernt werden. Mann
muss für Phase 0,1,2 und 3 einen Korrekturwert hinterlegen.
>Uebrigens functioniert eine Positionsregelung ..
Ja. Ich wollte einen Kaskadenregler mit unterlagerter Drehzahlregelung
machen.
meine Geschwindigkeitserfassung ist auch viel langsamer als 1mSec. Eine
solche Beschleunigung halte ich vielleicht theoretisch für möglich. In
der Praxis hat der Motor aber wahrscheinlich mechanische Massen zu
bewegen ...
JanK. schrieb:> Also Servomotoren haben mechanische Zeitkonstanten von etwa 1ms.
In 1ms aus dem Stand auf 63% der Maximaldrehzahl?
Hast du da mal einen Link auf ein Datenblatt?
>In 1ms aus dem Stand auf 63% der Maximaldrehzahl?>Hast du da mal einen Link auf ein Datenblatt?
Leider nicht. Es war in der Vorlesung "Servomotoren". Da hatten wir das
Modell eines Servomotors und mussten den Regler dazu entwerfen.
Egal.
Da sich meine Frage hier nicht eindeutig beantworten ließ:
Ich hab alle Quadraturencodersignale jetzt doch noch auf einen 2. Input
Capture Eingang gelegt. Morgen mach ich das Layout und wenn ich in 2-3
Wochen dann die Software habe postes ich es hier nochmals. (Oder schreib
einen Artikel.)
Aber das grundlegende Problem bleibt noch : wass machts du bei eine
Periodedauer laenger dan 1 ms ? Auch das Regelinterval aendern ? Dan
wird ihre Regelung auch langsamer ! In Praxis ist das auch so das sehr
niedrige Drehzaehlen von ein DC-Getriebemotor sich nicht schon regelen
lassen : Das Drehmoment wird dan abhangig von stand von die Achse
(brushed motor). Damit hat man kein Lineaires Verband zwischen PWM-Wert
und Drehmoment. Die besten Motoren sind dan diese mit eine Eisenlose
Anker (Maxon, Faulhaber...).
Der Thread ist zwar schon etwas älter, aber ich stehe gerade vor dem
gleichen Problem wie der Ersteller und eine schöne Lösung wurde ja noch
nicht gefunden...
Für das Verfahren gibt es sogar ein Paper:
http://www.diegm.uniud.it/petrella/Azionamenti%20Elettrici%20II/Tesine/Petrella%20et%20al.%20-%20Speed%20Measurement%20Algorithms%20for%20Low-Resolution%20Incremental%20Encoder%20Equipped%20Drives_a%20Comparative%20Analysis.pdf
Dort wurde ein TMS320F24x von TI verwendet, so wie ich das verstehe mit
2 Timern. Ein Timer (T1) ist wohl mit einer Clock der MCU verbunden, der
zweite (T2) läuft im Encoder-Modus und zählt Pulse. Bei jeder Änderung
von T2 wird dann ein Capture Event bei T1 ausgelöst, sodass man immer
den Zeitpunkt der letzten Flanke abrufen kann.
Die Frage ist, kann man das irgendwie beim STM32 nachbilden? Ich habe
mal ins Reference Manual geschaut, aber keinen Weg gefunden, ein Capture
Event durch einen anderen Timer zu triggern. Die Lösung, den Encoder
hardwareseitig an beide Timer anzuschließen, ist irgendwie aber auch
nicht das Gelbe vom Ei.
Der Drehzahlmessbereich ist mit einer Messung der Positionsänderung
immer schlecht. Jage die Positionsistwerte durch eine PLL die der
Motorposition folgt. Dann hast du eine saubere Drehzahl.
Servus,
so wie ich das verstanden haben:
Kaskadenregelung, wobei nur ein Encodersignal vorhanden ist.
Nun gut, nur so nebenbei es gibt auch Tachogenerator fürn Motor. Das
Problem ist die Zusatzkosten + wo kommt der Encoder hin.
Mit den Encoder misst man doch nur den Winkel. Dann gilt:
omega=d_pfi/dt. Hier schließt sich heraus, dass man nur eine
Differenzenbildung machen muss und diese durch die Abtastzeit teilen.
WorstCase:
Motor hat mehrere Umdrehung gemacht wärend der Abtastzeit. Wie bestimmt
man das?
Ich würde die Encoder Register auf volle 16bit setzen, dann kann sowas
nicht passieren. Bei jeder Abtastung Differenz bilden und Register
wieder Rücksetzen. Ganz einfach. Eventuell noch ein Tiefpass verpassen.
Eine andere Möglichkeit wäre: Viele Encoder geben ein zusätzliches
Signal bei einer bestimmten Umdrehung, k.A etwa 90° oder bei voller
Umdrehung. Ja, die könnte man mit einen Interrupt auch anzpfen. Ist aber
meiner Meinung nach unnötig.
mfg
Ach ja, wenn die das KnowHow vorhanden ist, dann kann man Luenberger
Beobachter anwenden. Steht ja in den Paper alles drin. Dadurch läuft der
Motor schön geschmeidig. :P
Kaskadenregelung ist schon richtig, wobei ich im sehr kleinen
Drehzahlbereich, d.h. ca. 0-250 rpm, unterwegs bin und aus Platzmangel
leider nur einen Encoder habe. Eine PLL und sin/cos-basierte
Kalmanfilter kommen daher wohl weniger in Frage. Am liebsten würde ich
ohne Systemmodell arbeiten, da die Störgrößen bei mir dominieren.
Aufgrund der geringen Drehzahl könnte man in diesem Fall sicher noch mit
Interrupts arbeiten und sich die Zeit dazu abspeichern. Bei 4
Umdrehungen pro Sekunde und einem üblichen Encoder (2048 Flanken) würde
die Interrupt-Frequenz im Höchstfall rund 8 kHz betragen.
Schön wäre es natürlich trotzdem, wenn sich das ohne große CPU Belastung
realisieren ließe.
Folgende Frickelei habe ich mir jetzt mal für den STM32 überlegt:
- Timer 1 läuft im Encoder-Modus und resettet sich bei einem Wert von 1
- Timer 2 läuft im Normalbetrieb durch eine Clock der MCU getaktet
- Timer 2 ist Slave von Timer 1 und wird durch dessen Reset selbst
resettet, also nach jedem Encoder-Tick
- Timer 3 ist Slave von Timer 2 und zählt bei einem Reset von Timer 2
eins hoch
Dann hat man in Timer 3 die aufsummierten Encoderticks und in Timer 2
kann man immer nachschauen, wie lange der letzte Tick zurückliegt.
Funktioniert aber natürlich nur in einer Drehrichtung und verbraucht
doch recht viele Timer...
Dino H. schrieb:> Kaskadenregelung ist schon richtig, wobei ich im sehr kleinen> Drehzahlbereich, d.h. ca. 0-250 rpm, unterwegs bin und aus Platzmangel> leider nur einen Encoder habe. Eine PLL und sin/cos-basierte> Kalmanfilter kommen daher wohl weniger in Frage. Am liebsten würde ich> ohne Systemmodell arbeiten, da die Störgrößen bei mir dominieren.
Ah was bitte? Gerade bei niedrigen Drehzahlen bekommst du doch gerade
wenig Impulse rein. Und mit der Timer Methode hast du dann eine untere
Grenzfrequenz, ab der du die Drehzahl als null an sehen musst! Wenn von
einem Abtastzeitpunkt zum nächsten sich die Encoder Position nicht
geändert hat und sich diese erst im 2. Abtastschritt ändert. Das sorgt
für Vibrationen im Regler und auf der Welle. Und was bitte kostet dich
eine PLL? 2 Parameter und 2 Multiplikationen und 3 Additionen uhhhh und
das bei 1ms Abtastfrequenz dafür braucht man sicher einen i7 mit
5GHz????
Ich kann verstehen das du keinen Lunenberger oder n Kalmanfilter
dimensionieren möchtest, OK. Aber einen PI Regler und ein Integrator
sollten bei der Anwendung schon drin sein. Und du hast ein F4 also ne
FPU, dann mach sie auch an! Und nutze die Auflösung die dir das Ding
liefert.
Dino H. schrieb:> Folgende Frickelei habe ich mir jetzt mal für den STM32 überlegt:> - Timer 1 läuft im Encoder-Modus und resettet sich bei einem Wert von 1> - Timer 2 läuft im Normalbetrieb durch eine Clock der MCU getaktet> - Timer 2 ist Slave von Timer 1 und wird durch dessen Reset selbst> resettet, also nach jedem Encoder-Tick> - Timer 3 ist Slave von Timer 2 und zählt bei einem Reset von Timer 2> eins hoch
Super du hast einen Frequenzzähler gebaut, das ist ein halbwegs
sinnvoller Ansatz.
Frage: Was passiert wenn der Antrieb ganz langsam weg driftet um sagen
wir 10 Steps pro Sekunde? oder noch weniger?
Gruß
Tec
Also beim PIC µC habe ich das über Timer und VELxCNT gemacht.
Das ist jetzt eine Berechnung für ein Motor mit Encoder 8192 Puls je
Phase pro Umdrehung:
Hallo zusammen,
auch ich messe die Drehzahl mit einem Encoder.
Ich habe einen Timer (TIM1) der für die Erzeugung von PWM zuständig ist.
Dieser ist in Center-Aligned-Mode konfiguriert. Bei jedem Überlauf bzw.
wenn der max. Wert von 2047 erreicht wird, wird ein Interrupt ausgelöst.
In der ISR wird der Zählerstand des Encoder-Timers abgespeichert (in der
Variable zaehlerstand_neu). In einer zweiten Variable (zaehlerstand_alt)
ist am Anfang eine 0 gespeichert. Als nächstes berechne ich die
Differenz dieser zwei Variablen. Hiermit weiß ich, um wieviel
Encoderschritte der Rotor sich bewegt hat. Da das ganze in einer ISR
berechnet wird, weiß ich auch die Zeit. Ich habe also den Weg und die
Zeit(die Sample Time), die zwei Sachen die man benötigt um eine
Geschwindigkeit(Drehzahl) zu berechnen. Ich hier nicht viel zu viel
erklären weil es dann zu viel wird. Hier mein Code:
Der Wunsch ist klar. 2 Pins liefern das Encoder Signal und ein Timer ist
als QuadraturEncoder eingestellt.
Ein zweiter Timer wird als InputCapture verwendet und misst die Dauer
zwischen zwei Pulsen.
So bekommt man die Vorteile beider Welten - Position plus Zeit zwischen
zwei Puls in Hardware gemessen. Ohne Overhead von Interrupts,
Genauigkeit etc.
Die Lösung dafür ist Master Slave. Den Encoder Timer konfiguriert man
als Master, der immer einen Puls ausgeben soll MMS=0b011 (TIM_TRGO_OC1).
Und der zweite Timer ist ein normaler InputCapture, nur dass er als
Input Signal nicht einen Pin annimmt, sondern den Master.
Dazu muss man nachsehen welcher Timer der Master ist, welcher Slave
diesen auswerten kann und wie dessen interne Verbindung heißt, z.B.
sSlaveConfig.InputTrigger = TIM_TS_ITR1;
Soweit so gut. Jetzt muss ich es nur noch zum Laufen bringen.
PS: Wegen Genauigkeit...
Rein über die Pos-Änderung, muss man die Position periodisch auslesen.
Je öfter, um so genauer ist die Geschwindigkeit. Was aber wenn die
Position gleich, weil z.B. alle 20ms die Positionsänderung ausgewertet
wird, aber das Rad sich so langsam dreht? Gut, die Lösung dafür ist sich
zu merken wann die letzte Positionsänderung war, so kommt man auch auf
Geschwindigkeiten wie 0.5. Aber nur noch mit einer Genauigkeit von
+-20ms. Alles nicht optimal....