AVR446

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    • Neu

      ich möchte einen Schrittmotor möglichst so beschleunigen, dass er nicht stehenbleibt,
      bisher mache ich es so, dass ich den "Timerpreload" (Startwert) auf Null setze, dann bei jedem Sprung in die ISR den Wert incrementiere bis zum Erreichen des Sollwertes für die gewünschte Drehzahl.
      Leider funktioniert das nicht, also habe ich vor dem Increment-Befehl noch eine Verzögerung eingebaut, d.h. z.B: die ISR muss 15mal durchlaufen werden, bevor der Timer-Preload erhöht wird.
      Das ist alles aber nicht befriedigend, da ich durch viel probieren herausgefunden habe, dass der Motor mit der Methode am Beginn zu langsam beschleunigt, am Ende aber doch wieder in den Stillstand läuft.
      Jetzt wollte ich halt mal das Verfahren nach der AN446 probieren, bin aber offensichtlich zu doof, das umzusetzen, deshalb mal die Frage nach einen Beispiel.
      Nochwas: Tabelle scheidet aus, (allerdings würde mich die auch mal an einem Beispiel interessieren), da die Enddrehzahl eine Variable ist, welche von diversen Programmeingaben abhängig ist.
      Drehzahlbereich etwa von 18 bis 375 min-1 (mit etwas Toleranz)
      Gruß
      Hans
    • Neu

      Hallo Hans
      In der AN wird im Prinzip nichts anderes gemacht, als die Zeit zu berechnen, nach der die Drehzahl jeweils von der einen zur nächsten Stufe hochgesetzt wird.

      Das kannst du relativ simpel nachbilden.
      In der Beschleunigungsphase immer nach einer fixen Zeit die Drehzahl beispielsweise jeweils 20 zu erhöhen. Das ergäbe dann 18 volle Stufen und einmal den Rest. Wenn die Rampe innerhalb 2 Sekunden auf max Speed sein soll, muss also 19x die Geschwindigkeit in 2s erhöht werden. Also alle 105ms.

      Bei 18 Umdrehungen brauchst du keine Rampe, das sind ja 0,3 Umdrehungen / Sekunde

      Eine Function könnte so aussehen:

      Quellcode

      1. Dim lastSpeed as Word ' interne HilfsVariable
      2. Function rampUp(byval maxSpeed as Word) as Function
      3. lastSpeed = lastSpeed + 20
      4. If currentSpeed > maxSpeed then currentSpeed = maxSpeed
      5. rampUp = currentSpeed
      6. End Function
      Kürzere Aufrufintervalle würden die Rampe steiler machen.

      Im gleichen Schema gehts dann wieder die Rampe runter.

      So würde ich das zumindest mal versuchen.
      Kaum macht man es richtig - und schon geht's!
    • Neu

      @Mitch64
      genau das funktioniert ja nicht, Deine "20" entsprechen ja im Prinzip genau meinen im Beispiel angeführten "15"
      und das führt ja zu dem beschriebenen Verhalten, dass es am Anfang zu wenig und am Ende zu viel ist.
      ich habe mir mal nach diesem AN446 mit angenommenen*) Werten eine Excel-Tabelle erstellt, da ist der Verlauf eben ganz anders, nämlich am Beginn große Sprünge, welche gegen Ende der Rampe immer kleiner werden.
      Soetwas brauche ich

      *) angenommen deshalb, weil ich mit der exakten Berechnung der Werte ein Verständnisproblem habe, d.h. ich habe nur im Prinzip nur die Folge nachgebildet.
      Gruß
      Hans
    • Neu

      Wenn man timerload-Werte linear ändert, bekommt man keine lineare Zeitveränderung. Ein Ändern von (timerx=) 250 zu 249 verändert weniger an der Aufrufzeit, als eine Änderung von 3 zu 2. Ist jetzt sehr drastisch gewählt, aber da erkennt man es gut. Es würde sich verbessern, wenn man nicht einfach dekrementiert, sondern einen Bruch abzieht, zB 200/200 (=1), beim nächsten mal 200/201, dann 200/202... Man nimt somit immer weniger weg, je öfter man es macht. Ist halt mehr Rechnerei.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von tschoeatsch ()

    • Neu

      Im Prinzip willst du eine lineare Rampe auf die Drehzahl bezogen.
      Du musst rückwärts rechnen zu dem Punkt, an dem deine Änderung durchgeführt wird.

      Wenn du den Preload linear änderst, ändert sich die Drehzahl eben nicht linear.
      Das hat @tschoeatsch schon richtig erkannt.

      Wenn die Drehzahl linear mit 20min-1 zunimmt, ist das linear.

      Mach mal eine Excel Tabelle und rechne das durch.

      Wenn du unbedingt bei deinem Preload bleiben willst, müsstest du von der gewünschten Drehzahl den Preload berechnen.
      Leider gibts bei dem Verfahren einen negativen Effekt, denn die Überlauf-Frequenz des Timers nimmt zu, wenn der Preload zunimmt.
      D.H. deine Zeiten zwischen dem Nachstellen der Drehzahl wird wieder nichtlinear. Also jeden 15. Durchlauf den Wert anpassen könnte nicht gescheit funktionieren.

      Du kannst es über den Preload aber trotzdem machen, Du musst den Preload immer in exakten Zeit-Abständen anpassen.
      Der Preload-Wert berechnest du aus dem gewünschtem linearen Anstieg der Drehzahl.
      Kaum macht man es richtig - und schon geht's!
    • Neu

      eine Änderung des Preloads von 0 bis 246 (von max. 256) ist m.E. alles andere als linear, aber leider eben in der falschen Richtung.
      Ich will ja nach oben "relativ" kleinere Schritte als "unten".
      Aber nochmal zu meiner Ausgangsfrage:
      die Leute bei AVR haben sich doch darüber sehr viel Gedanken gemacht, als sie die AN446 herausgaben,
      in allen Foren (insbesondere mc.net, das Forum das Verrückte macht) wird immer wieder darauf hingewiesen, in C findet man auch Beispiele, warum denn nicht in Bascom.
      Ich folgere mal, dass sich damit anscheinend noch keiner beschäftigt hat, und jeder seine eigen Lösung "bastelt", Warum?
      Gruß
      Hans
    • Neu

      Hans_L schrieb:

      eine Änderung des Preloads von 0 bis 246 (von max. 256) ist m.E. alles andere als linear, aber leider eben in der falschen Richtung.
      Ich will ja nach oben "relativ" kleinere Schritte als "unten".
      Mein früherer Post war bisschen wirr, ich versuch's mal deutlicher.
      Also, ich meinte den Preload nicht von 0 bis 246 inkrementieren, sondern einen Bruch dazu verwenden.
      Startwerte:
      preload=0: x=5
      in der isr steht dann:

      b=100/x
      incr x
      preload=preload+b

      Preload wäre dann der vorhergehende Wert +20, +16, +14, +12, +11, +10, +9, +8, +7, +7, +6, +6, +5, +5, +5, +5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, .....
      Bei 50 Schritten bist du etwa bei 250.
      Etwas klarer?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      Ich versuche mich gerade in die appnote einzulesen. Das Wichtige für die Rampe ist doch offenbar die Formel für die Pausen cn zwischen den Steppulsen:
      steppulspause.PNG.
      Das lese ich so: neue_Pause=alte_Pause-(2x alte_pause/(4n+1)), wobei n der Zähler der Pause ist.
      Wie bekommt man damit unterschiedliche Steigungen für die Beschleunigungsrampe hin? Nur durch die Länge des Pulses?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      @tschoeatsch

      mal ein paar Vorüberlegungen zu Deiner o.a. Methode.
      Preload ist vom Typ Byte, also mus +b ebenfalls byte sein,
      aus 100/x ist aber single(?)
      also brauche ich noch eine Typumwandlung B_Byte = B_Single, evt noch ein B_single=Round(B_single)
      X kann ich nicht gegen unendlich laufen lassen. also noch eine IF-Abfrage vor dem Inkrementieren, welche bei (z.B:) X=255 (auch byte) die Rechnung stoppt.
      Theoretisch könnte auch bei ungünstiger Wahl von X und Startwert_preload ein Überlauf (über 255) entstehen, also auch hier eine Abfrage mit Notbremse

      wird das nicht alles etwas viel für eine ISR?


      zu Deinem zweiten Beitrag: diese Frage stelle ich mir auch
      Gruß
      Hans

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Hans_L ()

    • Neu

      Du kannst alles mit bytes machen, es ist nicht verboten zu dividieren, es werden nur die Nachkommastellen abgeschnitten.
      Ich hab' meine Idee noch nicht selbst probiert, wie das auch mit einem stepper dran klingt/aussieht/anfühlt. Es ist eine Idee, wie man mit jedem Schritt weniger zugibt. Bei der Formel aus der appnote steht n ja auch im Nenner und im Zähler der vorhergehende Wert.
      Eine Beschleunigung kann man bei Raketen in's Unendliche treiben, bei einem stepper nicht. Bei meinem Beispiel bin ich ja nach ca. 50 Schritten bei etwa 250, das muss dann die timereinstellung für die höchste Drehzahl/Pulsfrequenz sein. In der appnote geht die Beschleunigung auch nur bis max_speed. Ein 8bit-timer ist auch bisschen unflexiebel.
      Ob das jetzt für eine isr zuviel ist? Die Formel aus der appnote berechnet je erstmal nur die Pause zwischen den Pulsen, das mus ja auch noch zu einem timerpreload umgerechnet werden, damit auch ein Pulspausenverhältnis am pin rauskommt. Das müsste dann mit Pwm mit variabler Frequenz gehen, ist aber eigentlich nur mit 16bit sinnvoll.
      Ich kann mir das jetzt grob so vorstellen, dass in einer isr diese Pwm errechnet wird und ausgeführt wird. In dieser isr wird auch berechnet, mit welcher Frequenz diese ausgeführt wird, was dann die Steilheit der Beschleunigungsrampe wäre. Alle x millisekunden wird um einen Wert y die Pulsfrequenz und somit die Geschwindigkeit erhöht. X ist die Aufruffrequenz der isr, y ist der Wert für die darin neu errechnete Pwm.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      Wenn ich jetzt die Formel aus der appnote vereinfache, dann wird das c von Schritt zu Schritt etwa halbiert, zunehmend bisschen mehr wie jeweils die Hälfte, durch das n im Nenner. Das bedeutet für mich, wenn das direket an de stepper geleitet wird die maximale Beschleunigung. Kleinere Rampen werden mit Zwischensteps ohne Pulszeitveränderungen erzeugt? Ist die max. Beschleunigung nicht von vielen mechanischen Faktoren abhängig? So richtig kann ich der appnote nicht folgen.
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------
    • Neu

      also von 0 bis 18 hab ich mit dem "Sollwert"(=6) gestartet, das funktioniert problemlos, deshalb ist das kein Problem,
      die 0 bis 375 zicken, Wunsch wäre max. nach 3 Umdrehungen, Super wäre nach 90Grad, (aber nicht zwingend notwendig)
      Der 16bit Timer ist leider schon belegt.
      Den 8 Bit Timer wollte ich mit Prescaler 64 betreiben, Startwert für 18U/min= 6, für 375U/min = 246 (würde eben beides in die 255 reinpassen)
      Gruß
      Hans
    • Neu

      Hans_L schrieb:

      Den 8 Bit Timer
      da steckt wohl das Problem. Je näher du den 255 kommst umso größer wird die Frequenzänderung, wenn du nur um 1 incrementierst, weniger geht ja nicht. Krasses Beispiel, die Änderung von 254 zu 255 verdoppelt die Drehzahl, wohingegen die Änderung von 6 zu 7 vergleichsweise wenig an der Drehzahl ändert. Wie wäre es mit einer prescaler-Umschaltung beim Hochfahren der Frequenz. Das wäre doch mal eine Herausforderung. Den prescaler so wählen, dass der timer möglichst weit bis zum Überlauf ticken muss. Dann macht eine incrementierung relativ kleine Frequenzänderungen.
      Welchen 8bit-timer verwendest du, den timer2, mit der größeren Prescalerauswahl?
      Raum für Notizen

      -----------------------------------------------------------------------------------------------------

      -----------------------------------------------------------------------------------------------------