Forum: Mikrocontroller und Digitale Elektronik Schrittmotor linear Beschleunigen


von Gerald M. (gerald_m17)


Lesenswert?

Hallo,

ich habe einen Schrittmotor über eine Spindel an einen Kolben verbunden, 
um eine Flüssigkeit mit einer gewissen Geschwindigkeit ausströmen zu 
lassen.

Die Sollgeschwindigkeit bekomme ich aus einem Regler alle 10ms. Jede 
Millisekunde berechne ich momentan die aktuelle Frequenz des Timers der 
die Pulse für den Motor ausgibt.
Kann jemand was zu diesen Zeiten sagen? ich hatte die 
Schrittmotorberechnung zunächst auch nur alle 10ms aufgerufen, doch mir 
erscheint der Wert etwas klein. Deshalb habe ich einen neuen Timer 
hierfür verwendet.
Bisher habe ich die Geschwindigkeit linear um einen Beschleunigungswert 
erhöht. Das funktioniert ohne Flüssigkeit auch gut. Leider passiert es 
oft, dass wenn ich erst bremse und dann wieder beschleunigen muss, dass 
ich Schritte verliere.

Deshalb würde ich gerne linear Beschleunigen, da ich vermute dass genau 
dieser Ruck zum Schrittverlust führt.

Ich habe mir zwar schon etwas ausgedacht, doch fehlt es hier an Details. 
Beispielsweise muss ich ja abbremsen bevor ich an das Zylinderende 
pralle. Auch "schwingt" das Ganze auch um den Sollwert, da ich 
vermutlich die Dauer bis zum erreichen der Geschwindigkeit falsch 
berechne.
Ich weiß ich habe schon einmal irgendwo eine Implementierung für 
3D-Drucker irgendwo gesehen, bei der auch eine hervorragende Erklärung 
mit dabei war, leider finde ich diese nicht. Ich meine da wurden sogar 
noch weitere Ableitungen als nur der Jerk mit beachtet.

Um den "zeig mal her was du hast" "Antworten", bei denen danach keine 
Antwort mehr kommt im Voraus etwas entgegenzuwirken, hier einmal mein 
Code. Aber wie gesagt, eigentlich bin ich auf der Suche nach etwas 
fertigen, denn ich bekomme immer einen Knoten im Hirn wenn ich daran 
denke die Beschleunigung zu verringern, da man ja dann immer noch 
beschleunigt, nur nicht so schnell :D

