Liebe Kompetenzhorde,
Ich will eine Schrittmotor in Echtzeit die Bewegung eines Objekts
nachvollziehen lassen.
Das Objekt wird über einen Sensor getrackt, der über i2c die x und y
Koordinaten an einen ATMEGA 328 sendet.
nun soll dieser atmega zwei Schrittmotoren steuern, abhängig von den x
und y Koordinaten des Objekts.
leider weiß ich einfach nicht wie ich das am besten programmieren soll,
ohne das es zeitliche Probleme gibt.
ich habe schon einiges probiert, aber nichts läuft präzise.
Sind da Interrupts sinnvoll? wenn ja, kann mir einer erklären wie das
ungefähr mit Interrupts geht?
Um Anlauframpen mache ich mir keine Sorgen, da das Objekt so träge ist,
dass der Schrittmotor keine zu großen Beschleunigungen machen muss.
Was für eine Schrittmotortreiber/Controller hast/möchtest du einsetzen.
Davon hängt viel bei der Programmierung ab. Welche Ströme brauchen deine
Motoren.
andrea schrieb:> Um Anlauframpen mache ich mir keine Sorgen, da das Objekt so träge ist,
Gerade wenn du ein träges Objekt (=träge Masse) hast, brauchst du die
Rampen. Das führt allerding zu Problemen, wenn du beim Einleiten eines
Bremsvorgangs nicht weißt, wo du anhalten möchtest.
Falls du mit "träge" mein, dass sich das Objekt nur langsam bewegt,
sieht die Sache allerdings einfach aus. "Langsam" wäre dann
Einzelschrittbetrieb vom Motor.
Wenn Du ohne Rampen arbeiten willst (was mit einem guten Treiber / Motor
bis ca. 1 kHz Halbschrittfrequenz gut geht):
StepTimerIRQ:
if(xIstPos < xSollPos){xStepDir=R;xStepClk=0;}
else
if(xIstPos > xSollPos){xStepDir=L;xStepClk=0;}
if(yIstPos < YsollPos){YstepDir=R;yStepClk=0;}
else
if(yIstPos > YsollPos){YstepDir=L;yStepClk=0;}
delay_us(10); //wenn die StepClk-Puls-Breite zu gering ist
XstepClk=1;YstepClk=1;
Ich mache das mit linearen Rampen und einem DDS-Positionssteller:
if((xDist=xSollPos-xIstPos)>0){xSollSpeed= xSpeedMax;}
else
if( xDist <0){xSollSpeed=-xSpeedMax;}
else xSollSpeed=0;
if(xIstSpeed < xSollSpeed){xIstAccel = xAccelMax;}
else
if(xIstSpeed > xSollSpeed){xIstAccel =-xAccelMax;}
else xIstAccel = 0;
xIstPos+=xIstSpeed+=xIstAccel;
Ist eine einfache Form, die ein Überschwingen produziert. Deshalb muss
die Speed proportional zur Dist heruntergedreht werden, aber das
überlasse ich Dir.
eProfi schrieb:> Wenn Du ohne Rampen arbeiten willst (was mit einem guten Treiber / Motor> bis ca. 1 kHz Halbschrittfrequenz gut geht):
Das kannst du nicht so allgemein sagen, da das von der Dimensionierung
des gesamten Antriebs abhängt. Wie hoch liegt dabei dein Drehmoment auf
Grund von Massenträgheiten im Vergleich zum Haltemoment des Motors?
Vielen dank erst mal für die Antworten!
Michael A. schrieb:> Was für eine Schrittmotortreiber/Controller hast/möchtest du einsetzen.> Davon hängt viel bei der Programmierung ab. Welche Ströme brauchen deine> Motoren.
ich habe da sowas hier:
http://www.sorotec.de/shop/product_info.php/info/p962_m542-schrittmotorkarte-leadshine.htmlMichael A. schrieb:> Gerade wenn du ein träges Objekt (=träge Masse) hast, brauchst du die> Rampen.
nicht das Objekt was bewegt werden soll ist träge sondern das Objekt was
getrackt wird.
Die Wege die der Motor fahren soll sind also von Natur aus Schrittmotor
freundlich.
das Objekt wird aber auch "schnell". das heißt es sind oft mehrere
schritte pro Hauptprogrammdurchlauf notwendig. Die Hauptprogrammschleife
wird dadurch langsam, das die Werte vom i2c Sensor ausgelesen werden
müssen
eProfi schrieb:> Wenn Du ohne Rampen arbeiten willst (was mit einem guten Treiber / Motor> bis ca. 1 kHz Halbschrittfrequenz gut geht):
Sehe ich das richtig, das in deinem Programm der Motor nicht direkt
gepulst wird sondern nur die soll-Position ermittelt wird?
Ich muss meine Treiber mit einem HIGH / LOW pro schritt füttern und das
ist mein Hauptproblem. Die Position des Motors, wird ja permanent durch
den Sensor vorgegeben.
Wie soll ich so schnell Pulsen und gleichzeitig den Rest erledigen, den
das Programm machen muss???
Die Motoren sind gut dimensioniert für das was sie beschleunigen müssen.
Hier liegt nicht mein Problem!
Die Erzeugung der Schritte würde ich vollständig im Timer Interrupt
erledigen, d.h. in der Hauptschleife legst du nur die Richtung fest und
welche Dauer der/die nächsten Schritte haben sollen. Ein PI-Regler für
jeden Motor, der in der Hauptschleife aktualisiert wird, ist
wahrscheinlich die einfachst Lösung dafür. Der Timer kümmert sich dann
um den korrekten Zeitablauf.
Ich hätte gesagt, du liest die aktuelle Position aus, berechnest, wo du
hinmusst und "fährst" in die Richtung. Und das wiederholst du, bis du da
bist.
Die Frage ist, wie schnell ist deine I2C Verbindung? Wenn du die bis
oben hin ausreizt, kannst du ja eventuell am Anfang vom Schritt den
Ausgang halt auf High setzen, die I²C Abfrage machen und danach wieder
auf Low gehen, dann machst du in der Low-Pause die Berechnung und so
weiter. 400khz I2C sind für 30bits ~ 3 byte (z.b. Adresse, Befehl,
Antwort) knapp 75 µs. Wenn du dein Motor mit 1khz taktest, sind das
500µs High und 500 Low. Also sollte das gehen, solange der Sensor die
400khz mit macht.
Dazu kommt ja noch, dass du ja theoretisch nicht jede Millisekunde die
Position brauchst.
edit: Wie bekommst du denn die Position deiner beiden Motoren? Bedenke,
das manchmal Schritte "verschluckt" werden können, wenn der Motor durch
irgendwas aufgehalten bzw behindert wird. Da geht reines Zählen nicht so
gut.
Im Prinzip macht jede CNC-Software so was.
Viel einfacher als mit Schrittmotoren und AVR wäre es aber gewesen,
wenn ihr die Position des Originalobjekts mit einfachen Potis
erfasst hättet, z.B. Linearpotis, und Servokontroller-ICs an
Gleichstrom(getreibe)motoren einsetzen würdet.
TLE4206 und TDA3629 geht bis 0.8A, MC33030 bis 1A, DRV590/591/593/594
bis 3A per PWM.
Die machen genau das: Nachführung.
Und wenn man das nun unbedingt mit Inkrementalgeber und Schrittmotoren
nachbauen muß: Der Analog-IC zeigt wie man's rechnet.
Die Software passt, wenn man's richtig programmiert, egal ob C oder
Assembler, übrigens auf 1 Bildschirmseite und kommt ohne Interrupts aus,
profitiert aber wenn sie einn Zeitgeber abfragen kann (sonst muß sie
halt so geschrieben werden daß jeder Schleifendurchlauf gleich lange
dauert damit er als Zeitmasstab herangezogen werden kann). Wichtig ist
daß man nicht nur an langsames Beschleunigen denkt, sondern auch ans
Abbremsen vor dem Ziel.
> Sehe ich das richtig, das in deinem Programm der Motor nicht> direkt gepulst wird sondern nur die soll-Position ermittelt wird?
Nein. Es werden Schrittimpulse (StepClk) generiert, die die Endstufe
versteht. Es wird nur dann ein StepClk generiert, wenn die SollPos noch
nicht erreicht ist.
Das Berechnen der sollPos geschieht im Main völlig unabhängig vom
StepIrq (der soll mit einer Frequenz laufen, die der höchsten
Geschwindigkeit entspricht).
Würde Dir aber dringend einen Regel-Algo empfehlen, da sonst die
Bewegung sehr ruckartig vonstatten geht.
eProfi schrieb:> Würde Dir aber dringend einen Regel-Algo empfehlen, da sonst die> Bewegung sehr ruckartig vonstatten geht
Darum ja:
Michael A. schrieb:> ... Ein PI-Regler für jeden Motor, der in der Hauptschleife> aktualisiert wird, ist wahrscheinlich die einfachst Lösung dafür.
Michael A. schrieb:> Ein PI-Regler für jeden Motor
Sicher, dass das so gut ist? Das zu reglende System ist ja seinerseits
auch ein I-System, da grob gesagt die Geschwindigkeit des Ritzels am
Motor integriert die Position ergibt. Aber danke für die schöne
Regelungstechnik-Aufgabe, Prüfung hab ich in nem Monat :) mfg mf
PS: Eine PT-2-Charakteristik des Gesamtsystems mit entprechender
Dämpfung wäre doch hier gut, dann gibts garantiert keine Überschwinger
und der Motor läuft auch sanft an.
>Ist eine einfache Form, die ein Überschwingen produziert. Deshalb muss>die Speed proportional zur Dist heruntergedreht werden, aber das>überlasse ich Dir.
Genau so wie eProfi schrieb hab ich das auch gemacht dadurch ist ein
Überschwingen unmöglich. Man kann auch andere Reglertypen nehmen jedoch
schwingen die meißten erst einmal kurz übers Ziehl hinaus bzw. da die
Gesammtfahrstrecke nicht bekannt ist und auch die Beschleunigung und
Geschwindigkeit des zu trackenden Objekts sich ständig ändert ist es
schon etwas schwerer ein ideales Regelsystem zu finden. Wenn dann auch
noch kein Überschwingen erlaubt ist hat sich dieses System als einziges
bei mir bewährt
> Genau so wie eProfi schrieb hab ich das auch gemacht> dadurch ist ein Überschwingen unmöglich.
Unsinn. Während der Motor bremst kann die Sollposition dem
entgegenkommen, und dann darf man nicht noch schneller
bremsen sondern MUSS überschwingen.
Wenn dein Programm damit nicht zurecht kommt, taugt es nichts.
hallo
vielen dank für die vielen antworten!
ich setzt mich dann nach her mal rann und probier verschiedene
vorschlege aus.
Was ich nach wie vor gerne wissen würde, ist wie man das mit
timer-Interrupts macht.
hat da jemand ein beispiel code?
momentan frage ich alle 0.1 sekunden die i2c daten ab und setze dann
einen speed, der bis zur nächsten abfrage gehalten wird.
das mach ich mit einer Timer Abfrage, aber leider gehen so immer shritte
verloren, die ich mit zaehle und dann nach hohle. so stimmt die position
immer, aber die bewegungen sind ziemlich ungleichmessig.
deshalb will ich mit Interrupts arbeiten, damit da nichts übersprungen
werden kann, aber wie?
habes es jetzt gut am laufen
jeder Motor hat einen eigenen Timer Interrupt für den speed, der alle
0.01 Sekunden ermittelt wird.
es ist ziemlich verblüffend wie gut der Schrittmotor z.b. eine
Handbewegung live ohne Verzögerung nach machen kann.
vielen dank für die Beiträge!
Schön für Dich, wenn es nach Deinen Vorstellungen klappt. Nur: das Forum
klappt so nicht, denn es lebt vom Nehmen und Geben. Wäre also schön,
Deinen Code hier zu finden.
> Überschwingerer treten natürlich in MaWins Fall auf.
Und das ist gut so denn sonst wäre der Code ja auch falsch.
Er sieht durch die defines die auf physikalischen Grunddaten aufsetzen
auch sehr sauber aus.
Man kann sqrt auch im Integerbereich ausrechnen.
http://home.utah.edu/~nahaj/factoring/isqrt.c.html
MaWin schrieb:> Er sieht durch die defines die auf physikalischen Grunddaten aufsetzen> auch sehr sauber aus.
Danke für die Blumen ;)
Im Anhang mal Bilder von Simulationen mit dem Regler.
bild1: Ziel bewegt sich mit konstanter Geschwindigkeit
bild2: Ausschnitt aus Bild 1, Motor erreicht Ziel
Ruck2: Regler folgt einer Ruckbegrenzten Trajektorie