Forum: Projekte & Code Schrittmotoren ansteuern


von Gerhard paulus (Gast)


Lesenswert?

Hallo,

ich hab mich mal mit Schrittmotoren beschäftigt und einige Ergebnisse
hier zusammengefaßt:

  http://www.gnomsoft.de/stepper.txt

Obiger Text könnte Leuten nützlich sein, die sich für die Ansteuerung
von Schrittmotoren mit Mikrocontrollern interessieren und in dieser
Materie mehr oder weniger von vorne anfangen. Mit einem AVR AT90S4433
und einem L293D werden mittels einfacher
Assembler-Programme Vollschritt, Halbschritt und Mikroschritt getestet,
und dies sowohl bei unipolarer als auch bei bipolarer Ansteuerung.

Für Hinweise auf falsche Fehler wäre ich dankbar ...

Gerhard

von Michael (Gast)


Lesenswert?

Hallo Gerhard,

schön, daß Du Dir die Mühe gemacht hast, Beschreibung und Programm zur
Ansteuerung zu erstellen.
Bezüglich der Mikroschrittansteuerung würde ich einschränkend sagen,
daß nicht alle Motoren geeignet sind, diese auch linear auszuführen, da
ihr magnetischer Aufbau darauf optimiert ist, die vollen Schritte mit
möglichst hoher Kraft zu machen.
Hingegen wäre eine Absenkung des Spulenstroms bei Stillstand nicht
schlecht. Dadurch wird die Erwärmung stark reduziert. Praxiswert 1/3
Imax.
Für bipolaren Betrieb bieteten sich u.a. L6219 und 2 x TEA3717/3718 an,
die Mikroschritte unterstützen und durch eine veränderbare Vref den
Betriebsstrom einstellen/reduzieren können.

Dies aber nur als Ergänzung zu Deiner Beschreibung.

Michael

von Gerhard Paulus (Gast)


Lesenswert?

Den Vorschlag von Michael hab ich aufgegriffen und für den TEA3718 ein
Programm zum Testen von bipolaren Schrittmotoren geschrieben:

  http://www.gnomsoft.de/TEA3718.txt


Vollschritt, Halbschritt, Minischritt (1/3,2/3), inkrementelle Schritte
vorwärts und rückwärts, Anzeige der aktuellen Pulse pro Sekunde ...

von Norman Paasche (Gast)


Lesenswert?

Hallo,