Anmerkungen:
Das Motorstruct hat eine targetvelocity und eine aktuelle 
"verlocity_in_steps"
Der "celleration" Wert soll beim Motor speichern welche Bescheunigung er 
gerade hat. Positiv bedeutet der Motor hat im letzten Schritt die 
beschleunigung erhöht, Negativ er hat sie verringert.
1
#define servorate 1000.0f  //has to fit to the servo rate set with timer 13 //now timer 6
2
3
#define accel_raw 200.0f  //steps per second^2
4
#define deccel_raw 200.0f  //steps per second^2
5
#define accel (accel_raw*microsteps/servorate) //microsteps per servoloop
6
#define deccel (deccel_raw*microsteps/servorate) //microsteps per servoloop
7
#define max_speed (max_motor_speed*fullsteps_per_rev*microsteps) //max Motor speed in microsteps/s
8
#define jerkstepsacc 50.0f
9
#define jerkstepsdecc 50.0f
10
#define jerkacc (accel/jerkstepsacc)
11
#define jerkdec (deccel/jerkstepsdecc)
12
13
uint32_t Set_Stepper_Velocity(MOTOR* Motor)
14
{
15
  uint32_t timervaluebuffer = 0;
16
  int32_t acceleration = 0;
17
  int32_t decceleration = 0;
18
  uint8_t positivedirection = 0;
19
  uint8_t accelerate = 0;
20
  uint32_t temp_vel = 0;
21
  uint32_t temp_vel_sq = 0;
22
  
23
  if (Motor->direction*Motor->targetvelocity > max_speed) //not faster than allowed
24
    {
25
      Motor->targetvelocity = Motor->direction*max_speed;  
26
    }
27
//update backup registers
28
  Motor->position = *(Motor->motorturns)*fullsteps_per_rev + Motor->handle.htim_ascounter->Instance->CNT / microsteps;
29
  *(Motor->counterreg) = Motor->handle.htim_ascounter->Instance->CNT;
30
  
31
//check general status
32
  if ((Motor->direction >= 0) && (Motor->targetvelocity > 0))
33
  {
34
    positivedirection = 1;
35
    if (Motor->targetvelocity > Motor->velocity_in_steps)
36
    {
37
      accelerate = 1;
38
    }
39
  }
40
  else if( (Motor->direction <= 0) && (Motor->targetvelocity < 0) )
41
    if (Motor->targetvelocity < Motor->velocity_in_steps)
42
    {
43
      accelerate = 1;
44
    }
45
46
  //check if we will hit a limit
47
  temp_vel = (abs(Motor->velocity_in_steps) + microsteps / 2) / microsteps;
48
  temp_vel_sq = temp_vel * temp_vel;
49
  //(full)steps we need to break   s=v^2/2a
50
  Motor->stepstostop = temp_vel_sq / (2*deccel_raw);// + temp_vel_sq*Motor->cellerate / (deccel_raw / jerkstepsdecc);
51
  if(positivedirection)
52
  {
53
    if((max_ml*factor_ml2steps - Motor->min_volume_steps) - (Motor->position) <= (Motor->stepstostop))
54
    {
55
      Motor->targetvelocity = 0;
56
      accelerate = 0;
57
    }
58
  }
59
  else
60
  {
61
    if((Motor->position) - (max_ml*factor_ml2steps - Motor->max_volume_steps) <= (Motor->stepstostop))
62
    {
63
      Motor->targetvelocity = 0;
64
      accelerate = 0;
65
    }
66
  }
67
  
68
  //if we want to stop, we should disable motor when we are at 0 steps/sec
69
  if (Motor->targetvelocity == 0) 
70
    {
71
      if ((Motor->direction*Motor->velocity_in_steps <= jerkdec)) //only disable when enabled
72
        {
73
          Disable_Motor(Motor);
74
          Motor->velocity_in_steps = 0;
75
          Motor->cellerate = 0;
76
          return 0;
77
        }
78
    }
79
  //keep velocity when we are already having it
80
  else if (Motor->targetvelocity == Motor->velocity_in_steps)
81
  {
82
    if (Motor->cellerate == 0 || Motor->cellerate == 1 || Motor->cellerate == -1)
83
    {
84
      Motor->cellerate = 0;
85
      return 0;
86
    }
87
  }
88
  
89
//calculate the acceleration
90
  int32_t diff = abs(Motor->targetvelocity - Motor->velocity_in_steps);
91
  //target is far away
92
  if(diff > 0.5*Motor->cellerate*(Motor->cellerate + 1)*jerkacc)
93
  {
94
    if (accelerate) //faster to target velocity
95
    {
96
      Motor->cellerate++;
97
    }
98
    else //faster to lower velocity
99
    {
100
      Motor->cellerate--;
101
    }
102
  }
103
  else //start to reduce acceleration
104
  {
105
    if (accelerate) 
106
    {
107
      Motor->cellerate--;
108
    }
109
    else //reduce decceleration
110
    {
111
      Motor->cellerate++;
112
    }
113
  }
114
  
115
  if (Motor->cellerate > jerkstepsacc)
116
  {
117
    Motor->cellerate = jerkstepsacc;
118
  }
119
  else if (Motor->cellerate < -jerkstepsdecc)
120
  {
121
    Motor->cellerate = -jerkstepsdecc;
122
  }
123
        
124
  if (Motor->cellerate < 0)
125
  {
126
    acceleration = jerkdec * Motor->cellerate;
127
    if (Motor->cellerate == -1)
128
    {
129
      if (-diff > acceleration)
130
      {
131
        acceleration = -diff;
132
      }
133
    }
134
  }
135
  else
136
  {
137
    acceleration = jerkacc * Motor->cellerate;
138
    if (Motor->cellerate == 1)
139
    {
140
      if (diff < acceleration)
141
      {
142
        acceleration = diff;
143
      }
144
    }
145
  }  
146
  
147
  if (Motor->velocity_in_steps == 0) //when we start driving, enable motor
148
  {
149
    Enable_Motor(Motor);
150
    if (Motor->targetvelocity < 0)
151
    {
152
      Motor_Direction_LEFT(Motor);
153
    }
154
  }  
155
  
156
  Motor->velocity_in_steps += acceleration;
157
158
  if (Motor->velocity_in_steps == 0)  //calculate the timer 
159
  {
160
    timervaluebuffer = timer_maxvalue; //not divide through 0
161
  }
162
  else
163
  {
164
    timervaluebuffer = timer_clock / abs(Motor->velocity_in_steps);
165
    if (timervaluebuffer > timer_maxvalue)
166
    {
167
      timervaluebuffer = timer_maxvalue; //just ignore that we cant go slower
168
    }
169
  }
170
  __HAL_TIM_SET_AUTORELOAD(Motor->handle.htim, timervaluebuffer);
171
  return 0;
172
}

von Wolfgang (Gast)


Lesenswert?

Gerald M. schrieb:
> Deshalb würde ich gerne linear Beschleunigen, da ich vermute dass genau
> dieser Ruck zum Schrittverlust führt.

Du brauchst eine konstante Beschleunigung, i.e. die Geschwindigkeit muss 
sich linear ändern. Schrittverluste bekommst du bei zu schneller 
Geschwindigkeitsänderung.
Hast du die Atmel AppNote AVR446 - Linear speed control of stepper motor 
gelesen (jetzt MicroChip AN_8017 ).
http://ww1.microchip.com/downloads/en/AppNotes/doc8017.pdf

Wenn bei deinem Aufbau beim Ändern der Beschleunigung Schwingungen 
angeregt werden können, musst du zur Vermeidung zusätzlich dafür sorgen, 
dass der Ruck nur niedrige Werte annimmt.

von Achim M. (minifloat)


Lesenswert?

Gerald M. schrieb:
> Um den "zeig mal her was du hast" "Antworten", bei denen danach keine
> Antwort mehr kommt im Voraus etwas entgegenzuwirken, hier einmal mein
> Code.

Um den "Pack den Code in den Anhang" "Antworten", bei denen danach keine 
Antwort mehr kommt im Voraus etwas entgegenzuwirken, Pack den Code in 
den Anhang.

Anmerkungen: Du weißt jederzeit wie lang deine Bremsrampe in Schritten 
ist? Dann musst du vor erreichen des Zylinderendes eben schauen, ob 
diese Anzahl Schritte noch in den restlichen Verfahrweg passen.

Für Vorausberechnung von Rampen kannst du, um Strecke, Geschwindigkeit, 
Beschleunigung, Ruck/Jerk in n-ter Ableitung ohne Sprungstellen zu 
haben, zum Beispiel (cos(x) + 1)/2 benutzen.

