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?
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
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?
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
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 ?)
> 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.
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 :)
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).
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 ?)
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
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.
@ 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 ?
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/Schrittmotorenhttp://ostermann-net.de/electronic/i_schritt.htmhttp://www.schrittmotor-blog.de/http://dse-faq.elektronik-kompendium.de/dse-faq.htm#F.10http://www.schrittmotor-blog.de/literatur-zu-schrittmotoren/
Mit freundlichen Grüßen
Thorsten Ostermann
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.
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:
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.
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.