Forum: Mikrocontroller und Digitale Elektronik Schrittmotor beschleunigen mit rampenförmigem Anstieg der Geschwindigkeit


von Stephan S. (ssn)


Lesenswert?

Hallo,

ich versuche über einen PIC32 und einen Schrittmotor-Controller 
(RN-Stepp297) einen Schrittmotor-Antrieb zu steuern. Es handelt sich um 
einen Roboter, der beim Anfahren mit linear ansteigender Geschwindigkeit 
loslegen soll (Beschl. konstant).

Die Rampe will ich imAugenblick dadurch erreichen, dass die Delay-Zeit 
zwischen den Schritten, die der Schrittmotor macht, von einem Startwert 
bis zu einem Endwert immer um den selben Faktor verringert wird.

Ich habe folgenden Code um die "Rampenfunktion" zu realisieren:
1
#define DELAY (4000)  // Wert fuer pause; 0.1 msec bei Timer mit 40 MHz
2
#define MAX_SPEED (10)  // ist der kleinste Wert fuer pause(arg), mit der sich der SM noch gut verhaelt
3
#define START_SPEED (100) // Wert fuer pause(arg) zum Anfahren, wird dekrementiert
4
5
void pause(float uAnz)
6
{
7
  unsigned int uDelay = (unsigned int)uAnz * DELAY; 
8
  TMR23 = 0;
9
  while(TMR23 < uDelay)
10
  { /* do nothing */ }  
11
}
12
13
void drive(int iAnzSteps)
14
{
15
  unsigned short fPause = START_SPEED;
16
  // Drehrichtung festlegen
17
  [...]
18
  // Toggle zwischen GND und High-Level 
19
  // Rampe indem fPause immer um den selben Faktor verringert wird
20
   while( (--iAnzSteps >= 0) && (fPause > MAX_SPEED) )
21
  {
22
    TRISG |= 0x0002; // Pin RG1 als Eingang -> high-Pegel +5V
23
    pause(fPause); 
24
    TRISG &= 0xFFFD; // Pin RG1 als Ausgang -> low-Pegel GND
25
    pause(fPause); 
26
27
    fPause = (fPause * 4) / 5; // Rampe
28
  }
29
  // Toggle zwischen GND und High-Level , max. Speed
30
  while(--iAnzSteps >= 0) // mit max Speed fahren
31
  {
32
    TRISG |= 0x0002;
33
    pause(MAX_SPEED);
34
    TRISG &= 0xFFFD;
35
    pause(MAX_SPEED);
36
  }
37
} // drive()
38
39
int main()
40
{
41
  // Bsp: 400 Vollschritte = 2 Umdrehungen
42
  drive(400);  
43
}

Im Prinzip sollte

fPause = (fPause * 4) / 5; // Rampe

die Geschwindigkeit gleichmäßig ansteigen lassen. Die 
Multiplikation/Division würde ich später durch ganzzahlige Werte in 
einem Array ersetzen.
Aber wenn ich den Motor betrachten scheint er eher langsam anzufahren 
und dann plötzlich sehr schnell zu beschleunigen.

Kann mir jemand einen Tipp geben was ich da falsch mache?

Stephan

von Frank L. (franklink)


Lesenswert?

Hallo Stefan,

wenn ich es richtig sehe, wird fPause durch die Division durch 5 irgend 
wann den Wert 0 unterschreiten. Da Du unsigned short verwendest, gibt es 
keinen negativen Wert für fPause sondern den maximalen Wert für unsigned 
short.

Gruß
Frank

von shagoon (Gast)


Lesenswert?

Die Zeitintervalle, nach denen die Geschwindigkeit erhöht wird, werden 
bei Deiner Lösung mit höherer Geschwindigkeit immer kürzer. Das ergibt 
keine konstante Beschleunigung, sondern die Beschleunigung ist 
proportional zur Geschwindigkeit.

von Michael L. (-mic-)


Lesenswert?

hallo stephan.

> Die Rampe will ich imAugenblick dadurch erreichen, dass die Delay-Zeit
> zwischen den Schritten, die der Schrittmotor macht, von einem Startwert
> bis zu einem Endwert immer um den selben Faktor verringert wird.

das ist natürlich nicht linear.
linear verringern heißt in gleichen zeitabständen einen bestimmten 
betrag subtrahieren.

gruß

michael

von Stephan S. (ssn)


Lesenswert?

@Frank

Hoppla, ich seh jetzt erst dass ich den falschen Typ verwende...das 
fPause soll eigentlich für float stehen...werd ich auf float ändern.
Trotzdem hat mein Code eigentlich so funktioniert wie ich erwartet habe, 
zum Debuggen hab ich die Variable uDelay in der Funktion pause() 
beobachtet. Kleiner als 1 kann der Wert nicht werden weil ich ihn in der 
while-Schleife überprüfe (fPause > MAX_SPEED).

@shagoon

Hm...hast recht, daran hatte ich nicht gedacht. D.h. ich müsste entweder 
mit 'nem Timer arbeiten oder bei steigender Geschwindigkeit die 
Beschleunigung immer langsamer erhöhen, was ich mit festen Werten in 
einem Array erreichen könnte.

@michael