mfg mf

von Spess53 (Gast)


Lesenswert?

Hi

Such mal nach AN_8017. Da hat Atmel das vor 15 Jahren schon vorgekaut.

MfG Spess

von Gerald M. (gerald_m17)


Lesenswert?

Wolfgang schrieb:
> Du brauchst eine konstante Beschleunigung, i.e. die Geschwindigkeit muss
> sich linear ändern. Schrittverluste bekommst du bei zu schneller
> Geschwindigkeitsänderung.

Nein, ich hätte gerne eine lineare Beschleunigung, also einen konstanten 
"Ruck" (Ruck ist die Ableitung der Geschwindigkeit). Eine konstante 
Beschleunigung hatte ich bereits davor implementiert.

Achim M. schrieb:
> Anmerkungen: Du weißt jederzeit wie lang deine Bremsrampe in Schritten
> ist?

Nein, das wusste ich vorher, als die Beschleunigung noch kosntant war. 
Da ist es einfach (tatsächlich ist die Formel so noch im Sourcecode, da 
ich dachte dass es eventuell nicht so viel ausmacht. Auch ist das 
Vergleichen der Schritte zum Ende noch drin). Jetzt ist es komplizierter 
zu rechnen.

Achim M. schrieb:
> Beispiel (cos(x) + 1)/2 benutzen

was heißt hier x? Mit diesem Satz kann ich leider nichts anfangen. Wo 
ist hier Beschleunigung und Ruck?

Spess53 schrieb:
> Such mal nach AN_8017. Da hat Atmel das vor 15 Jahren schon vorgekaut.

Nein haben sie nicht.

von Wolfgang (Gast)


Lesenswert?

Gerald M. schrieb:
> Nein, ich hätte gerne eine lineare Beschleunigung, also einen konstanten
> "Ruck" (Ruck ist die Ableitung der Geschwindigkeit). Eine konstante
> Beschleunigung hatte ich bereits davor implementiert.

Schon bei konstanter Beschleunigung bekommst du bei Antrieb einer fest 
an den Motor angekoppelten Masse keine Schrittverluste, weil konstante 
Beschleunigung konstantes Drehmoment bedeutet und das Drehmoment die 
Ursache für den Lastwinkel ist.
Mit dem Ruck hat das nur zu tun, wenn die Schwingfähigkeit deines 
Systems die Ursache ist. Du kannst entweder wild rumpobieren oder du 
analysierst dein anzutreibendes System.

von Hugo H. (hugo_hu)


Angehängte Dateien:

Lesenswert?

Damit kannst Du rumspielen - die Formeln sind auch zu sehen - muss nur 
umgesetzt werden. Ich habe Code für den ATXMega dazu - aber "sehr 
speziell" :-)

von Gerald M. (gerald_m17)


Lesenswert?

Wolfgang schrieb:
> Gerald M. schrieb:
>> Nein, ich hätte gerne eine lineare Beschleunigung, also einen konstanten
>> "Ruck" (Ruck ist die Ableitung der Geschwindigkeit). Eine konstante
>> Beschleunigung hatte ich bereits davor implementiert.
>
> Schon bei konstanter Beschleunigung bekommst du bei Antrieb einer fest
> an den Motor angekoppelten Masse keine Schrittverluste, weil konstante
> Beschleunigung konstantes Drehmoment bedeutet und das Drehmoment die
> Ursache für den Lastwinkel ist.
> Mit dem Ruck hat das nur zu tun, wenn die Schwingfähigkeit deines
> Systems die Ursache ist. Du kannst entweder wild rumpobieren oder du
> analysierst dein anzutreibendes System.

Hi,
danke, ich weiß das. Ich kenne auch die Energieverteilung für die 
Frequenzen. Und bei mir hat selbst eine deutliche Anhebung des Stroms 
nicht wirklich geholfen, weshalb ich eben jetzt "ruckfrei" anfahren und 
Bremsen möchte.

Hugo H. schrieb:
> Damit kannst Du rumspielen - die Formeln sind auch zu sehen - muss nur
> umgesetzt werden. Ich habe Code für den ATXMega dazu - aber "sehr
> speziell" :-)

Danke auch dir, ich kann leider erst später rein schauen.

von Wolfgang (Gast)


Lesenswert?

Gerald M. schrieb:
> danke, ich weiß das. Ich kenne auch die Energieverteilung für die
> Frequenzen.

Warum sagst du dann "... ich vermute ..."

Hast du es schon mal mit einem Rotationsdämpfer probiert um die Güte 
deines Systems zu reduzieren?

von Gerald M. (gerald_m17)


Lesenswert?

Ich vermute es weil ich es noch nicht mit linearer Beschleunigung testen 
konnte.

Der Aufbau ist fix, daran kann ich nicht wirklich etwas ändern. Ist ein 
Schrittmotor auf Gummipuffern, der über ein Zahnrad und Riemen an die 
Spindel verbunden ist.
Eigentlich sollte das System auch recht gut gedämpft sein, da ja der 
Kolben über die Kolbenringe an der Zylinderwand rutscht. Aber gerade die 
haben ja auch etwas Spiel, da sie nicht direkt gleiten sondern erst noch 
etwas haften. Das merkt man schon beim Drehen mit der Hand. Der Riemen 
sollte sich etwas dämpfen.
Es ist auch immer nur ein kurzer Moment in dem er Schritte verliert.

Achja, und ich habe außerdem keinen Rotationsdämpfer (und auch keinen 
Platz am Motor um ihn zu montieren)

