Forum: Mikrocontroller und Digitale Elektronik Lineare Beschleunigung schrittmotor in bestimmter Zeit


von Patrick G (Gast)


Lesenswert?

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 :)

von Wolfgang (Gast)


Lesenswert?

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?

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

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.

von Patrick G (Gast)


Lesenswert?

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.

von Geert H. (geerth)


Lesenswert?

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.

von Md M. (Firma: Potilatormanufaktur) (mdma)


Lesenswert?

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
von Geert H. (geerth)


Lesenswert?

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
von Wolfgang (Gast)


Lesenswert?

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".

von Geert H. (geerth)


Lesenswert?

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
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von Georg (Gast)


Lesenswert?

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

von Patrick G (Gast)


Lesenswert?

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. :)

von Klaus (Gast)


Lesenswert?

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

von Kai S. (kai1986)


Lesenswert?

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

von Geert H. (geerth)


Lesenswert?

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

von Reiner D. (dollreiner)


Lesenswert?

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
von Waldemar Z. (waldemar_z)


Lesenswert?

> 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
von m.n. (Gast)


Lesenswert?

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

von aSma>> (Gast)


Lesenswert?

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).

von Waldemar Z. (waldemar_z)


Lesenswert?

> 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
von Raphael G. (steggesepp)


Lesenswert?

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
von Reiner D. (dollreiner)


Lesenswert?

lineare änderung der winkelbeschleunigung -> integral -> quadratische 
änderung der winkelgeschwindigkeit. oder ?

von Raphael G. (steggesepp)


Lesenswert?

Ja.

von Reiner D. (dollreiner)


Lesenswert?

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
von Walter S. (avatar)


Lesenswert?

Reiner D. schrieb:
> lineare änderung der winkelbeschleunigung -> integral -> quadratische
> änderung der winkelgeschwindigkeit. oder ?

wieso lineare änderung, ich dachte a==konst?

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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
von Raphael G. (steggesepp)


Lesenswert?

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
von Reiner D. (dollreiner)


Lesenswert?

@ 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 ?)

von m.n. (Gast)


Lesenswert?

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.

von Reiner D. (dollreiner)


Lesenswert?

(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
von m.n. (Gast)


Lesenswert?

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 ;-)

von Reiner D. (dollreiner)


Lesenswert?

http://www.ebay.de/itm/like/332070454213?lpid=106&chn=ps&ul_noapp=true

..ist aber für die fachliche frage ohne bedeutung.

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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
von Reiner D. (dollreiner)


Lesenswert?

massig info, vielen dank !

von Jobst M. (jobstens-de)


Lesenswert?

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

von Jobst M. (jobstens-de)


Lesenswert?

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

von Raphael G. (steggesepp)


Lesenswert?

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
von Raphael G. (steggesepp)


Lesenswert?

Eine Rückmeldung wäre ja schon irgendwie angenehm :-/

von Patrick G. (patrick_123)



Lesenswert?

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
von Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite


Lesenswert?

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

von Steggesepp (Gast)


Lesenswert?

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?

von Der Andere (Gast)


Lesenswert?

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.

von Patrick G. (patrick_123)


Lesenswert?

"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..

von Wolfgang (Gast)


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

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.

von Wolfgang (Gast)


Lesenswert?

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.

von Martin (Gast)


Lesenswert?

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
}

von Possetitjel (Gast)


Lesenswert?

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>

von Nico W. (nico_w)


Lesenswert?

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
Noch kein Account? Hier anmelden.