Sicher? Wenn ich von einem Wert immer den gleichen Betrag abziehe dann 
ist es doch nicht linear.
Bsp: Ich ziehe von pause = 16 den wert 1 ab und erhalte Pause = 15. Dann 
ist die Geschwindigkeit 16/15 von der vorherigen Geschwindigkeit.
Wenn ich das weiter so mache ziehe ich irgendwann von pause=2 den Wert 1 
ab und erhalte mit pause(1) die doppelte Geschwindigkeit wie mit 
pause(2).


Vielen Dank für Eure Hinweise, ich werde mal versuchen damit 
weiterzukommen.

Stephan

von Michael L. (-mic-)


Lesenswert?

@Stephan:
upsi. hast recht. war da irgendwie aufm falschen dampfer :-)

gruß

michael

von Karl H. (kbuchegg)


Lesenswert?

Stephan Schwarzmann wrote:

> Sicher? Wenn ich von einem Wert immer den gleichen Betrag abziehe dann
> ist es doch nicht linear.

Doch. Erst mal schon.
Aber es ist nicht die Geschwindigkeit, die sich linear verhält, sondern 
die Pausendauer die von einem Puls zum nächsten vergeht. Sowas nennt man 
aber gwöhnlich die Periodendauer und die steht reziprok zur Frequenz
  f = 1 / t

(und die Frequenz mit der du einen Schrittmotor ansteuerst ist ja 
letztendlich nichts anderes als die Geschwindigkeit mit der er sich 
dreht)

Wenn das t aber linear variiert wird, verhält sich f nicht mehr linear.


Dein t = t * faktor

Ansatz erzeugt aber auch keinen linearen Anstieg in f. Probiers mal im 
Excel aus.

> Bsp: Ich ziehe von pause = 16 den wert 1 ab und erhalte Pause = 15. Dann
> ist die Geschwindigkeit 16/15 von der vorherigen Geschwindigkeit.
> Wenn ich das weiter so mache ziehe ich irgendwann von pause=2 den Wert 1
> ab und erhalte mit pause(1) die doppelte Geschwindigkeit wie mit
> pause(2).

Das beweist eigentlich nur, dass es eine bestimmte Zahl gibt, bei der 
die Addition einer Konstanten 1 der verdopplung der Zahl gleichkommt. 
Hat aber nichts mit Linearität zu tun.

Beispiel: Wenn deine Geschwindigkeit von 20 km/h in jeder Sekunde um 5 
km/h abnehmen soll, dann ist der Zusammenhang

    Sekunden    Geschwindigkeit

      0             20
      1             15
      2             10
      3              5
      4              0

Die Geschwindigkeit nimmt unbestreitbar linear ab. Und trotzdem hast du 
einen Schritt drinnen (10 -> 5), in dem die lineare Abnahme um 5km/h 
genau einer Halbierung der Geschwindigkeit entspricht.


Wenn du die Geschwindigkeit linear ansteigen lassen willst, dann würde 
ich das erst mal auch genau so machen:
Die Geschwindigkeit linear ansteigen lassen (zb. indem man immer eine 
Konstante addiert) und aus dieser Vorgabegeschwindigkeit die benötigte 
Pulsdauer (also deinen Pausenwert) ausrechnen.

von Stephan S. (ssn)


Lesenswert?

>> Sicher? Wenn ich von einem Wert immer den gleichen Betrag abziehe dann
>> ist es doch nicht linear.
>
> Doch. Erst mal schon.
> Aber es ist nicht die Geschwindigkeit, die sich linear verhält, sondern
> die Pausendauer die von einem Puls zum nächsten vergeht.

Ja, hab mich natürlich auf die Geschwindigkeit bezogen die damit nicht 
linear ist.

> Wenn du die Geschwindigkeit linear ansteigen lassen willst, dann würde
> ich das erst mal auch genau so machen:
> Die Geschwindigkeit linear ansteigen lassen (zb. indem man immer eine
> Konstante addiert) und aus dieser Vorgabegeschwindigkeit die benötigte
> Pulsdauer (also deinen Pausenwert) ausrechnen.

Da hast Du natürlich recht.

Die Geschwindigkeit lin. ansteigen zu lassen und den Delay-Wert dann 
daraus zu berechnen ist wohl schon der richtige Weg.

Ohne Timer hab ich dann allerdings immer noch das Problem dass die 
Erhöhung der Geschwindigkeit nicht in regelmäßigen Zeitabständen 
geschieht, sondern immer schneller vonstatten geht da die Delay-Zeit ja 
immer kleiner wird.

Evtl schaff ich's ja auch 'ne Funktion aufstellen die mir dann Werte für 
einen Array liefert und die immer kleiner werdenden Delay-Zeiten 
berücksichtigt.

Stephan

von Karl H. (kbuchegg)


Lesenswert?

Stephan Schwarzmann wrote:

> Ohne Timer hab ich dann allerdings immer noch das Problem dass die
> Erhöhung der Geschwindigkeit nicht in regelmäßigen Zeitabständen
> geschieht, sondern immer schneller vonstatten geht da die Delay-Zeit ja
> immer kleiner wird.

Hmm. Da hast du zweifellos recht. Das hab nun wieder ich übersehen.

> Evtl schaff ich's ja auch 'ne Funktion aufstellen die mir dann Werte für
> einen Array liefert und die immer kleiner werdenden Delay-Zeiten
> berücksichtigt.

An sowas ähnliches hab ich jetzt auch gedacht.

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.