von Walter T. (nicolas)


Lesenswert?

Kannst Du so ein Pulspaket einer Rampe loggen (Zeitstempel)?

Nicht, dass Du durch das Herumschreiben im Timer innerhalb der Pulsdauer 
Pulse verlierst und in Wirklichkeit nur ein riesiger Jitter Dein Problem 
ist.

: Bearbeitet durch User
von Hugo H. (hugo_hu)


Lesenswert?

Gerald M. schrieb:
> Es ist auch immer nur ein kurzer Moment in dem er Schritte verliert.

2 Möglichkeiten (aus meiner Sicht):

1. Anfahren ("quietschende Reifen" wegen fehlender Rampe -> Excel)
2. Resonanzfrequenz 
(http://www.goetz-automation.de/Schrittmotor/Resonanzen.htm) Dort sind 
Gegenmaßnahmen beschrieben.

Das wäre meine erste Adresse, wenn ich es nicht hinbekomme: 
https://www.mikrocontroller.net/user/show/ostermann

: Bearbeitet durch User
von Carsten-Peter C. (carsten-p)


Lesenswert?

Hallo,
ich habe auch lange Zeit Probleme mit Schrittverlusten bei meinem 
Selbstbau-Plotter gehabt. Erst der Einbau von einem Motortreiber mit 
Mikroschritt brachte Abhilfe. Geht meinetwegen ein Achtelschritt 
verloren, stimmt die Position beim nächsten Schritt wieder. Der Motor 
läuft auch deutlich ruhiger.
Gruß Carsten

von Wolfgang (Gast)


Lesenswert?

Carsten-Peter C. schrieb:
> Geht meinetwegen ein Achtelschritt
> verloren, stimmt die Position beim nächsten Schritt wieder.

Ein einzelner Achtelschritt kann bei einem Schrittmotor nicht verloren 
gehen. Wenn das wirklich passiert sein sollte, sind Pulse woanders 
hängen geblieben.

von Carsten-Peter C. (carsten-p)


Lesenswert?

Wolfgang schrieb:
> Ein einzelner Achtelschritt kann bei einem Schrittmotor nicht verloren
> gehen.

Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren. 
Nach meinen Erfahrungen dann, wenn der Motor einen Schritt macht, durch 
den Schwung schon ein wenig weiterdreht, zurückgezogen wird und dann 
erst den neuen Vorwärtsschritt bekommt. Also besonders bei einer flachen 
Linie bzw. ungünstigen Drehzahlen. Nach Umstellung auf Achtelschritt war 
das Problem beseitigt. Die Rampe hat da bei meinem Projekt eine eher 
kleinere Rolle gespielt.
Gruß Carsten

von Wolfgang (Gast)


Lesenswert?

Carsten-Peter C. schrieb:
> Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren.

Schritte können in allen Schrittmodi verloren gehen, aber eben nicht als 
Einzelschritt. Bei Vollschrittbetrieb entsteht ein Versatz von 
Vielfachen von 4 Schritten, bei Halbschritt von 8 Schritten usw.
Wenn Mikroschrittbetrieb zu weniger Fehlern führt, liegt das an 
Resonanzen/Schwingungsanregung.

von Gerald M. (gerald_m17)


Lesenswert?

Walter T. schrieb:
> Kannst Du so ein Pulspaket einer Rampe loggen (Zeitstempel)?
> Nicht, dass Du durch das Herumschreiben im Timer innerhalb der Pulsdauer
> Pulse verlierst und in Wirklichkeit nur ein riesiger Jitter Dein Problem
> ist.

Sollte tatsächlich nicht so sein, da der STM32 ja ein Shadow Register 
(falls das der richtige Name ist) hat, der den neuen Wert erst nach 
einem Interrupt ändert, um genau das zu vermeiden.

Ansonsten kann ich noch erwähnen, dass ich 256x Mikroschritte nutze 
(Treiber ist der TMC2660) weshalb ich auch nicht daran glaube dass 
einzelne Pulse verloren gehen (auch wenn ich mit sehr hoher Rate den Pin 
toggle).

Der Treiber hat auch umfangreiche Einstellungsmöglichkeiten, wobei ich 
bisher meist Datenblatt- Standardwerte nutze.

Aber wie gesagt, es ist eben sehr auffällig dass in bestimmten 
Situationen die Schritte verloren gehen. (Genau dann wenn eben 
Resonanzen angeregt werden können)

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo Gerald,

"sollte" ist bei mir ein häufiger Faktor, der ein Erschwerung der 
Fehlersuche bewirkt. Aber das ist erst einmal meine private Meinung.

Gerald M. schrieb:
> Ich weiß ich habe schon einmal irgendwo eine Implementierung für
> 3D-Drucker irgendwo gesehen, bei der auch eine hervorragende Erklärung
> mit dabei war, leider finde ich diese nicht.

Bei 3d-Druckern ist der "Jerk" aber etwas anderes. Er ist die 
physialisch inkorrekte Bezeichnung dafür, dass die Geschwindigkeitsrampe 
nicht bei der Geschwindigkeit 0 startet, sondern bei einer höheren 
Geschwindigkeit. Das ist bei vielen Schrittmotor-Antrieben möglich 
(siehe Skizze).

Gerald M. schrieb:
> Ansonsten kann ich noch erwähnen, dass ich 256x Mikroschritte nutze
> (Treiber ist der TMC2660)

Mit den kleinen Treibern habe ich wenig Erfahrung, aber bei den größeren 
sind kleinere Mikroschritt-Faktoren oft gutmütiger.

Aber wenn das Problem wirklich ein Resonanzeffekt ist, besteht die 
einzige echte Lösung darin, im Resonanzbereich nur so kurz wie möglich 
zu sein. Klassiker, der hier im Thread an mehreren Stellen vorgeschlagen 
wurde, waren dämpfende Elemente, die auch die Resonanzfrequenz absenken. 
Die andere Variante ist, das System steifer zu machen, die 
Resonanzfrequenz also anzuheben und unterhalb der Resonanzfrequenz zu 
operieren.

Aber ich würde jetzt erst einmal den "sollte"-Teil überprüfen. Das hält 
den Rücken frei.

von Wolfgang (Gast)


Lesenswert?

Walter T. schrieb:
> Aber wenn das Problem wirklich ein Resonanzeffekt ist, besteht die
> einzige echte Lösung darin, im Resonanzbereich nur so kurz wie möglich
> zu sein.

Das ist keine Garantie. Die Resonanzschwingung kann genauso gut durch 
einen Sprung in der Beschleunigung, i.e. durch den Ruck angeregt werden.

von Walter T. (nicolas)


Lesenswert?

Wolfgang schrieb:
> Das ist keine Garantie. Die Resonanzschwingung kann genauso gut durch
> einen Sprung in der Beschleunigung, i.e. durch den Ruck angeregt werden.

Bei einem Schrittmotor-Spindeltrieb bin ich Herr über die Positionsebene 
(Ort, Geschwindigkeit, Beschleunigung, Ruck) - ansonsten läuft 
irgendetwas schief. Angeregt werden kann nur über die Kraftebene.

von Wolfgang (Gast)


Lesenswert?

Walter T. schrieb:
> Angeregt werden kann nur über die Kraftebene.

Eben. Und wenn mit dem in der Atmel AppNote AVR446 beschriebenen 
Algorithmus die Beschleunigung hart umgeschaltet wird, tritt eine harte 
Kraftänderung und damit ein hoher Wert für den Ruck auf. Da hat Gerald 
schon Recht. Deshalb oben die explizite Frage nach der Schwingfähigkeit 
seines Systems ...

von Karl (Gast)


Lesenswert?

Man definiere bitte mal was ein Ruck sein soll? Und woher weißt du das 
du überhaupt Schrittverluste hast? Hast du dir mal Gedanken über 
Massenträgheit gemacht? Und das mit den Resonanzen hast du auch noch 
nicht so verstanden. Zur Anregung reichen Imperfektionen. Und wenn du 
eine "lineare Beschleunigung willst, sollte das dann nicht wenigsten 
bi-linear sein, oder willst du wirklich einen Sägezahn? Ich frag mich 
auch, wenn du alle 10 ms nachregelst, wo das noch die Zeit für solch 
Spielerei sein soll.
Ich würde behaupten dein Regler/Regelkreis schwingt (Vollgas/Bremse) und 
davon gibt dein "Ruck".

von Robert M. (r_mu)


Lesenswert?

Gerald M. schrieb:
>
> Ich weiß ich habe schon einmal irgendwo eine Implementierung für
> 3D-Drucker irgendwo gesehen, bei der auch eine hervorragende Erklärung
> mit dabei war, leider finde ich diese nicht. Ich meine da wurden sogar
> noch weitere Ableitungen als nur der Jerk mit beachtet.
>

möglicher das da 
https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained

Die verwenden Bezier-Kurven um das Geschwindigkeitsprofil zu erzeugen. 
Von einer konstanten Geschwindigkeit zu einer anderen wird die 
Beschleunigung über so eine Bezier-Kurve "erzeugt" in der Art, dass zu 
Beginn/Ende nicht nur die Beschleunigung = 0 ist, sondern auch der Ruck 
und die Ableitung des Rucks 0 sind.

Die Bezier-Polynome haben einige "schöne" Eigenschaften und es gibt 
Haufen Literatur und Algorithmen in der Computergrafik dazu.

Soweit ich mich erinnere ist im Code auch eine brauchbare Erklärung zu 
finden wie man das alles per "forward differentiation" auf einem µC in 
vernünftiger Geschwindigkeit umsetzt.

von Robert M. (r_mu)


Lesenswert?

Karl schrieb:
> Man definiere bitte mal was ein Ruck sein soll?

Ruck ist die Änderung der Beschleunigung (nicht der Geschwindigkeit wie 
weiter oben irgendwo geschrieben, vermutlich Tippfehler).

Näherungsweiser Vergleich mit Gaspedal/Bremspedal am Auto: konstante 
Beschleunigung würde heissen, beim Beschleunigen / Bremsen die 
Pedalstellung sprunghaft zu ändern und dann so zu halten, also z.B. 
Vollgas zu geben (bzw. Vollbremsung zu machen). Abrupte Betätigung des 
Gas- oder Bremspedals erzeugt einen Ruck. Darum betätigt man Fahr- und 
Bremspedal im Normalfall nicht ruckartigt.

von Wolfgang (Gast)


Lesenswert?

Karl schrieb:
> Man definiere bitte mal was ein Ruck sein soll?

Ruck ist die Ableitung der Beschleunigung nach der Zeit
https://de.wikipedia.org/wiki/Ruck

von NichtWichtig (Gast)


Lesenswert?

Gerald M. schrieb:
> Hallo,
>
> ich habe einen Schrittmotor über eine Spindel an einen Kolben verbunden,
> um eine Flüssigkeit mit einer gewissen Geschwindigkeit ausströmen zu
> lassen.
>
> Die Sollgeschwindigkeit bekomme ich aus einem Regler alle 10ms. Jede
> Millisekunde berechne ich momentan die aktuelle Frequenz des Timers der
> die Pulse für den Motor ausgibt.
> Kann jemand was zu diesen Zeiten sagen?

Meiner Meinung nach der falsche Ansatz dort im Zeitinterval etwas zu 
machen.

Ich hatte vor Jahren sowas ähnliches programmiert und dort war der 
aktuelle Impuls Basis für den nächsten Step.
Somit war sicher gestellt das von Step zu Step exakt die gewünschte 
Beschleunigung/Verzögerung dem Motor gegeben wurde.
Nur so konnte er die Last sauber ohne Schrittverluste (und damit 
Totalverlust) hoch fahren.

Die Magie liegt in der exponentiellen Kurve, Taktfrequenz, Timergröße 
und so.
Ich hatte das mit einem 8051 in Assembler realisiert und für die 
Timerwerte ein 512 Byte großes Array berechnet.
Die untere Hälfte wurde der Timerinterrupt mehr als einmal benutzt bevor 
ein neuer Step zum Motor ging, aber der Mitte wars dann nur noch einer 
und je schneller es wurde desto kleiner wurde der Timerwert.

Auch wurde klar das am Ende der Beschleunigung ein Wechsel von a auf 0 
ebenfalls ein Problem darstellt.

Die bereits angesprochenen Bezier-Kurven sind da durchaus eine 
Möglichkeit.

von Udo S. (urschmitt)


Lesenswert?

Mal quergedacht (nicht im Sinne der Querschläger!)

Könnte es sein, dass der Schrittverlust etwas mit dem Losbrechmoment des 
Kolbens zu tun hat.
Jeder der mal eine Einwegspritze in der hand hatte weiss, dass man ein 
deutlich höheres Moment braucht bis der Kolben in Bewegung kommt.

von Achim M. (minifloat)


Lesenswert?

Gerald M. schrieb:
> Achim M. schrieb:
>
>> Beispiel (cos(x) + 1)/2 benutzen
>
> was heißt hier x? Mit diesem Satz kann ich leider nichts anfangen. Wo
> ist hier Beschleunigung und Ruck?

x die Zeit und das Ergebnis der Weg.
Plotte dir das mal von x=[0...π] dann kannst du vielleicht was damit 
anfangen.

Warum einen COS benutzen? Tja, ...
Die erste Ableitung Geschwindigkeit ist dadurch schon mal stetig und 
ohne Knicke.
Die zweite Ableitung Beschleunigung ist dadurch schon mal stetig und 
ohne Knicke.
Die dritte Ableitung Ruck ist damit schon mal stetig und ohne Knicke.
Die vierte ...
mfg mf

von Achim M. (minifloat)


Lesenswert?

PS. Da der COS eine Steigung von 1 im Wendepunkt hat, kann man diesen 
Zustand beliebig lang beibehalten. Das wäre dann die normierte 
Geschwindigkeit '1'.

von Gerald M. (gerald_m17)


Lesenswert?

Zunächst einmal danke für die ganzen Antworten.

Nein nächstes Vorgehen wird so sein:

Ich werde auf Fehlersuche in meinem Code gehen. Grundsätzlich 
funktioniert er ja, nur die "Abbruchbedingung" für das Beschleunigen ist 
nicht ganz korrekt weshalb immer um die Zielgeschwindigkeit 
"geschwungen" wird.

Des Weiteren werde ich überprüfen ob ich die Gummi-Halterungen des 
Motors entweder gegen härtere eintausche oder ganz entferne. Ich hatte 
sie eingebaut um die Übertragung der Motorgeräusche auf den Rahmen zu 
vermindern. Allerdings hatte das keinen wirklichen Effekt, da die 
Motoren durch die Mikroschritte sowieso recht ruhig sind. Ich habe sie 
dann drin gelassen weil ich dachte sie Schaden nicht. Ich kann mit 
nämlich auch vorstellen dass durch den Ruck beim plötzlichen 
Beschleunigen auch der ganze Motor Recht weit bewegt wird was sicher 
nicht gut ist.

Funktioniert alles soweit, werde ich die lineare Beschleunigungsrampe 
(ich teile momentan die maximale Beschleunigung durch 50 und diese wird 
dann eben um diese Schritte erhöht) durch eine Look-up-Table erweitern, 
dass ich keine lineare Beschleunigungsrampe habe, sondern eben eine 
Cos-artige. Das gefällt mir. Vermutlich werde ich mir dann die Schritte 
bis zur vollen Beschleunigung entweder ebenfalls per LUT berechnen, da 
ich ja momentan von einer linearen Rampe ausgehe (bei 30/50 der 
Beschleunigung brauche ich ja 0.5*30*31/50 an Teilen der Bescheinigung 
zum bremsen)

Außerdem werde ich noch nach der Anleitung des Treiber-Herstellers und 
mit einem Oszilloskop die Ansteuerung des Motors optimieren.


Ich melde mich. Ergänzungen sind auch in der Zwischenzeit willkommen.

von Gerald M. (gerald_m17)


Angehängte Dateien:

Lesenswert?

Also der Code läuft schonmal.

Das ganze sieht jetzt aus wie angehängt. Scope3 zeigt die 
Geschwindigkeit bei zwei Steps von 0 auf 2, dann wieder auf 0 und am 
Ende auf 5.
DBG1 zeigt die momentane Beschleunigung. Diese habe ich in 500 Teile 
unterteilt.
Ich habe "etwas" Jitter auf den Messungen, da ich die Schritte usw. via 
TCP/IP alle 50ms in Simulink hole und auch die Sollwerte für den Flow in 
Simulink stelle.
Man sieht, dass meine Rechnung nicht ganz korrekt ist, so dass der 
Controller manchmal doch noch etwas beschleunigen/bremsen muss um die 
Zielgeschwindigkeit exakt zu treffen (siehe Zoom.png). Das ist aber 
minimal und ich werde es verschmerzen.

von Tom (Gast)


Lesenswert?

Hallo Gerald,

Gerald M. schrieb:
> Wolfgang schrieb:
>> Du brauchst eine konstante Beschleunigung, i.e. die Geschwindigkeit muss
>> sich linear ändern. Schrittverluste bekommst du bei zu schneller
>> Geschwindigkeitsänderung.
>
> Nein, ich hätte gerne eine lineare Beschleunigung, also einen konstanten
> "Ruck" (Ruck ist die Ableitung der Geschwindigkeit). Eine konstante
> Beschleunigung hatte ich bereits davor implementiert.

Ruck ist die Ableitung der Beschleunigung. Im Umkehrschluss bedeutet 
linear steigende Beschleunigung quadratisch steigende Geschwindigkeit. 
Und da hast du die Ursache für deine Schrittverluste ;)

