Hallo, nach 2 wöchigem "rumtesten" unter der Verwendung der Formel V=a*t bin ich auf keinen grünen Zweig gekommen. Kann mir hier jemand einen Tipp geben wonach ich genau suchen muss bzw. Vielleicht schon einen kleines Codebeispiel (in C, für Arduino) geben. Bedingungen für die Beschleunigung sind: - physikalisch korrekt beschleunigen (also nicht irgend wie irgend etwas von den stepdelays abziehen) - Ich kenne Vmax (steps/s) und a (steps/s^2). Somit hat nach v=a*t (t=v/t) der Schrittmotor eine genau definierte Zeit in der er Vmax erreichen muss. Und das ist auch gut so. Denn ich möchte nach der Zeit gehen und nicht nach Steps/Winkel. - am Besten keine Timer verwenden sondern alles über die Loop(). - keine komplizierten Berechnungen während dem Beschleunigen. Am Besten alles im vorraus da mehrere Stepper mit einem Arduino angesteuert werden sollen. iWie hab ichs noch nicht hinbekommen dass der Stepper linear beschleunigt. Meist endeten meine Bemühungen in etwas exponentiellem wobei wohl auch der Grund war, dass ich die Beschleunigung nicht seperat in der Loop behandelt habe sondern mit den kleiner werdenden delays mehr oder weniger immer schneller beschleunigt habe. Mit Delay meine ich allerdings keine sleep() etc. Funktionen wie es die als delaymicros() etc. Beim Arduino gibt sondern die berechnete Zeit zwischen den Schritten die ich abwarte. Deep() etc. Wird selbstverständlich nicht benutzt. Ist im übrigen für ein kleines Hobby-Projekt bei dem ein ferngesteuertes Auto exakt vorgegebene Positionen anfahren soll. Würde mich über Tipps und Codebeispiele freuen :)
Patrick G schrieb: > nach 2 wöchigem "rumtesten" unter der Verwendung der Formel V=a*t bin > ich auf keinen grünen Zweig gekommen. Kann mir hier jemand einen Tipp > geben wonach ich genau suchen muss bzw. Was suchst du denn? Möchtest du wissen, wie groß die Beschleunigung a sein muss, damit sich die Geschwindigkeit innerhalb einer Zeit t von V0 auf V ändert?
Findest du in der Arduino Stepper Lib nicht, was du brauchst? Einfach in jedem loop eine speed-variable hochzählen und dann setSpeed() benutzen. Klingt aber für mich eher so, als wenn du eine Positionsregelung willst. Auch dazu gibt es schon fertige Libs, falls du das Rad nicht neu erfinden willst.
Hmm Nein. Ich suche eher einen Algorithmus der anhand gegebener Beschleunigung (Steps/s^2) und Vmax (Steps/s) die Delay zwischen den Schritten so ausrechnet, dass der Schrittmotor von V0 auf V linear beschleunigt. Die Zeit zum Beschleunigen ist allerdings nicht beliebig da mit steps/s^2 ja, je nach gegebem Beschleunigungswert, in einer bestimmten Zeit auf Vmax beschleunigt sein muss. Das soll auch so sein.
http://www.atmel.com/Images/doc8017.pdf Try to find the .pdf of David Austin. The link in the document above does not work at present. His work is famous, but I think it is not mathematically 100% accurate in the first step(s) at low speed. I have looked at this subject (as a hobbyist). Found that a counter that is adjusted (increase/decrease counter top) every delta t generates an acceleration of fixed amount. The delta t is a fix value generated by a second counter. If you want acceleration as a continuous variable as well... that seems a problem to me.
Patrick G schrieb: > Hmm Nein. Ich suche eher einen Algorithmus der anhand gegebener > Beschleunigung (Steps/s^2) und Vmax (Steps/s) die Delay zwischen den > Schritten so ausrechnet, dass der Schrittmotor von V0 auf V linear > beschleunigt. Die Zeit zum Beschleunigen ist allerdings nicht beliebig > da mit steps/s^2 ja, je nach gegebem Beschleunigungswert, in einer > bestimmten Zeit auf Vmax beschleunigt sein muss. Das soll auch so sein. Mal angenommen du willst in 100 loop-Durchläufen von 0m/s auf 10m/s kommen. Dann brauchst du doch nur speed = 0 loop_start speed = speed + 0,1 setSpeed(speed) loop_end machen. Wie lange ein loop dauert solltest du natürlich wissen, wenn du keinen timer benutzen willst, um eine Routine anzustoßen oder eine wait-Variable zu setzen. Verstehe ich dich falsch?
:
Bearbeitet durch User
Patrick G schrieb: > Hmm Nein. Ich suche eher einen Algorithmus der anhand gegebener > Beschleunigung (Steps/s^2) und Vmax (Steps/s) die Delay zwischen den > Schritten so ausrechnet,... This delay calculation involves division. Division consumes a lot of time. But, because at the following steps the division results will be close to each other this algorithm (based on multiply) most times gives accurate results already in 1 fast multiply loop: https://en.wikipedia.org/wiki/Division_algorithm#Newton.E2.80.93Raphson_division
:
Bearbeitet durch User
Patrick G schrieb: > Ich suche eher einen Algorithmus der anhand gegebener > Beschleunigung (Steps/s^2) und Vmax (Steps/s) die Delay zwischen den > Schritten so ausrechnet, dass der Schrittmotor von V0 auf V linear > beschleunigt. Jetzt wäre es natürlich schön, wenn du verraten würdest, welche Schrittfrequenz du erreichen möchtest. Der Algorithmus aus der AVR446 braucht IMHO pro Schritt auf einem Arduino mit ATmega328 @ 16MHz gut 100µs. Geert H. schrieb: > Division consumes a lot of time. It dependst on your understanding of "a lot".
Wolfgang schrieb: > Geert H. schrieb: >> Division consumes a lot of time. > > It dependst on your understanding of "a lot". I think on AVR it takes about 3000 cycles for a 'standard' floating point division. At 16 Mhz some 5000 divisions/sec. As this is probably by far the most time consuming per step it may be an indication of the max possible (micro-)step speed: 1000... 3000/s?
:
Bearbeitet durch User
Patrick G schrieb: > Lineare Beschleunigung > V=a*t nach allem was du schreibst, ist es keine "lineare" Beschleunigung, sondern eine konstante Beschleunigung, d.h. in einem gewissen Zeitintervall ändert sich die Beschleunigung nicht.
Geert H. schrieb: > I think on AVR it takes about 3000 cycles for a 'standard' floating > point division. The algorithmus described in AVR446 didn't use any floating point operation.
Patrick G schrieb: > Ich suche eher einen Algorithmus der anhand gegebener > Beschleunigung (Steps/s^2) und Vmax (Steps/s) die Delay zwischen den > Schritten so ausrechnet, dass der Schrittmotor von V0 auf V linear > beschleunigt Das ist doch so trivial, dass es garnicht den namen Algorithmus verdient. Selbstverständlich ist die Dauer zwischen 2 Stepimpulsen umgekehrt proportional zur Geschwidigkeit, also ist Division angesagt oder eine Tabelle. Habe ich schon auf Z80 und 8051 realisiert. Um das noch klarzustellen, es scheint da Probleme zu geben: für eine konstante Beschleunigung erhöht man in jeder Zeiteinheit die Sollgeschwindigkeit um den gleichen Betrag. Georg
Vielen Dank für eure Antworten. :) @Wolfgang: Ja das mit der Geschwindigkeit ist auch noch so eine Sache. Angestrebt war Maximalgeschwindigkeit in 1/16 StepMode. Da aber meine momentane Loop schon mit ~16µSek die MaxGeschwindigkeit vorgibt, wird da wohl nicht mehr viel zu machen sein.. außer auf FullStep etc. zu wechsel. Letztendlich möchte ich versuchen nicht die über 20µSek zu kommen (Pro Loopdurchlauf! Bedeutet da ist Beschleunigungsberechnung, StepPin-Ansteuerung und Zeitvergleich bis zum nächsten Step enthalten) Momentan hab ich das auch geschafft.. aber mit einer physikalisch inkorrekten Beschleunigung (ich errechne eine Startgeschwindigkeit und von der ziehe alle 1000µS immer 1µS ab wodurch die Beschleunigungsberechnung eine einfach Subtraktion ist. Damit komme ich auf ~16µSek für einen Loopdurchlauf bei dem ein Step gemacht wird. @Georg: Naja, so einfach scheint es eben nicht zu sein.. zumindest für mich. Angenommen ich errechne gleich zu beginn die Stepdelay für den aller ersten Schritt. Dann wird die vergangene Zeit bei ca. 4-8µSek liegen und die Geschwindigkeit (von Null angefangen) noch sehr niedrig. Das führt dazu, dass die StepDelay wegen der niedrigen Geschwindigkeit sehr hoch sein wird wodurch man am Anfang sehr viel Zeit mit Warten verbringt und dann plötzlich extreme Beschleunigungssprünge macht. Theoretisch müsste man um das zu umgehen eine Startgeschwindigkeit vorgeben. Damals hat das eben nicht funktioniert, werde es aber nochmal testen da ich damals noch diverse andere Fehler hatte wie eine Beschleunigung die immer schneller berechnet wurde da ich die errechnete delay gleichzeitig auch für die nächste Beschleunigungsberechnung genommen habe. Kann man überhaupt die Formel V= a*t für eine Beschleunigung benutzen oder müsste man da ganz andere Formeln nehmen da es sich hier um eine Drehbewegung handelt? P.S. Ich benutze keine AccelStepper Lib und das möchte ich auch gar nicht. Will für meinen Anwendungszweck (ferngesteuertes Auto) was eigenes. Von daher habe ich auch kein setSpeed() etc.^^ Wenn ich was brauchbares hin bekomme dann wird das natürlich auch veröffentlicht. :)
Patrick G schrieb: > Ist im übrigen für ein kleines Hobby-Projekt bei dem ein ferngesteuertes > Auto exakt vorgegebene Positionen anfahren soll. Ich versteh jetzt die Diskussion über die Geschwindigkeit nicht, wenn es um die exakte Position geht. Dazu muß man doch einfach nur Schritte zählen. MfG Klaus
Hallo, dein Problem ist nicht deine Berechnung für die Zeit zwischen den Schritten, sondern deine "Zeitmessung". Deine "Loop" hat nicht immer die gleiche Durchlaufzeit sondern ist "Durchlaufzeit + Stepdelay" lang. Entweder musst du das für deine Berechnung berücksichtigen oder den schon oben vorgeschlagen Weg über die Bibliothek nehmen. Gruß Kai
Geert H. schrieb: > http://www.atmel.com/Images/doc8017.pdf > > Try to find the .pdf of David Austin. The link in the document above > does not work at present. His work is famous, but I think it is not > mathematically 100% accurate in the first step(s) at low speed. The working link: http://www.embedded.com/design/mcus-processors-and-socs/4006438/Generate-stepper-motor-speed-profiles-in-real-time The original code that went with the D Austin article seems to have disappeared off the face of the 'net but, with the original authors permission, here it is. Original filename "motor.c" or "01austin.zip". from: http://www.avrfreaks.net/comment/931537#comment-931537 or: http://www.avrfreaks.net/sites/default/files/motor.c
ich häng ne frage dran : die Geschwindigkeit steuere ich über einen Interrupt, der abhängig von einem Timer, zeitgesteuert Schritte ausführt (jeweils einen aus dem Vollschritt-Muster). Das Problem ist, daß die H-Brücke bei langsamen Drehzahlen (Interrupt kommt seltener, z.b. bloß noch alle 20ms) wegen der langen "Haltezeit"-Perioden sehr heiß wird. Lösungsidee : den Schritt jeweils z.b. 1ms ausführen, dann hat er gedreht, und dann für den Rest der Wartezeit bis zum nächsten Schritt den Motor stromlos machen. Geht das ? (und dann der Bezug zum Thread : Wenn das geht, einfach quadratisch die Pausenzeit kürzer werden lassen, gibt doch ne lineare Beschleuingung, oder ?)
:
Bearbeitet durch User
> Lösungsidee : den Schritt jeweils z.b. 1ms ausführen, dann hat er gedreht, und dann für den Rest der Wartezeit bis zum nächsten Schritt den Motor stromlos machen. > Geht das ? Das geht schon nur verlierst du damit Drehmoment. In etwa das gleiche ergibt sich wenn man einen Schrittmotor mit Spannung steuert statt mit Strom.
:
Bearbeitet durch User
Patrick G schrieb: > - physikalisch korrekt beschleunigen Da weiß ich nicht, was das ist. Oder anders gefragt: wie beschleunigt man inkorrekt? Patrick G schrieb: > Ist im übrigen für ein kleines Hobby-Projekt bei dem ein ferngesteuertes > Auto exakt vorgegebene Positionen anfahren soll. Dafür ist ja keine exakte Linearität erforderlich, sondern Rampen fürs Beschleunigen und ein Soll-Istwert Vergleich. Mit/für AVR und auch Code für Arduino allerdings ohne setup() und loop(): http://mino-elektronik.de/Generator/takte_impulse.htm#bsp7
Reiner D. schrieb: > Lösungsidee : den Schritt jeweils z.b. 1ms ausführen, dann hat er > gedreht, und dann für den Rest der Wartezeit bis zum nächsten Schritt > den Motor stromlos machen. Der Motor springt dann aufgrund des Rastmomentes immer auf den nächsten Vollschritt. Du handels dir dann eine hohe Ungenauigkeit rein. Besser ist es einen Treiber zu kaufen, der eine Stromabsenkung besitzt. Schrittmotoren können schon warm werden (siehe Datenblatt).
> Der Motor springt dann aufgrund des Rastmomentes immer auf den nächsten
Vollschritt. Du handels dir dann eine hohe Ungenauigkeit rein.
Er steuert aber über Vollschritte wie du nachlesen kannst :)
:
Bearbeitet durch User
Nur nochmal zum Verständnis, möchtest du [1] eine immer gleichbleibende konstante Beschleunigung? D.h. dass dein a in V = a*t immer den selben wert besitzt (z.b. a = 5 (immer))? Das würde bedeuten, dass V sich wie eine Rampe verhält, die Geschwindigkeit nimmt also "linear" zu, der zurückgelegte Weg jedoch ändert sich Quadratisch (s = 0,5*a*t^2) Oder möchtest du [2] eine lineare Beschleunigungszunahme, also dass du zuerst langsam und dann immer schneller beschleunigst (also a zuerst 0 und dann steigend)? Also z.B. a = j * t (j = ruck, gibt an wie stark sich die beschleunigung ändert), dann wäre V = a * t = 0,5 j t^2. Die Geschwindigkeit ändert sich also quadratisch in dem Fall. Reiner D. schrieb: > (und dann der Bezug zum Thread : Wenn das geht, einfach quadratisch die > Pausenzeit kürzer werden lassen, gibt doch ne lineare Beschleuingung, > oder ?) Bei V = a * t gibt es kein quadrat, wieso also die Zeit quadratisch verkürzen um linearität zu erlangen? Um V zu halbieren: t/2; Um V zu vierteln: t/4; ... Das kann man wohl als linearität bezeichnen (oder eben proportionalität).
:
Bearbeitet durch User
lineare änderung der winkelbeschleunigung -> integral -> quadratische änderung der winkelgeschwindigkeit. oder ?
und dann bem steuern vom nema : bei niedrigen drehzahlen wird der "ohmisch", also kein imaginärteil mehr -> viel strom bei 12 volt, zuviel ! mit nem fertigen regler kein problem (strombegrenzung), aber wenn man den direkt (h-brücke) steuern möchte : pwm - leistungsbegrenzung in den haltepausen zwischen den schritten ? (wie lang darf denn dann ein schrittpuls sein, wenn man mit den vollen 12v draufgeht .. 1ms so etwa ?)
:
Bearbeitet durch User
Reiner D. schrieb: > lineare änderung der winkelbeschleunigung -> integral -> quadratische > änderung der winkelgeschwindigkeit. oder ? wieso lineare änderung, ich dachte a==konst?
Hallo Reiner > die Geschwindigkeit steuere ich über einen Interrupt, der abhängig von > Das Problem ist, daß die H-Brücke bei langsamen Drehzahlen (Interrupt > kommt seltener, z.b. bloß noch alle 20ms) wegen der langen > "Haltezeit"-Perioden sehr heiß wird. > > Lösungsidee : den Schritt jeweils z.b. 1ms ausführen, dann hat er > gedreht, und dann für den Rest der Wartezeit bis zum nächsten Schritt > den Motor stromlos machen. Wenn die H-Brücke zu heiß wird, ist sie entweder kaputt, hat ein schlechtes Toming (Kurzschluss in den Umschaltphasen der PWM) oder ist schlicht unterdimensioniert. Die einzige vernünftige Lösung ist, die eigentliche Ursache anzugehen, und nicht einen schlechten Workaround verwenden. Und zur eigentlichen Frage: Zum Thema Schrittmotoren, Rampen und Beschleunigung haben wir hier schon einige längere Diskusisonen gehabt. Die Beiträge sollten per Suchfunktion zu finden sein. Da steht eigentlich alles drinn, was man wissen muss. Mit freundlichen Grüßen Thorsten Ostermann
:
Bearbeitet durch User
Walter S. schrieb: > Reiner D. schrieb: >> lineare änderung der winkelbeschleunigung -> integral -> quadratische >> änderung der winkelgeschwindigkeit. oder ? > > wieso lineare änderung, ich dachte a==konst? Zwei verschiedene Fragensteller (Reiner D. und Patrick G.). Ich war auch kurzzeitig verwirrt :) Ein großes Manko in diesem Thread ist die sprachliche uneindeutigkeit. Es wäre schön, die gewünschten Ergebnise mal grafisch zu visualisieren (Ein Beschleunigungs-Zeit-Diagramm, ein V-Zeit-Diagramm, ein Weg-Zeit-Diagramm..). Nur eine Empfehlung.
:
Bearbeitet durch User
@ thorsten : (der begriff "workaround" hat mich amüsiert, früher hat man das "rucksacklösung" genannt..) du hast völlig recht : ursachenanalyse statt symptomgebastel. ehrlich gesagt ist der kern mein mangelhaftes know-how über schrittmotoren. liege ich falsch, wenn ich meine, daß wegen dem minimalen spulenwiderstand (realteil) bei ruhe zwischen den schritten und einer versorgung von (mindestens) 12 volt der strom zu hoch wird, so daß ein vorgeschalteter regler (siehe sense-widerstände im l297) den dann begrenzt ? wenn ja : warum das nicht mit pwm machen statt dem regler ? (soll ich einen eigenen thread machen [stepper für dummies], der hier wird ja wohl ein wenig verbogen ?)
Reiner D. schrieb: > liege ich falsch, wenn ich meine, daß wegen dem minimalen > spulenwiderstand (realteil) bei ruhe zwischen den schritten und einer > versorgung von (mindestens) 12 volt der strom zu hoch wird, Wegen de's Spulenwiderstande's mußt Du in's Datenblatt Deine's Motor's 'sehen ;-) Es gibt durchaus Motore, deren Spulen für 12 V DC ausgelegt sind. Die haben nur den großen Nachteil, keine hohen Drehzahlen zu bieten, was wiederum bei einer Küchenuhr auch nicht schlimm sein muß, es sei denn, man hat es eilig, wieder auf Winterzeit umzustellen.
(der bayer neigt halt zum dativ... : schon wegen dem butter ;-) klar, aber der nema17 hat im datenblatt eben keine 12 volt, ist aber schön billig und passt gut mechanisch. also : pwm ?
:
Bearbeitet durch User
Reiner D. schrieb: > klar, aber der nema17 hat im datenblatt eben keine 12 volt, ist aber > schön billig und passt gut mechanisch. Nema17 gibt es nur diesen: http://www.pollin.de/shop/dt/OTAzOTg2OTk-/Bauelemente_Bauteile/Motoren/Schrittmotoren/Schrittmotor_MINEBEA_17PM_K374BN01CN_1_8_.html Auch billig ;-)
http://www.ebay.de/itm/like/332070454213?lpid=106&chn=ps&ul_noapp=true ..ist aber für die fachliche frage ohne bedeutung.
Hallo zusammen, m.n. schrieb: > Reiner D. schrieb: >> klar, aber der nema17 hat im datenblatt eben keine 12 volt, ist aber >> schön billig und passt gut mechanisch. > > Nema17 gibt es nur diesen: > http://www.pollin.de/shop/dt/OTAzOTg2OTk-/Bauelemente_Bauteile/Motoren/Schrittmotoren/Schrittmotor_MINEBEA_17PM_K374BN01CN_1_8_.html > Auch billig ;-) "Nema17" ist keine Typenbezeichnung, sondern eine Angabe für das Flanschmaß: http://www.schrittmotor-blog.de/nema-schrittmotor-was-ist-das-eigentlich/ Mit freundlichen Grüßen Thorsten Ostermann
Hallo Reiner, > liege ich falsch, wenn ich meine, daß wegen dem minimalen > spulenwiderstand (realteil) bei ruhe zwischen den schritten und einer > versorgung von (mindestens) 12 volt der strom zu hoch wird, so daß ein > vorgeschalteter regler (siehe sense-widerstände im l297) den dann > begrenzt ? Nein, da liegst du ziemlich richtig. > wenn ja : warum das nicht mit pwm machen statt dem regler ? Weil der Regler sowieso PWM macht, aber eben so, dass auch der gewünschte Strom erreicht wird. Ohne Regler wäre es ein Steller, was spätestens unter Last zu ungenau wäre. > (soll ich einen eigenen thread machen [stepper für dummies], der hier > wird ja wohl ein wenig verbogen ?) Du brauchst keinen Thread zu dem Thema aufzumachen. Es gibt genug Webseiten und Bücher dazu. Das müssen wir hier nicht im Rahmen einer Diskussion nochmal neu aufbereiten, wenn mal wieder jemand mit Newbie-Fragen ankommt. Wenn du dich eingelesen hast und konkrete Fragen hast, können wir die hier gerne diskutieren... https://www.mikrocontroller.net/articles/Schrittmotoren http://ostermann-net.de/electronic/i_schritt.htm http://www.schrittmotor-blog.de/ http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.10 http://www.schrittmotor-blog.de/literatur-zu-schrittmotoren/ Mit freundlichen Grüßen Thorsten Ostermann
:
Bearbeitet durch User
Ich verstehe die Problematik gerade nicht so ganz. DDS - Der Steuerwert ist linear zur Ausgangsfrequenz und damit zur Drehzahl. Lineare steigende Drehzahl also einfach durch lineares heraufzählen dieser Variable, lineare Beschleunigung durch Parabel. Gruß Jobst
Jobst M. schrieb: > Lineare steigende Drehzahl also einfach durch lineares heraufzählen > dieser Variable, lineare Beschleunigung durch Parabel. Blödsinn, das war die Strecke. Linear steigende Drehzahl ist ja schon lineare Beschleunigung. War gestern zu spät für mich. Gruß Jobst
Jobst M. schrieb: > Jobst M. schrieb: >> Lineare steigende Drehzahl also einfach durch lineares heraufzählen >> dieser Variable, lineare Beschleunigung durch Parabel. > > Blödsinn, das war die Strecke. > Linear steigende Drehzahl ist ja schon lineare Beschleunigung. > War gestern zu spät für mich. > > > Gruß > > Jobst War wohl doppelt zu spät :). Die Ableitung einer Rampe (lineare Steigung) ist eine Konstante. Somit ist die Beschleunigung eine Konstante. Konstant -> Rampe (Linear) -> Parabel a v s Rampe (Linear) -> Parabel -> Kubisch a v s NULL -> Konstant -> Rampe (Linear) a v s Ich versuch das mal mit schlechtem Code:
1 | V = 0; //Steps pro us (Das steigt linear an) |
2 | a = 100; //Steps pro s^2 (Konstant) |
3 | a *= 1E-12; //Steps pro us^2 |
4 | t = 10; //Durchlaufzeit in us |
5 | |
6 | |
7 | /* da kein Timer verwendet wird ist die Durchlaufzeit unklar, ich gehe von
|
8 | 10us aus, deshalb wird hier alles in us gerechnet (V,a,t). Falls man
|
9 | sich das anzeigen lassen will muss man es eben umrechnen. */
|
10 | |
11 | while(1) { |
12 | V = a * t; //Schritte pro Zeit |
13 | t_step = 1 / V; //Zeit pro Schritt |
14 | |
15 | /* Jenachdem was man für peripherie nutzt um den Ausgang
|
16 | Ein- oder Auszuschalten, ist die weitere Logik unterschiedlich */
|
17 | |
18 | /* Falls das Signal per PWM gesteuert wird, könnte man nun den
|
19 | Zähler anhand des t_step wertes einstellen */
|
20 | |
21 | /* Falls man in der Schleife die Ein- und Ausgänge selbst einstellt
|
22 | muss man die gerade vergangene Zeit mit t_step vergleichen und
|
23 | dementsprechend Ein- und Ausschalten, so dass alle t_step
|
24 | microsekunden ein neuer Impuls gesendet wird */
|
25 | }
|
t_step ist die Zeit pro Schritt und diese ist umgekehrt Proportional zur Geschwindigkeit V und ist demnach NICHT linear und verläuft hyperbolisch (1/V). Vielleicht beantwortet das die ein oder andere Frage.
:
Bearbeitet durch User
Eine Rückmeldung wäre ja schon irgendwie angenehm :-/
Raphael G. schrieb: > Eine Rückmeldung wäre ja schon irgendwie angenehm :-/ Hallo Raphael, danke für die Antwort und den Code. Theoretisch müsste es so funktionieren. Allerdings muss t bei jedem Schleifendurchlauf (hier um 10µS) hochgezählt werden. So habe ich das letztendlich auch gemacht. Nunja theoretisch hätte es funktionieren müssen, praktisch leider nicht. Hab es jetzt aufgeben müssen da ich noch 5 Tage bis zur Projektabgabe habe und es immer noch nicht gescheit läuft. Im Anhang habe ich mal ein Screenshot von einer meiner zig angefertigten Graphen gemacht. Dieser Graph beschreibt eigentlich genau deine Methode. Eigentlich schade. Hatte gehofft mit V=a*t etwas brauchbares hinzubekommen, etwas was eben ohne Timer auskommt und so simpel ist wie du es in deinem Code geschrieben hast. Kein Plan was ich ums verrecken so derartig falsch gemacht habe. War ständig darauf bedacht keine komplexen Formeln zu verwenden und es so simpel wie möglich (a la V = a*t) zu halten. Auf dem Arduino Uno ohne FPU und Division in Hardware darf man schon gar nicht erst an komplexe Formeln denken ansonsten ist man ruckzuck über 30µS pro Schleifendurchlauf. Vielleicht ist aber die allgemeine Formel V=a*t einfach nicht für Schrittmotoren geeignet. Wenn iwer ein funktionierenden Code für 8MHz 8Bit Arduinos hat und den zeigen will dann nur her damit :) Letzter Stand meines Codes der nur je nach Geschwindigkeit und mehr sprunghaft statt linear funktioniert:
1 | loop(){ |
2 | unsigned long currentTimeMicros = micros(); |
3 | if (stepDelay_uSec > finalStepDelay_uSec) { //finalStepDelay_uSec = 1000000/speedStepsPerSec |
4 | time += (currentTimeMicros - timeLastAccTick) / 1000000.0; //Vergangene Zeit in S umrechnen und aufaddieren |
5 | timeLastAccTick = micros(); //Letzter Zeitpunkt speichern |
6 | stepDelay_uSec = 1000000 / (acceleration*time); //Wartezeit zwischen Schritten in µS -> t = 1 / f -> 1 / V = 1 / (a*t) = in µS -> 10000000 / (a*t) |
7 | }
|
8 | if (stepsToDo > 0 && currentTimeMicros - timeLastStep >= stepDelay_uSec) { |
9 | digitalWriteFast(stepPin_, HIGH); |
10 | stepsToDo--; |
11 | timeLastStep = micros(); |
12 | digitalWriteFast(stepPin_, LOW); |
13 | }
|
14 | }
|
:
Bearbeitet durch User
Das sieht alles sauber aus. Natürlich ist v=a*t auch auf Schrittmotoren anwendbar. Wenn deine 6400 steps/s allerdings Voll- oder Halbschritte sind (was beim Einsatz eines L297 zu erwarten ist), ist deine Enddrehzahl vermutlich einfach zu hoch. Bei Halbschritt kommt man so auf 16 U/s. Bei niedriger Versorgungsspannung oder einer hochohmigen Motorwicklung ist das selbst mit moderater Beschleunigung nicht zu erreichen. Mit freundlichen Grüßen Thorsten Ostermann
Patrick G. schrieb: > So habe ich das letztendlich auch gemacht. > Nunja theoretisch hätte es funktionieren müssen, praktisch leider nicht. Was war denn letztendlich passiert? Bleibt er hängen mittendrin?
Patrick G. schrieb: > Hatte gehofft mit V=a*t etwas brauchbares hinzubekommen Die Formel gilt nur für konstante Beschleunigung. Patrick G. schrieb: > Vielleicht ist aber die allgemeine Formel V=a*t einfach nicht für > Schrittmotoren geeignet. Die Formel ist nicht allgemein. Allgemein wäre dV = a*dt. Mit Differenzengleichungen kann man damit bei bekannten delta-t gut auf dem Rechner umgehen. Patrick G schrieb: > Ist im übrigen für ein kleines Hobby-Projekt bei dem ein ferngesteuertes > Auto exakt vorgegebene Positionen anfahren soll. Hobby Projekt? Patrick G. schrieb: > Hab es jetzt aufgeben müssen da ich noch 5 Tage bis zur Projektabgabe > habe Also doch nicht Hobby? Das Konzept an sich ist schon fragwürdig, weil man mit der reinen Schrittmotorsteuerung Effekte wie Schlupf etc nicht erfasst. jeder noch so kleine Winkelfehler beim "Berechnen" des Fahrwinkels anhand von Lenkeinschlagwinkel, Geschwindigkeit und Zeit führt danach ganz schnell zu riesigen Poitionsfehlern.
"Also doch nicht Hobby?" Mittlerweile ist es beides. Angefangen hat es als HobbyProjekt. Als wir dann in der Schule Anfang dieses Jahres ein Projekt aussuchen durften habe ich natürlich gleich dieses Projekt angemeldet. Ist mittlerweile also ein Projekt für die Schule das danach auch bei mir bleiben wird und als Hobby Projekt weitergeführt wird. "Was war denn letztendlich passiert? Bleibt er hängen mittendrin? Bei niedriger Beschleunigung beschleunigt der Schrittmotor anfangs meist ruhig und gleichmäßig. Sobald er in die höheren Drehzahlen kommt fängt er an stufenartig (und das immer länger werden) zu beschleunigen. Er hält also für eine bestimmte Zeit die Geschwindigkeit und erhöht diese iwann sprunghaft. Bisher habe ich nicht herausgefunden woran das liegt. Auf jeden Fall ist das Problem auf einem Arduino UNO viel stärker festzustellen als auf einem 84MHz Arduino Due. GGf. Rechenungenauigkeiten bei a*t etc..
Patrick G. schrieb: > Auf jeden Fall ist das Problem auf einem Arduino UNO viel stärker > festzustellen als auf einem 84MHz Arduino Due. GGf. > Rechenungenauigkeiten bei a*t etc.. Hast du dir die AVR446 überhaupt mal durchgelesen? In einer gleichmäßigen Beschleunigungsrampe brauchst du kein a*t zu rechnen.
Berechnung der Wartezeiten Tw(s) zur konstanten Beschleunigung a eines Schrittmotors in Abhänigkeit der bereits gemachten Schritte s: Aus dem Physikunterricht wissen wir: s = 1/2 a t² (1) v = a t (2) v ist aber auch umgekehrt proportional zur Wartezeit zwischen zwei Schritten: v = 1 / Tw (3) Gleichsetzen von (2) und (3) ergibt: Tw = 1 / (a t) (4) aus (1) ergibt sich die Abhängigkeit von t zu s: t = sqrt(2 s / a) (5) jetzt (5) in (4) einsetzen und etwas vereinfachen. Dann kommt folgendes raus: Tw = 1 / sqrt( 2 a s) Da hier nicht auf Einheiten geachtet wurde spielt die 2 auch keine entscheidende Rolle und kann einfach im a "verschwinden" Tw(s) = 1/sqrt( a s ) Wie gehe ich praktisch damit um? ich probiere für verschiedene Werte von a aus, nach wie vielen Schritten s ich mein minimales Tw (Höchstgeschwindiggeit!) erreicht habe. Wenn die Schrittanzahl "vernünftig" erscheint (insgesamt 360° oder was auch immer du willst bis Höchstgeschwinndigkeit) hast du ein vernünftiges a gefunden. Je nach CPU Leistungsfähigkeit und vorhandenem Speicher entweder Tabellen anlegen oder rechnen.
Martin schrieb: > Je nach CPU Leistungsfähigkeit und vorhandenem Speicher entweder > Tabellen anlegen oder rechnen. ... oder sich mal angucken, wie das in der AVR446: "Linear speed control of stepper motor" angegangen wird. Statt der sqrt-Funktion reicht für diese Anwendung locker eine Taylor-Appoximation mit einer rekursiven Berechnung des Schrittabstandes. Dann geht das ganz ohne Tabellen, die für jede Rampe neu berechnet werden müssten oder dicke CPU-Leistung.
Ich habs mal ausprobiert, ein Arduino Uno braucht ca 80 µs für 1/sqrt(..). Kann man also locker berechnen.
1 | #define motorPin1 11
|
2 | #define motorPin2 10
|
3 | #define motorPin3 9
|
4 | #define motorPin4 8
|
5 | #define SLOW 10000
|
6 | #define SPEED 700
|
7 | #define RIGHT 1
|
8 | #define LEFT 0
|
9 | |
10 | |
11 | typedef struct |
12 | {
|
13 | byte cnt:3; |
14 | }
|
15 | PTR8; |
16 | |
17 | PTR8 ptr8; |
18 | |
19 | byte steps[8][4] = |
20 | {
|
21 | { 1, 0, 0, 0 }, |
22 | { 1, 1, 0, 0 }, |
23 | { 0, 1, 0, 0 }, |
24 | { 0, 1, 1, 0 }, |
25 | { 0, 0, 1, 0 }, |
26 | { 0, 0, 1, 1 }, |
27 | { 0, 0, 0, 1 }, |
28 | { 1, 0, 0, 1 } |
29 | };
|
30 | |
31 | void makeStep(byte i) |
32 | {
|
33 | digitalWrite(motorPin1, steps[i][0]); |
34 | digitalWrite(motorPin2, steps[i][1]); |
35 | digitalWrite(motorPin3, steps[i][2]); |
36 | digitalWrite(motorPin4, steps[i][3]); |
37 | }
|
38 | |
39 | |
40 | void moveMotor(byte dir, double a, unsigned long steps) |
41 | {
|
42 | unsigned long i; |
43 | unsigned long ms; // Start Berechnung |
44 | unsigned long md; // Dauer Berechnung |
45 | unsigned aktdelay; // Wartezeit in µs |
46 | Serial.print("Steps: "); |
47 | Serial.println(steps); |
48 | for (i=0;i<steps;i++) |
49 | {
|
50 | ms = micros(); |
51 | aktdelay = 1/sqrt(a*(i+1)); |
52 | if (dir == RIGHT) |
53 | {
|
54 | ptr8.cnt ++; |
55 | }
|
56 | else
|
57 | {
|
58 | ptr8.cnt --; |
59 | }
|
60 | if (aktdelay < SPEED) |
61 | {
|
62 | aktdelay = SPEED; |
63 | }
|
64 | if (aktdelay > SLOW) |
65 | {
|
66 | aktdelay = SLOW; |
67 | }
|
68 | md = micros()-ms; // geht kaputt wenn der Timer Overvlow während der Berechnung passiert, kann man aber richten |
69 | makeStep(ptr8.cnt); |
70 | delayMicroseconds(aktdelay-md); |
71 | }
|
72 | }
|
73 | |
74 | |
75 | void setup() |
76 | {
|
77 | pinMode(motorPin1,OUTPUT); |
78 | pinMode(motorPin2,OUTPUT); |
79 | pinMode(motorPin3,OUTPUT); |
80 | pinMode(motorPin4,OUTPUT); |
81 | Serial.begin(115200); |
82 | ptr8.cnt = 0; |
83 | }
|
84 | |
85 | |
86 | void loop() |
87 | {
|
88 | byte incomingByte = 255; |
89 | while (incomingByte == 255) //warten bis Zeichen auf der seriellen Schnittstelle erscheint |
90 | {
|
91 | incomingByte = Serial.read(); |
92 | }
|
93 | moveMotor(LEFT,0.000000001,4096); |
94 | }
|
Martin schrieb: > Ich habs mal ausprobiert, ein Arduino Uno braucht > ca 80 µs für 1/sqrt(..). > Kann man also locker berechnen. Also, entschuldige mal... das sind ungefähr 1300 (!!) Takte (bei 16MHz Systemtakt). Findest Du das nicht leicht übertrieben? Wenn Du drei Achsten ansteuern willst, ist das System bei 4000 Schritten je Sekunde dicht. <Georg_Schramm> Das ist doch kein Niveau! </Georg_Schramm>
Mit einer vereinfachten Wurzel vom Quake-Algo kommt man auf etwa 300 Takte für eine inverse Wurzel. Man muss ja auch nicht bei jedem Schritt die perfekte Schrittweite (Zeit) ermitteln. Alle 1 bis 2ms sollten normal dicke reichen. Schon etwas länger her, aber bei Schrittraten von bis zu 500kHz hatte ich keine stark hörbaren Effekte wenn ich das nur alle 2ms berechnet hatte.
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.