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
Kannst Du die Tabelle mit der Aufwärts-Rampe nicht zum Abbremsen rückwärts auslesen; was anderes mache ich mit meinen Tabellen auch nicht ?
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.
Was ist denn jetzt noch Dein konkretes Problem ? Bei so was "1-cos(pi-3pi)" kann ich Dir leider nicht weiter helfen, das ist mir zu mathematisch :-)
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);
t=t-d -> t=t+d da in der ersten Zeile schon ein Minus steht (f=fm-----).
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
Mit Gleichung 16 von folgendem Link http://www.embedded.com/columns/technicalinsights/56800129?_requestid=56271 ergibt sich für die zurückgelegte Strecke der Linearen Strecke (diese Strecke entspricht S_RAMP):
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.