Du suchst also besser nach einer Ruck-begrenzten Beschleunigungsrampe.
https://de.wikipedia.org/wiki/Ruck

Gruß
Tom

von 123 (Gast)


Lesenswert?

Ich wünsch viel spass, ...

Riehmen antrieb bedeutet Federsystem, ... Beim anfahren spannst du erst 
den riehmen, bis die spannung in dem System so gross ist die Haftreibung 
deines Kolbens zu überwinden. Dabei lägt sich auch der rimen ein wenig. 
Danach zieht sich der rimen wieder zusammen, ...

Deine Maximale beschleunigung wird abhäng von der geschwindigkeit sein. 
Hier spiel ja auch reibungsverhältisse der Mechanik, Drehmoment des 
Motors, ... alles mit rein. Und das ganze ist sicher über die Zeit / 
Temperatur nicht konstant, ...

Bremsen, ... ist auch so eine kust für sich, ... je nach mechanik, und 
vorgabe muss man langsam runter fahren, oder es reicht abschalten / 
windungen kurzschliessen, oder mann muss ggf sogar hart "gegen 
bestromen"

Beitrag #6728922 wurde vom Autor gelöscht.
von Gerald M. (gerald_m17)


Angehängte Dateien:

Lesenswert?

Hallo Tom,

