ich habe ein problem.
ich kann keinen timer interrupt liniar schneller ablaufen lassen.
weil wenn ich die nächsten timer interrupt berechne,wird dieser
interupt das nexte mal ja immer schneller durchlaufen (ein bisschen
bewusst berechnet) nur das diese beschleunigung dann zum quadrat erfolg
.
wie muss man dann diese sachen kompensieren.
http://www.mikrocontroller.net/articles/Schrittmotoren
hier ist die lösung beschrieben unter
Häufigster Fehler der letzte satz
denn ich leider nicht ganz verstehe
Da hast Du Glück, ich bin der Autor des Abschnittes.
Mehrere Lösungsmöglichkeiten hab ich bisher erfolgreich implementiert.
1.
Die einfachste: eine Tabelle mit den Timerwerten. Zum Beschleunigen /
Abbremsen nehme ich bei jedem Schritt den nächsten / vorangegangenen
Wert. Bei erreichter Geschwindigkeit bleibe ich beim aktuellen Wert.
Die Tabelle habe ich mit einem einfachen Pascal-Programm berechnet und
als Array eingetragen.
Vorteil: man kann auch andere Kurven (wie im Wiki-Artikel beschrieben
z.B. s, sin oder sonstwie) verwirklichen.
Nachteil: die Tabelle ist starr, möchte man eine andere Beschleunigung,
muss der Controller neu programmiert werden.
2.
Die Berechnung kann man aber leicht den µC durchführen lassen.
Für die lineare Beschleunigung sieht das so aus:
freq = startfreq + vergangene Zeit * Steigung
der Timerwert ist dann xtalfrequ / freq.
Zur Berechnung der vergangenen Zeit addiere ich die bisherigen
Timerwerte auf.
3. Es gibt eine weitere Vereinfachung dieser Formel, hab ich gerade
nicht parat. Ich meine, es war ein prozentuales Decrementieren des
Timerwertes.
Wenn man die Rampe in mehrere Abschnitte unterteilt, bekommt man eine
Profilsteuerung. Die mache ich einfach so, dass ich eine weitere
Tabelle mit ca. 8-32 Einträgen habe, in der steht einfach, bei welcher
Schrittnummer er auf welche Steigung umschalten soll.
Zum Programm im Anhang, ist eine frühe Pascal-Version, ein geübter
C-Programmierer erkennt sofort, was gemeint ist.
Die Variablen: f0 Startfreq, fm Maximalfrequenz, fx Quarzfrequenz
(Timerfrequenz), t aktuelle Zeit seit Start in Timertics, tm Dauer der
Rampe in Timertics, i Schrittnummer, d delaytime (Timerwert, für AVR
65536-d verwenden), dm delay merk, d-dm delaytime-Änderung.
Ich berechne gleich die Steigung, indem ich die gewünschte Dauer der
Rampe mit angebe.
der Kern ist:
f:=f0+(fm-f0)*(t/tm);
d:=round(fx/f);
inc(t,d);
Bei meinem 80C166-Controller berechne ich die Rampen unmittelbar vor dem
Start, da ich Start-/Stop-Geschwindigkeit, Beschleunigung, usw. als
Parameter verändern kann. Außerdem dürfen es ja nicht mehr
Tabellenwerte werden, wie Schritte von der Anfangs- bis zur Endposition
gemacht werden sollen, die Höchstgeschwindigkeit somit auch nie erreicht
werden kann.
Da so eine Tabelle runde 16kByte RAM benötigt, gibt es beim PIC und
vermutlich auch beim AVR arge Platzprobleme.
Wen trotzdem mein Assembler-Quellcode für 80C166 interessiert:
http://www.domnick-elektronik.de/download.htm
(SMOST = Schritt-MOtor-STeuerung).
Danke euch beiden für diese beiden Beiträgen.
Der erste war aber für mich optimal.
Die rampenberechnung steigent hab ich bereits in den microcontroller
hineinprogrammiert aber, irgentwie bekomme ich daraus die abfahrrampe
nicht gepacken.zwar bekomme ich wärte ähnlich,aber nicht die gleichen
absteigent deshalb wolte ich fragen ob profi auch die berechnung für
die abwärtsrampe hätte .danke
Welche Variante hast Du implementiert, die mit der Tabelle oder die mit
der online- (=onstep)-Berechnung?
Rechnest du mit Integer oder mit Float?
Kannst ja mal Deinen Code hier anhängen, dann kann ich Dir gezielter
helfen.
Ist es so tragisch, dass er minimal andere Frequenzen beim Bremsen
verwendet? Wichtig ist doch, dass die Schrittzahl am Ende stimmt.
1-ich habe nicht die variante mit den listen gemacht sondern direkt in
den microcontroller programmiert.
Ich habe den timer auschnitt upgeloadet,dort ist aber nur eine
beschleunigungsrampe programiert sonst nix.
ich bräuchte diese berechnung sozusagen nur noch Hinterwerts,
die abfahrrampe habe ich in vb6 in listboxen getestet und das
Problem gehabt das mehr als angegeben taktfrequenzen ausgegeben wurden
als bei der beschleunigungsrampe.Die frequenzen müssen eigentlich nicht
ganz genau stimmen nur die anzahl.
Noch eine frage wie geht es am leichtesten eine 1-cos(pi-3pi) rampe
uber die lineare drüberzulegen
das ginge schon aber diese werte werden realtime berechnet und nicht
zwischengespeicher,ich könnte sie zwar zwischenspeichern in einem array
aber das nimmt mir bei 2k ram zu viel platz ein zB (500werte a integer
1k ram) man müsste das nur rückwerts berechnen lassen.
Zuerst bist Du dran: Integer / Float-Berechnung??
Code posten
?
Hast Du statt des inc(t,d) schonmal dec(t,d) versucht?
Als Abbruchkriterium würde ich auch nicht die vergangene Zeit, sondern
die Anzahl der Schritte verwenden.
mein konkretes broblem ist das ich bei der beschleunigungsrampe genau
500 frequenzwerte habe die natürlich immer größer werden.
aber ich müsste auch die abbremsrampe gleich berechnen mit den gleichen
ausgangswerten dort kommen aber nicht genau 500 frequenzen raus die
abwärts laufen.mein problem ist also das ich nicht weis wie man diese
berechnung umstellt.
den code habe ich oben im timer.txt angegeben aber nur für die
beschleunigungsrampe.Das mit dem abbruchkriterium müsste gehen ich
dachte nur ich hätte es immer falsch gemacht,und profi hätte diese
abfahrampe gleich wie die beschleunigungsrampe schon geschrieben,dann
dachte ich ich frage nochmals nach.
Vorsicht, durch Zurück-Button oder aus einem anderen Grund postest Du
immer zweimal.
Ich habe es Dir doch gerade geschrieben:
- Beende nach der richtigen Anzahl der Schritte
- verwende statt inc(t,d) einen dec(t,d) (Pascalform von t-=d; )
Ah, Du proggst mit Basic: Tactual = Tactual - Ddelay
Der Rest der Formel bleibt gleich.
Oder Du stellst die erste Zeile um:
t:=0;
f:=fm-(fm-f0)*(t/tm);
d:=round(fx/f);
inc(t,d);
In C würde ich aus PerformanceGründen das alles in eine Zeile
schreiben:
fd=fm-f0;t=0; (nur einmal vor der Schleife)
t+=d=fx/(fm-fd*t/tm);
timer=-d; (oder =65535-d; weiß ich gerade nicht)
Bei der Formel "1-cos(pi-3pi)" würde ich eine Tabelle verwenden.
Du kannst sie entweder kürzer machen (wer braucht schon 500 Schritte
zum Beschleunigen von 4 auf 300 Hz? Meine oben gepostete Ramp3.txt geht
linear von 250 bis 9600 Hz bei 7372800Hz Timer in 660 Schritten).
Oder Tabelle komprimieren (z.B. nur die Unterschiede zum vorhergehenden
Wert als Byte. Das begrenzt zwar die Steigung, aber nur in den ersten
paar Schritten). Mit einem ADPCM-KomprimierungsCode könnte man auch das
umgehen. Aber für den brauchst Dua auch wieder eine Tabelle.....
Ich habe mal nachgeschaut, die Cos-Beschleunigungskurve kann man mit
einer Integer-Funktion nachbilden, aber das habe ich noch nicht
gecoded, sondern nur mal in Excel simuliert.
hallo dieser teil geht bei mir nicht gerade brobiert mit dem in anhang
vb6 program
Oder Du stellst die erste Zeile um:
t:=0;
f:=fm-(fm-f0)*(t/tm);
d:=round(fx/f);
inc(t,d);
ok danke mein broblem sollte gelöst sein,die werte sind jetzt halbwegs
in ordnung
das mit dem inc und so verwende ich nicht oft deshalb habs ich
übersehen danke.
Profi schrieb:> Wenn man die Rampe in mehrere Abschnitte unterteilt, bekommt man eine> Profilsteuerung. Die mache ich einfach so, dass ich eine weitere> Tabelle mit ca. 8-32 Einträgen habe, in der steht einfach, bei welcher> Schrittnummer er auf welche Steigung umschalten soll.
Ich weiß das der Beitrag sehr alt ist, aber er passt trotzdem wie die
Faust aufs Auge.
Ich bin derzeit dabei Rampen für Schrittmotoren zu implementieren.
Lineare habe ich dabei erfolgreich Realisiert. Ich verwende hierzu denn
folgenden Algorithmus:
http://www.embedded.com/columns/technicalinsights/56800129?_requestid=56271
Zur Realisierung anderer Rampen verwende ich nun die Näherung durch
lineare Teilstücke. Das Umschalten der Beschleunigung findet bei
bestimmten Geschwindigkeiten statt. Diese Geschwindigkeiten sind in
einer Tabelle abgelegt.
Ich habe nun das Problem das meine Downramp zu schnell abbremst.
Die Frage ist nun: hat jmd. schon diesen Algorithmus verwendet und damit
Erfolgreich S-Förmige Rampen Realisiert?
Bzw. steht das Programm mit dem Umschalten bei bestimmten Schrittzahlen
irgendwo zur Verfügung?
Hi - ich bin da derzeit dran so nen Rampengenerator zu programmieren,
aber ich bin bissi ausgeschert weil ich ne Idee zu Webserver hatte.
Ehrlich gesagt hat mich die Umsetzung auch bissi genervt, weil die
Festpunkt-Berechnung ein ziemliches "Gewerch" ist.
Es gibt zu diesem Thema eine Application-Note von ATMEL und einen
Beispiel-Code - der aber - mir - nicht wirklich Gefallen hat. Auch lief
er bei mir nicht sauber... Das war dann auch der Grund warum ich mich
hingesetzt habe und das Ganze mal von Grund auf aufgerollt habe -> siehe
anghängtes PDF.
Wenn ich es fertig habe - stelle ich es hier rein.
Gruss,
Gary
Student schrieb:> Die Frage ist nun: hat jmd. schon diesen Algorithmus verwendet und damit> Erfolgreich S-Förmige Rampen Realisiert?
Dazu musst du bei besagten Alghorithmus nur die eingestellte
Beschleunigung rampenförmig auf deine Soll-Beschleunigung erhöhen. Das
heist du fängst mit einer kleinen Beschleunigung an und über dein
"Verrundungszeit" ziehst du die Beschleunigung linear hoch.
Das Prinzip habe ich verstanden. Es liegt eine Tabelle im RAM die für
bestimmte Schrittzahlen die jeweilige Beschleunigung enthält. Für eine
S-Förmige Rampe würden die Beschleunigungswerte einen Dreieckförmigen
Verlauf ergeben.
Das ganze funktioniert bei mir soweit auch. Nur kommt es vor das bei
bestimmten Parametersätzen (bestehend aus Max_Geschwindigkeit,
Max_Beschleunigung und Schrittzahl) die Endgeschwindigkeit nicht der
Maximalgeschwindigkeit entspricht.
Ein Fehler aufgrund von Rechenungenauigkeiten ist auszuschließen, da ich
in Excel dasselbe Problem habe. Zur Veranschaulichung mal zwei
angehängte PDF's. Einmal wo es übereinstimmt und einmal wo es einen
Fehler gibt.
Ich gehe davon aus das ich einen Fehler in den Umschaltpunkten, also in
den Schrittzahlen habe. Daher meine Frage nach dem Code von Profi. Ich
würde mir gerne mal ansehen ob seine Umschaltpunkte ungefähr gleich sind
wie meine und ich somit einen Fehler im Algorithmus habe. Oder ob meine
Umschaltpunkte Quark sind.
Hi - also was ich sehe ist das du nur bei der verrundeten Rampe nicht
die Endgeschwindigkeit erreichst. Da wo es richtig läuft fährst du auch
ein viel kürzere Strecke und es wird weniger lang verrundet.
Damit interpretiere ich erst einmal das du einen Fehler hast der von der
Dauer der Verrundung abhängt. Wie machst du den deine Umschaltung?
Bestimmst du sie evtl. noch anhand einer konstanten Beschleunigung ohne
den Verundungsbereich?
Wenn du auf die Seiten von Atmel schaust da gibt es den von dir
gesuchten Beispielcode.
Gruss,
Gary
PS: Sind deine Charts "Laufzeit"-Daten?
gerry schrieb:> eine 1-cos(pi-3pi) rampe
1 - cos(pi - 3*pi) = 1 - cos(-2pi) = 1 - cos(0) = 0
pi oder phi? oder was? SCNR
Wie wäre es denn die Cosinus-Funktion mit Parabelstücken anzunähern?
Der \0
G. B. schrieb:> Hi - also was ich sehe ist das du nur bei der verrundeten Rampe nicht> die Endgeschwindigkeit erreichst. Da wo es richtig läuft fährst du auch> ein viel kürzere Strecke und es wird weniger lang verrundet.> Damit interpretiere ich erst einmal das du einen Fehler hast der von der> Dauer der Verrundung abhängt. Wie machst du den deine Umschaltung?>> Bestimmst du sie evtl. noch anhand einer konstanten Beschleunigung ohne> den Verundungsbereich?
Also meine Umschaltpunkte sind wie vorher schon gesagt an der
durchzuführenden Schrittzahl Orientiert.
S_Target entspricht dabei der gesamten durchzuführenden Schrittzahl.
Ermittelt habe ich diese nach folgendem vorgehen:
- Die Dreieckförmige Beschleunigung in 9 Abschnitte aufgeteilt.
- Die bis zum erreichen dieses Abschnittes erreichte Strecke über
Integration ermittelt.
- Für die Beschleunigungswerte wurden ebenfalls Werte ermittelt mit
denen in derselben zeit dieselbe Strecke durchfahren wird.
Dabei habe ich folgende Annahme getroffen (hier liegt glaube ich auch
das Problem): Beim erreichen der Zielgeschwindigkeit wurde S_Target/2
zurückgelegt. Wenn es aber abschnitte mit konstanter Geschwindigkeit
gibt stimmt dies ja nicht. Ich ging nun aber davon aus das dies den
Algorithmus nicht stört.
>> Wenn du auf die Seiten von Atmel schaust da gibt es den von dir> gesuchten Beispielcode.>> Gruss,> Gary>> PS: Sind deine Charts "Laufzeit"-Daten?
Dieser Beispielcode realisiert nur Lineare Rampen, und diese sind ja
kein Problem.
Die Charts wurden mit Excel erstellt und verwenden denselben Algorithmus
wie er auch im Controller realisiert ist.
Student schrieb:> Dieser Beispielcode realisiert nur Lineare Rampen, und diese sind ja> kein Problem.
Der Code arbeitet mit konstanter Beschleunigung für deine Variante musst
du die Beschleunigung varieren - gemäß dem Dreisatz aus der Herleitung
ergibt erreichst du das über das Verstellen des Schrittzählers.
Student schrieb:> Beim erreichen der Zielgeschwindigkeit wurde S_Target/2> zurückgelegt. Wenn es aber abschnitte mit konstanter Geschwindigkeit> gibt stimmt dies ja nicht. Ich ging nun aber davon aus das dies den> Algorithmus nicht stört.
Also möchtest du das deine Verrundung sich immer so ergibt das du bei
S_Target/2 deine max.Geschwindigkeit erreichst? Das passt dann aber gar
nicht mit deinen Graphen zusammen? Verstehe dich jetzt nicht!
Ich probiere es einmal anders herum, wenn du eine konstante Verrundungs-
zeit Tv vorgibst so ergibt sich die Dauer der Beschleunigung zu
Ta= Vmax/Amax + Tv,
Willst du den Zeitpunkt deiner Umschaltung in Schritten wissen, dann
bestimmt sich das für die Verrundungsphase - hoffe ich - wie folgt:
Dein Drehwinkel bei konstanter Winkelbeschleunigung beträgt
phi=0.5*alpha*t² ; wobei wir t=Tv einsetzen
aber alpha = ruck * t -> ruck gleich Ableitung der Winkelbeschleunigung
damit ergibt sich
phi = 0.5 ruck t³ = n * beta ; beta = Schrittwinkel deines Motors.
also hast du deinen Umschaltpunkt nach n-Schritten:
n = (0.5 ruck Tv³)/beta.
Für die konstant beschleunigte Phase kennst es ja.
Wenn du nun deine Verrundungszeit an der Strecke fest machen willst,
dann musst du halt Tv entsprechend dem Profil berechnen. Ist ja aber
auch nicht schwer.
Tges = 2*n*beta/V_max - wobei n = Schritte die du fahren willst
-> Tv = Tges/4
Nähern wir uns an?
Bin mal gespannt wie es jetzt weiter geht, auf jeden Fall möchte ich den
Code dann von dir haben, weil ich wie gesagt im Moment "zu faul" bin für
das Thema.
Gruss,
Gary
G. B. schrieb:> Tges = 2*n*beta/V_max - wobei n = Schritte die du fahren willst> -> Tv = Tges/4
Sorry der letzte Teil war zu schnell geschossen, den dein V_max ergibt
sich natürlich aus deiner max. erlaubten Beschleunigung.
Student schrieb:> Das ganze funktioniert bei mir soweit auch. Nur kommt es vor das bei> bestimmten Parametersätzen (bestehend aus Max_Geschwindigkeit,> Max_Beschleunigung und Schrittzahl) die Endgeschwindigkeit nicht der> Maximalgeschwindigkeit entspricht.
Das die Endgeschwindigkeit nicht erreicht wird liegt ja vielleicht auch
daran das du gar nicht lange genug mit Max_Beschleunigung fahren
kannst.
Da dein Weg viel zu kurz ist.
G. B. schrieb:> Also möchtest du das deine Verrundung sich immer so ergibt das du bei> S_Target/2 deine max.Geschwindigkeit erreichst? Das passt dann aber gar> nicht mit deinen Graphen zusammen? Verstehe dich jetzt nicht!
Es ist so gemeint:
Ich habe die Umschaltpunkte für die Beschleunigung (und damit die
Zeitpunkte zur Neuberechnung des Zählers) unter folgender Vorraussetzung
berechnet:
- nach S_Target/2 ist V_Target erreicht (Danach begint Bremsen wobei
wieder S_Target/2 zurückgelegt wird)
- V_Target darf dabei V_Max nicht überschreiten
Der Geschwindigkeitsverlauf wird nun eine Sinoide Form annehmen, ohne
Zeitabschnitte in denen die Geschwindigkeit konstant bleibt
Kurzes Beispiel: Ich möchte 3000 Schritte zurücklegen und habe dabei
folgende Parameter:
A_MAX = 300
V_MAX = 1500
Die Umschaltpunkte ergeben sich nun wie folgt:
S1 = 3
S2 = 22
S3 = 74
S4 = 176
S5 = 342
S6 = 574
S7 = 855
S8 = 1169
Als Beschleunigungswerte erhalte ich:
a1 = 60
a2 = 120
a3 = 180
a4 = 240
a5 = 300
a6 = 240
a7 = 180
a8 = 120
a9 = 60
Ich erhalte dabei den angehängten Graph. Dabei bleibt V_Target kleiner
als V_Max.
Wenn nun aber der Fall eintritt das V_target > V_Max habe ich ein
Problem. Hierfür wolte ich die Rampe nun beschrenken das sie bei V_Max
ihr Ende findet.
Für die Lösung galten dabei folgende Vorraussetzungen:
- So schnell wie möglich auf V_Max fahren (Beschleunigung darf nicht
verkleinert werden)
- Wenn V_Max erreicht fahre mit V_Max weiter bis Bremspunkt erreicht.
- Ab Bremspunkt Geschwindigkeit verringern (Dieselbe Rampe nur mit
negativer Beschleunigung)
Da ich die Beschleunigung nicht verkleinern wollte habe ich die Schritte
die er pro Beschleunigungsabschnitt hat verringert. Dadurch Beschleunigt
er nicht mehr so lange wie vorher und erreicht somit eine kleinere
Geschwindigkeit. Der Schlüssel liegt nun darin herauszufinden wieviele
Gesamtschritte er benötigt um V_Max zu erreichen. Diese neue Schrittzahl
nenne ich bsw. S_RAMP.
Die Umschaltpunkte bleiben dieselben wie im vorherigen Post (Man ersetze
S_Target nur durch S_Ramp).
Wenn man V_Max auf 1000 setzt würde sich der Graph_2 ergeben. Es sind
also insgesamt 2500 Schritte (1250 Schritte während der Beschleunigung
und 1250 Schritte während der Bremsung) nötig. Um nun trotzdem 3000
Schritte zu fahren müsste man in der mitte 500 Schritte mit V_Max
fahren. Das ist ja kein Problem.
Man erkennt also das man durch verkleinern der zu fahrenden Strecke
V_Target anpassen kann.
Mein Problem liegt nun in der Berechnung von S_Ramp um eben dies zu
erreichen.
Meine bisherige Berechnung für S_Ramp lautet wie folgt:
Dieselbe Strecke wird durch eine Lineare Rampe zurückgelegt die mit der
S-Förmigen Ranmpe zwei Schnittpunkte hat. Nämlich bei V_Target/2 und
V_Target. Die Beschleunigung für diese Lineare Rampe ergibt sich aus dem
Mittelwert der Dreieckförmigen Rampe
Leider kommt dabei nicht das korrekte heraus. Und genau da ist mein
Problem.
Sollte ich vl. diese Gleichung über einen korrekturfaktor anpassen? Denn
eigentlich würde ich schon die richtige Gleichung verwenden wollen. Oder
wird es doch besser wenn ich die Beschleunigung verkleinere?
>Ich probiere es einmal anders herum, wenn du eine konstante Verrundungs->zeit Tv vorgibst so ergibt sich die Dauer der Beschleunigung zu
Das würde ich aus folgendem Grund nicht machen: Wenn ich die
Verrundungszeit klein wähle um auch bei geringen Beschleunigungszeiten
(Bedingt durch hohe Beschleunigung und niedrige Zielgeschwindigkeit)
eine gute Form zu erhalten habe ich ein Problem bei langen
Beschleunigugnszeiten. Hier wird die Verrundung wieder zu klein.
Umgekehrt wird die Verrundungszeit ggf. größer als die
Beschleunigungszeit
Ich werde mir das ganze nochmal genauer anschauen und dann meine
Ergebnisse hier Posten (wahrscheinlich keinen Quellcode da dies ja sehr
Controlerspezifisch ist). Aber als Pseudocode mit den wichtigsten
Formeln.
Profi schrieb:> Da hast Du Glück, ich bin der Autor des Abschnittes.
Hast du/irgendwer die ausfuehrliche Dokumentation, die im Artikel
"Schrittmotoren/2.3 Beschleunigungsrampen richtig wählen und berechnen"
empfohlen wird vielleicht noch irgendwo gespeichert, wuerde mich sehr
interessieren.... aber die Links sind leider tot...
Schoene Gruesse