Habe jetzt von Nanotec den IMT901 Chip (14Eu's) getestet. Er kann
Voll-,Halb-,Viertel- und Achtelschritt und das mit minimalem
Bauelementeaufwand. -> www.nanotec.com oder .de .
Wer hat schon mal was mit den Chips von Allegro gemacht?
(A3955,A3972,A3973,A5804)

Norman

von Michael (Gast)


Lesenswert?

@Norman

>Habe jetzt von Nanotec den IMT901 Chip (14Eu's) getestet.

WIE ?

Treiber ICs gibt's viele - viele Hersteller, viele Typen, viele
Preise. Man kann sie auf den Tisch legen, an einen Motor anschließen,
mit Spannung versorgen: der Nachteil dieser ICs ist, es bewegt sich
nichts !

Daher: Wie hast Du sie angesteuert ? Welcher Controller ? Welche Rampen
- linear oder exponentiell ? Wie wirken sich die 1/4 oder 1/8 Schritte
bei niedrigen Drehzahlen auf die Eigenresonanz der Motoren aus ?

Das wäre doch interssant zu erfahren.

von NormanPaasche (Gast)


Lesenswert?

Hallo Michael,

der Chip selbst kontrolliert den Motorstrom, choppert diesen.
Durch Steuereingänge legt man die Schrittbreite (1/1;1/2;1/4;1/8)
fest. Mit dem Richtungssignal und dem CLK1 steuert man nun Schritt
für Schritt den Motor an.
Solange man eine bestimmte vom Motor und dessen Trägheit abh. Drehzahl
nicht überschreitet, folgt der Rotor im Motor dem Drehfeld. Es handelt
sich ja um eine Synchronmaschine. Diese ist so aufgebaut, das immer
ein Polpaar pro Vollschritt entsteht. Das heißt, alle anderen
Schrittbetriebsarten ergeben sich ja nur durch unterschiedliche
Magnetfelder (siehe Bestromung) und sind daher instabil. Regelungs-
technisch betrachtet ist jeder Motor ein Integrationsglied, welches
ohne Belastung zu Schwingungen neigt. Erst wenn an der Motorwelle eine
Last, ein Getriebe oder ähnl. anmontiert ist, hat der Motor einen
p-Anteil, welcher sich aus dem Flächenträgheitsmoment ergibt.
Das Flächenträgheitsmoment des Ankers ist jedenfalls zu gering, um
das Drehverhalten des Motors einzuschätzen.

Daraus ergibt sich, das wenigstens eine Schwungscheibe an den Rotor
gekoppelt werden muß, um eine vernünftige Regelung hinzubekommen.

Ich habe nun folgendes gemacht:
Mit einem ATmega128 steuere ich den IC an. Ich gebe an einem Portpin
den Takt aus, für den Schrittmotor. In der Timerinterruptroutine er-
zeuge ich wechselseitig eine 0 bzw. eine log. 1 am Portpin.
Weiterhin gibt es noch ein Enableflag, um bei erreichen der Position
den Takt auszuschalten.

Wenn jetzt der Motor zu einer bestimmten Position fahren soll, so
berechnen ich zuerst die Schrittweite. In Abh. vom Regelparameter
kp ergeben sich nach meiner Rampenfunktion n-Schritte.
Nun wird vom Endpunkt die n-Schritte abgezogen (entspr. Drehrichtung
kann dies auch eine Addition sein). Dieser Punkt wird in einer
Variablen hinterlegt, und stellt den Beginn der Bremsrampe dar. Die
Beschleunigungsrampe endet bei erreichen der Maximaldrehzahl (Vorgabe-
parameter Vmax). Sollte der zu verfahrende Weg kleiner sein, als die
Rampenlänge, so wird der Bremspunkt auf die Hälfte des Verfahrweges
festgelegt.
Nach dem nun alle notwendigen Parameter festgesetzt wurden, erfolgt
der Start des Motors.
In der Interruptroutine wird nun der Takt freigegeben, und pro Takt
die Position um 1 Schritt erhöht oder erniedrigt (siehe Drehrichtung).
Weiterhin wird die jetzt gerade erreichte Position verglichen mit dem
Bremspunkt, um die Bremsrampe einzuleiten; sowie mit dem Endpunkt, um
den Motor auszuschalten (Takt disable).
Jetzt kommt die Auswertung der Drehzahl in der Interruptroutine.
Es muß zunächst die Drehzahl bestimmt werden und dann verglichen
werden mit Vmax. Solange Vmax nicht erreicht ist und keine Bremsrampe
gefahren wird - wird entsprechend dem Regelparameter kp aller n-Inter-
ruptaufrufe die Zeitkonstante des Timers so verändert, das die Aufruf-
frequenz des Timers sich erhöht, damit folglich die Drehzahl erhöht
wird. Damit entsteht dann letztendlich die Anfahrrampe.
Ist der Bremspunkt erreicht, so erfolgt jetzt eine Verlangsamung der
Aufruffrequenz des Interrupts, bis Vmin erreicht ist. Sollte die Soll-
position vorher erreicht werden, wird einfach der Motor nicht mehr
getaktet und bleibt stehen.
Ich gebe zu, es klingt etwas schwierig, ist aber bis hierher noch
relativ einfach zu implementieren.

Jetzt kommt sozusagen noch der i-Punkt. Um Resonanzen des mechanischen
Systems zu umgehen, sollten die Resonanzstellen schnell durch laufen
werden. Gleichzeitig kann es sinnvoll sein, den Antrieb hochdynamisch
auszulegen. Daher legt man kp so an, das die Rampe recht steil ist,
aber der Motor mit Getriebe folgen kann. Durch einen I-Anteil in der
Drehzahlberechnung kann in Abh. von der Drehzahldifferenz die Rampen-
steilheit erhöht werden. (Drehzahldifferenz ist hier im Gegensatz zu
Asynchronmotordrehzahlreglern die Differenz zwischen Vmax und der
Istdrehzahl gemeint). Als Ergebnis entsteht eine sinusartige Rampe.

Da ich für meinen Brötchengeber derzeit dieses Projekt bearbeite und
noch in der Entwicklung bin, habe ich bis jetzt nur eine normale
Rampenfunktion programmiert. Das Ergebnis ist, es gibt während der
Anfahrtrampe Geräusche und Schwingungen, die sich durch die Steilheit
der Rampe (siehe kp -Anteil) minimieren lassen. Schrittverluste treten
erst bei extrem steilen Rampen auf. Die Bremsrampe hat bei mir die
gleiche Steilheit wie die Anfahrtrampe. Hier erfolgt jedoch durch die
Trägheit des Antriebssystems (Motor und Getriebe) ein rasches
Abbremsen ohne Geräusche.

Ich hoffe, daß meine Ausführungen verständlich sind bzw. waren. Falls
Interesse besteht, so kann ich gern Teile meines Sources zur Verfügung
stellen.

MfG Norman

von Michael (Gast)


Lesenswert?

Hallo Norman,

an einem Mega128 plane ich zwei Schrittmotoren mit je 2xL6203+L6506 zu
betreiben. Auf 1/4 oder 1/8 Schritte möchte ich verzichten. Durch
geeignete Auswahl der Prozessor-Ports kann man so auch DC-Motoren mit
PWM bidirektional mit bis zu 4A betreiben (PWM1x und PWM3x) oder andere
Lasten schalten; dies geht z.B. mit dem IMT901 nicht, da die Ausgänge
nicht separat gesteuert werden können.

Gut, man muß alles per Software machen, aber ob man einen Pin toggelt
oder ein Bitmuster für die einzelnen Treiber ausgibt, bleibt vom
Zeitbedarf ähnlich kurz. Ansonsten teile ich Deinen Lösungsansatz, dem
Motor nicht eine stupide Drehzahl sondern eine Zielposition vorzugeben,
die er anfährt und dann fertig meldet. Meine Zielvorstellungen sind:
Schrittfrequenz 1Hz - 10kHz, Vorgabe Start-Lauf-Frequenz +
Rampenparameter, dyn. Änderung der Drehzahl mit Berücksichtigung der
Rampe ohne Zwischenstopp, Stopp zu jedem Zeitpunkt ohne Schrittverlust.
Die Fahrt soll mit Vorgabe des Ziels gestartet und mit busy-flag
kontrolliert werden.
Weiter gesponnen: ein kleiner Interpreter, der eine Sequenz der beiden
Motoren ermöglicht. Ich fürchte nur, daß dafür ein Schalttag im
kommenden Jahr zu wenig ist.

So würde mich schon interessieren, wie Du die Rampen anpaßt. Der
Knackpunkt ist ja, daß man in der kurzen Zeit von Schritt zu Schritt
keine großartigen Berechnungen durchführen sondern einen guten
Kompromiß für Rampenverlauf und Zeitbedarf finden möchte.

Das Durchfahren der Resonanzen bei hohen Drehzahlen ist ein Punkt. Ein
weiteres Problem ist aber auch der Betrieb bei niedrigen
Schrittfrequenzen (z.B. 50Hz). Ist bei dem IMT901 die 1/8 Schritt
Auflösung derart, daß die Geräuschentwicklung deutlich abnimmt? Daß das
Hämmern des Motors sich in sanftes Meeresrauschen verwandelt, kann man
wohl nicht erwarten.
Versuche mit 2xTEA3718 an einem Mega8 und 1/8 Schritt waren nicht so
überzeugend. Oder hast Du vielleicht positive Erfahrungen mit
Dämpfungsgliedern auf der Motorachse gemacht?

Gruß Michael

von Norman Paasche (Gast)


Lesenswert?

Hallo Michael,

ich bin mit meinem Projekt auch noch am Anfang. Bei mir soll der
Antrieb später mal mit CAN-BUS (canOpen?) angesprochen werden.
Derzeit bin ich noch an dem Problem Rampe dran. Es läuft prinzipell
schon, aber ich muß den Code noch verifizieren und vorhandene Bugs
beheben. Schick mir Deine EMail an NormanPaasche@AOL.COM und ich
schick Dir mal den Teil Source von mir zu. Ich denke, Du kannst dann
die Frequenzberechnung sehen - also wie das mit der Rampe funktioniert.
Mein Mega128 läuft mit 16 MHz. Die oberste
Ausgabefrequenz (Drehzahl der Welle) beträgt etwa 6..7 kHz.

So denn guten Rutsch und verbrenn Dir nicht die Finger bei der
Knallerei...
 Norman

von Michael (Gast)


Lesenswert?

Hallo Norman,

vielen Dank für Dein Angebot, welches ich aber nicht annehmen werde.
Vielmehr würde ich es begrüßen, wenn Du Deine Informationen allen
Interessierten hier zur Verfügung stellen könntest. Dies ist Sinn und
Zweck dieses Forums.
Ebenfalls ein gutes Neues.

Michael

von Norman Paasche (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Michael,

prinzipiell hast Du recht, nur weis ich nicht, wie und in welcher
Form ich das hier unterbringen soll. Der Source für den ATmega allein
denke ich, ist vielleicht nicht so aussagekräftig. Es müßte wenigstens
ein Schaltplan mit dazu, um den Source zu verstehen.
Bei meiner Lösung geht es um einen Positionierantrieb, der mit
zwei Endlagenschaltern ausgestattet ist. Referenzrichtung gibt an,
welcher der Endlagenschalter als Referenzpunkt dient. Die zählweise
der Inkremente dreht sich dann entsprechend. Der Motor fährt
prinzipell eine Rampe. Dabei beschleunigt er von Vmin nach Vmax.
Bremsen geschieht analog. Wenn die Entfernung zu klein ist, so wird
noch vor erreichen von Vmax die Bremsrampe eingeleitet.
uc_motorstate = 0  Stillstand
              = 1  Beschleunigung incl. geradliniger Bewegung
              = 2  Bremsbeschleunigung
In der Datei Ports sind die Zugriffsfkt. auf den Schrittmotorsteuer-IC
IMT901 von www.nanotec.com zu finden.

Über die serielle Schnittstelle (9k6 8N1) werden die Befehle an den MC
geschickt. UART0.c/h liest alles ein. Der Protokollinterpreter
PROTO0.c/h erwartet ein Dollarzeichen als Start und ein Enter (0dh)
als Endekennung. Derartige Befehle werden dem Kommandointerpreter
KOMMAND0.c/h übergeben, welcher jetzt einzelne Werte oder den Start
des Motors initiert.
Zunächst erfolgt mit $REF[0x0D] die Referenzfahrt. Anschließend
kann mit $START5000[0x0D] auf die Position 5000 gefahren werden.

MfG
Norman

von Michael (Gast)


Lesenswert?

Hallo Norman,

vielen Dank für Deinen Dateianhang.
Im Programmierwald stehen viele Bäume, sodaß ich mich nur auf motor.c
ab Zeile 174ff konzentriert habe. Was ich erkenne ist eine lineare
Rampe mit ui_rampe. Den von Dir oben erwähnten I-Anteil erkenne ich
nicht. Ist der irgendwo zu finden ?
Beim Lesen der Istposition mit MOTOR_POSITION() kann ich nur raten, den
Timerinterrupt kurz zu deaktivieren; sonst sind böse Überraschungen zu
erwarten, wenn die long-Variable während des Auslesens per Interrupt
verändert wird.

Michael

von Norman (Gast)


Lesenswert?

Hallo Michael,

ich hatte vom Prinzipiellen geschrieben und meine Implementation
ist keinesfalls rund. Daher habe ich nur das Notwendigste meiner
Meinung nach programmiert. ui_rampe ist ein Wert, der aus meiner
Regelkonstante kp errechnet wird. Um eine sehr flache Rampe zu
fahren, muß kp klein sein. zB 1000. Durch die Berechnung wird jetzt
ui_Rampe bis ca. 100 groß. Dies bedeutet, es werden 100 Interrupt-
aufrufe gezählt, bis die Zeitkonstante geändert wird. Ist Kp ca. bei
24000, so ist ui_Rampe kleiner 10. Die Zeitkonstante ergibt sich
ebenfalls aus kp. Aus der Strecke für Beschleunigung (beide Seiten
der Rampe) ergibt sich der Deltabetrag des Anstiegs, um den ui_vist
erhöht wird. Siehe Motor_Drive() und letzter Teil des Interrupts.
Einen I-Anteil gibt es bei mir nicht. Es wäre vielleicht
überlegenswert, ob man eine Sinusförmige Rampenfunktion abbildet.
Derzeit teste ich an einem Model (Schlitten eines Nadeldruckers).
Nächste Woche habe ich dann voraussichtlich eine komplette Achse
mit Gewindespindel und Kugelumlaufmutter am Schlitten. Dann wird
sich zeigen, ob der Ansatz tauglich ist???
Die Fkt. Motor_Position() ändert nichts am Wert. Daher sollte das
lesen des Wertes unkritisch sein. Gut man kann eine Warteschleife
einbauen, die abwartet bis der Interruptaufruf vorbei ist, oder den
Wert im Interrupt duplizieren, auf den dann zurückgegriffen werden
kann.

Der Interrupt selbst ist etwas lang geworden, jedoch wollte ich das
die MAIN-While-Schleife weiterläuft und gegebenenfalls auf Nachrichten
reagieren kann.

Falls Du noch ein paar Ideen hast, würde ich mich freuen. Ansonsten
bau ich gerade die CAN-Bus-Anbindung für den ATMega.


Mfg Norman

von Stefan Wahoff (Gast)


Lesenswert?

Hi sorry wenn ich ein wenig von dem Thema abweiche, aber ich denke es
passt vielleicht ganz gut. Ich will in meinem Rechner eine schublade
rausfahren lassen und kippen lassen, ähnlich wie z.b mit einem LCD hier
: http://www.nef.wh.uni-dortmund.de/~wahoff/modding/lcd-finish.gif

Ich brauch also 2 motoren. erst muss M1 rausfahren danach M2 kippen
und danach M1 wieder kurz zurückfahren.
Bin mittlerweile soweit gekommen, das man das wohl ganz gut mit einem
AVR AT90S4433 und einem L293D regeln kann. Gibt es da vielleicht ein
Programm wo ich nur die werte ändern muss, wie lange sich die motoren
drehen und das ich dan auf den avr spiele? Bzw. was für einen motor
sollte ich dafür nehmen?
wie gesagt hab da nicht soviel Ahnung von und fang grad erst an mich in
das Thema einzulesen.

Würd mich über Hilfe freuen

von Michael Baldischweiler (Gast)


Lesenswert?

Hi,

wir haben in der alten Firma den IMT900 und dann denn IMT901
eingesetzt. Der 1/8-Schritt-Betrieb funktioniert nicht mit
Linear-Motoren !! Der Vorteil beim IMT901 liegt darin, dass er auch mit
Schrittmotoren bei einer Betriebsspannung von 12V arbeitet. Viele
Applikationen haben Probleme, wenn extra eine 24V Versorgung benötigt
wird. Wir hatten bei der Eigenresonanz nie Problem, haben passende
Start-/Stop-Rampen geschrieben, die diese Frequenz übersprungen haben.

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
Noch kein Account? Hier anmelden.