ja, die Geschwindigkeit läuft quadratisch hoch und runter.
Aber nur bis die Beschleunigung ihren maximalen Wert erreicht hat. Dann 
hält die Beschleunigung ihn, was zu einer linear zunehmenden 
Geschwindigkeit führt. Daraus resultiert ein S-förmiger Verlauf der 
Geschwindigkeit --> keine Schrittverluste.
Wie die Beschleunigung und die Geschwindigkeit dann aussehen siehst du 
außerdem in meinem Post genau über deinem.

@123

Läuft schon :)
Für das Bremsen habe ich einen eigenen "Beschleunigungswert". Im Moment 
ist er so groß wie die positive Beschleunigung, allerdings kann man ihn 
vermutlich deutlich größer machen (= schneller bremsen als losfahren). 
Das ist aber nicht nötig.

von He. (Gast)


Lesenswert?

Gerald M. schrieb:
> Deshalb würde ich gerne linear Beschleunigen,

Das führt aber auch zu einem Puls, weil die 1. Ableitung konstant ist. 
Das ist so, wie eine Wasserwelle vor dir herschieben. Bei Motoren haben 
wir aber mit zunehmender Geschwindigkeit steigende Verluste und 
Getriebeschwingungen. Damit muss immer mehr Strom eingeprägt werden, 
dessen Verluste dann nichtlinear in Schwingungen und Reibung gehen. Das 
födert das Ruckeln.

von He. (Gast)


Lesenswert?

Carsten-Peter C. schrieb:
> Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren.

Das stimmt nicht ganz. Wenn der Motor anfängt, hinterher zu hinken, dann 
ist der Verlust da und gfs nicht mehr zu kompensieren. Nur Messen kann 
man ihn direkt nur bei einem Vollschritt. Dazwischen ist 
Signalauswertung gefragt.

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


Lesenswert?

Hallo,

Carsten-Peter C. schrieb:
> Wolfgang schrieb:
>> Ein einzelner Achtelschritt kann bei einem Schrittmotor nicht verloren
>> gehen.
>
> Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren.
> Nach meinen Erfahrungen dann, wenn der Motor einen Schritt macht, durch
> den Schwung schon ein wenig weiterdreht, zurückgezogen wird und dann
> erst den neuen Vorwärtsschritt bekommt. Also besonders bei einer flachen
> Linie bzw. ungünstigen Drehzahlen. Nach Umstellung auf Achtelschritt war
> das Problem beseitigt.

Das zeigt nur, dass die Resonanzen reduziert wurden und damit die 
Auftrittswahrscheinlichkeit für Schrittverluste. Auftreten können 
Schrittverluste aber auch bei Mikroschritt, spätestens wenn die Last das 
aktuelle Drehmoment des Motors überschreitet.

Mit freundlichen Grüßen
Thorsten Ostermann

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


Lesenswert?

Hallo Harald,

Harald E. schrieb:
> Carsten-Peter C. schrieb:
>> Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren.
>
> Das stimmt nicht ganz. Wenn der Motor anfängt, hinterher zu hinken, dann
> ist der Verlust da und gfs nicht mehr zu kompensieren. Nur Messen kann
> man ihn direkt nur bei einem Vollschritt. Dazwischen ist
> Signalauswertung gefragt.

Nein, du wirfst hier Schleppfehler/Lastwinkel und Schrittverlust 
durcheinander. Ein Schrittmotor im open-loop Betrieb kann man sich 
Modellhaft als Drehfeder vorstellen. Diese Feder wird unter Last 
ausgelenkt. Zu dieser Last gehören auch die beim Beschleunigen 
auftretenden dynamischen Anteile. Die gleichen sich beim Abbremsen 
wieder aus. Nur wenn das Last-Drehmoment zu groß wird, "reißt" die 
Feder. Der Motor verliert Schritte, kann dem Drehfeld nicht mehr folgen 
und kommt aus dem Tritt.

Einzelne "verlorene" Schritte gibt es dynamisch eigenlich nicht. Das 
sind dann in der Regel Fehler die durch EMV auf den Taktleitungen oder 
Softwarefehler entstehen.

Mit freundlichen Grüßen
Thorsten Ostermann

von Carsten-Peter C. (carsten-p)


Lesenswert?

Thorsten O. schrieb:
> Hallo Harald,
>
> Harald E. schrieb:
>> Carsten-Peter C. schrieb:
>>> Schritte gehen eigentlich nur im Vollschritt und Halbschritt verloren.
>>

Hallo,
stell Dir vor, der Motor steht und die folgende Mikroschritte bewegen 
den Motor bedingt durch seine zu treibende Last  nicht. Dann wird 
irgendwann nach den folgenden Schritten die Kraft groß genug sei, um den 
Motor auf seine Position zu „ziehen“. Er läuft wieder „richtig“ oder 
schafft es gar nicht. Schafft er es beim Vollschritt nicht, ist der 
Versatz da. Mein Plotter läuft im 1/8 Schritt am Besten. Meine SW habe 
ich in Assembler für den ATmega 1284 geschrieben. Anfangsgeschwindigkeit 
und Rampenlänge lassen sich in weiten Bereichen einstellen. Sicher ist 
es nicht so einfach das Programm nachzuvollziehen, aber wenn es Dir 
hilft kann ich es Dir gerne schicken.
Gruß Carsten

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


Lesenswert?

Hallo Carsten,

wen sprichst du hier an? Dein Zitat ist so unvollständig dass man nicht 
erkennen kann wen du eigentlich meinst...

Ich glaube dir gerne, dass dein Programm funktioniert. Trotzdem ist das 
was du beschreibst kein Schrittverlust, sondern der Lastwinkel. Der 
Fehler wird ja beim weitersteppen oder beim Wegfall der Last wieder 
ausgeglichen.

Mit freundlichen Grüßen
Thorsten Ostermann

von Carsten-Peter C. (carsten-p)


Lesenswert?

Hallo Thorsten,
ich wollte eigentlich nur nett sein und Gerald M. mein Programm 
anbieten. Die Idee war, über die serielle Schnittstelle kurz die 
anzulaufende Position zu übermitteln. Also z.B. lauf mal zur Position 3 
cm. Ob es passt, kann ich nicht beurteilen. Ich wollte niemanden 
kritisieren.
Gruß Carsten

von Gerald M. (gerald_m17)


Lesenswert?

Hallo Carsten,

vielen Dank für dein Angebot. Ich habe allerdings meine Software schon 
in c geschrieben und sie funktioniert auch. Vielleicht interessiert es 
dennoch jemand anderes und du kannst ja trotzdem deinen Code anhängen :)
Oft sucht man ja etwas im Internet und ist froh wenn jemand etwas 
hochgeladen hat, weil man genau das gesucht hat.

Liebe Grüße
Gerald

von He. (Gast)


Lesenswert?

Carsten-Peter C. schrieb:
> stell Dir vor, der Motor steht und die folgende Mikroschritte bewegen
> den Motor bedingt durch seine zu treibende Last  nicht. Dann wird
> irgendwann nach den folgenden Schritten die Kraft groß genug sei, um den
> Motor auf seine Position zu „ziehen“.

Nicht nur das, der Motor kann ja per Ansteuerung in einem Mikroschritt 
gehalten werden und wenn er nachhinkt, ist auch das schoin ein Problem 
für dynamische Positionierungen. Sowohl im Endzustand als auch auch dem 
Weg dahin.

Ist wie ein Tiefpass, der zu träge ist.

Ja, das ist kein Schrittverlust, im eigentlichen Sinn, aber ein 
Micostep-Verlust. Die Drehposition entspricht nicht der Sollposition.

von Walter T. (nicolas)


Lesenswert?

Harald E. schrieb:
> Die Drehposition entspricht nicht der Sollposition.

Die Drehposition entspricht fast nie der Sollposition. Die IST-Position 
entspricht immer der Soll-Position mit der Auflösung eines Halbschritts 
mit einer lastabhängigen Abweichung - auch bei Mikroschrittbetrieb.

von He. (Gast)


Lesenswert?

Walter T. schrieb:
> Die Drehposition entspricht fast nie der Sollposition.

Im Startfall praktisch schon :-)
Ausserdem regeln wir in der Tat die Drehposition = Sollposition. Die 
Sollposition des Motorankerwinkels ist nur nicht gleich dem des Feldes!

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.