-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 14

Thema: Schrittmotor, PWM, Anfahrkurve und Bremskurve

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2005
    Beiträge
    25

    Schrittmotor, PWM, Anfahrkurve und Bremskurve

    Anzeige

    Hallo,

    ich habe einen Schrittmotor mit 10000 Steps/Umdrehung.
    (40V 5,8A Typ Positec VRDM 397/50 LHB made by Sig Berger Lahr)

    Der Motor wird über eine mitgelieferte Karte bestromt.

    Eingänge der Karte:
    Puls, TOR, Richtung

    Der Schrittmotor macht genau einen Step bei einem Puls.
    ALSO=>
    Der Motor dreht also um so schneller, je höher die Frequenz der Takte
    am Pulseingang ist.

    DAS PROBLEM:
    DER MOTOT SOLL LANGSAM ANFAHREN (ca. 2sec.) DANN ca. 5sec. AUF VOLLGAS FAHREN UND DANN WIEDER WEICH BREMSEN (ca. 2sec.)

    Zur PWM habe ich bereits nachgelesen:
    dass PWM ja nicht die Frequenz verändert (bzw. die Periodendauer), sondern nur das Puls-Pausen-Verhältnis.

    Jetzt zur Frage:
    Kann ich diesen StepMotor mit der mitgelieferten Karte über PWM steuern(Geschwindigkeitssteuern) ?
    Was ich doch eigentlich brauche ist eine Frequenzveränderung, oder?


    MEIN LÖSUNGSANSATZANSATZ:
    Das habe ich bis jetzt wie folgt programmiert (WINAVR):

    //code
    Puls von low nach high
    delay
    Puls von high nach low
    delay

    den delay kann ich über eine Schleife verändern, sodass sich auch die Frequenz verändert und somit auch die Geschwindigkeit.

    Das Problem bei dieser Lösung ist es, dass (bei WinAvr) die Übergänge zwischen Anfahren und Vollgas und Vollgas und bremsen nicht weich genug sind, bzw. das das für 10000 Steps/Umdrehung zu langsam wird


    Generelle Verständnisfrage:
    Ist PWM überhaupt das richtige für dieses Problem?

    Wie löse ich das Problem mit der Anfahrkurve?

    Vielen Dank für jeden Hinweis.
    mfg

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.08.2004
    Ort
    Stuttgart
    Alter
    42
    Beiträge
    849
    Servus!

    So was einfaches in der Art hab ich eben als Beispiel gecodet für eine eigene Stepperkarte. Kannst den Code ja mal probieren, ich gehe über den Timer-Interrupt zurück als Zeitbasis. Kannst es noch zu deiner Variante modifizieren.

    http://www.wieselsworld-online.de/themen/px08x006.htm

    Und direkt der Code:

    http://www.wieselsworld-online.de/th...rteAVRTest.bas

    Grüße Wolfgang

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.08.2004
    Ort
    Stuttgart
    Alter
    42
    Beiträge
    849
    Probiers mal prinzipiell damit, habs kurz umgeschrieben, muß man aber anpassen. Die Freuenz ist auch nicht linear da T = 1 / f ist. Kannst aber anders schreiben und es ist auch linear.

    Code:
    $RegFile = "m8def.dat"   ' ATMEGA8L8
    $Crystal = 3686400       ' 3,68MHz intern
    
    '  Port AVR:       Stepperantrieb
    '  ---------       ---------
    '
    '   PD2 ---------> Enable
    '   PD3 ---------> Dir
    '   PD4 ---------> Clock
    '
    
    Stpk03Enable  Alias PortD.2
    Stpk03Dir     Alias PortD.3
    Stpk03Clock   Alias PortD.4
    Taster1       Alias PinD.6
    Taster2       Alias PinD.7
    
    DDRD  = &B00011100
    PortD = &B11000000
    
    Dim i         As Integer
    Dim k         As Integer
    
    '1,8,64,256,1024
    Config Timer0 = Timer , Prescale = 1024
    Enable Timer0
    
    On Timer0 DoStep
    
    Enable Interrupts
    
    Stpk03Enable = 1
    Stpk03Dir = 1
    
    i = 0
    Do
      Do
        i = i + 1
        k = i
        WaitMs 50
      Loop Until k = 255
    
      WaitMs 5000
    
      Do
        i = i - 1
        k = i
        WaitMs 50
      Loop Until i = 0
    
      WaitMs 10000
    Loop
    
    DoStep:
      If k = 0 Then
        Stpk03Enable = 0
      Else
        Stpk03Enable = 1
      End If
      Timer0 = k
      Stpk03Clock = Not Stpk03Clock
      Return
    Grüße Wolfgang

  4. #4
    Super-Moderator Lebende Robotik Legende Avatar von Manf
    Registriert seit
    30.01.2004
    Ort
    München
    Alter
    64
    Beiträge
    12.372
    Jetzt zur Frage:
    Kann ich diesen StepMotor mit der mitgelieferten Karte über PWM steuern(Geschwindigkeitssteuern) ?
    Was ich doch eigentlich brauche ist eine Frequenzveränderung, oder?
    Schrittmotoren werden mit Schrittmustern angesteuert, die mit Schrittfrequenz an den Motor angelegt werden.
    Soweit hat das mit PWM nichts zu tun.

    Das Muster besteht aus vorgegebenen Strömen. Die Schaltung wird aber mit Spannung versorgt. Um aus der Spannung Ströme für die Spulen zu generieren, benötigt man Regelschleifen mit PWM Stellgliedern.
    Die Frequenz der PWM in den Stromregelschleifen sollte damit (konstant und) höher sein als die Schrittfrequenz.
    Manfred

    http://www.st.com/stonline/books/pdf/docs/1679.pdf

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    23.03.2004
    Ort
    Hamburg
    Beiträge
    69
    Hi brundle,
    Normalerweise brauchst Du nur einen Puls an die Steuerkarte zu geben um den Motor einen Step weiter zu drehen, die Karte erledigt den Rest. Damit der Motor permanent dreht, must Du permanent Pulse geben. Die Frequenz mit der Du die Pulse gibst, bestimmt die Geschwindigkeit des Motors. Wenn die Pulse zu schnell kommen, kommt der Motor nicht mehr mit, d.h. er verliert Pulse und wir kraftlos. Ich hab die Vmax meiner Motoren einfach experimental ermittelt. (ausprobiert )
    Der Trick bei der Ansteuerung von Schrittmotoren ist, diese Pulse in einem timergesteuerten Interruptprogramm zu erzeugen. Dadurch kommen die Pulse immer gleichmäßig und du brauchst im Hauptprogramm nicht auf das timing zu achten.
    Als Beispiel hier mal die wichtigsten Teile aus meinen Programm. (hoffe ich hab beim Zusammenkürzen nichts wichtiges weggekürz)
    Die "waitms 10" im Hauptprogramm sind nur geschätzt, keine Ahnung ob der Motor damit ruckfrei beschleunigt/bremst.
    Code:
    '###################################################
    '              Schrittmotorsteuerung
    '###################################################
    
    $crystal = 8000000                      'Quarzfrequenz
    
    'Konfiguration Schrittmotoren
    Config Pinc.5 = Output                  'linker Schrittmotor Drehrichtung  0=links / 1=rechts
    Config Pinc.3 = Output                  'linker Schrittmotor Impuls
    Config Pinc.4 = Output                  'rechter Schrittmotor Drehrichtung  0=links / 1=rechts
    Config Pinc.2 = Output                  'rechter Schrittmotor Impuls
    
    ' Timer0     Impulse für die Motoren
    Config Timer0 = Timer , Prescale = 64
    On Ovf0 Motoren                         'Bei Überlauf wird das Unterprogramm "Motoren" ausgeführt
    
    Enable Timer0                           'Timer aktivieren
    Stop Timer0                             'Timer anhalten
    Enable Interrupts                       'Interrupts anschalten
    
    'Variable
    Dim Vl As Byte                          'Geschwindigkeit Linker Schrittotor
    Dim Vr As Byte                          'Geschwindigkeit rechter Schrittotor
    Dim Vzl As Word                         'Zähler Geschwindigkeit links
    Dim Vzr As Word                         'Zähler Geschwindigkeit rechts
    Dim Schrittelinks As Word               'Zähler Schritte links
    Dim Schritterechts As Word              'Zähler Schritte rechts
    
    Dim I As Byte                           'Schleifenzähler
    '*************************************************************************
    '               +++++++++++++ Hauptprogramm ++++++++++++++
    '*************************************************************************
    '
    ' Die Variablen Vl und Vr bestimmen die Geschwindigleit der Motoren
    ' je kleiner der Wert ist, desto schneller dreht der Motor
    ' Wie klein der Wert maximal werden darf, hängt von den Motoren,
    ' der Taktgeschwindigkeit der Prozessors und der Einstellung des Interrupttimers ab
    ' (bei mir ist Vmax=30)
    ' Vl bzw. Vr =0 stopt den Motor
    '-------------------------------------------------------------------------
    
    Start Timer0
       Portc.5 = 1                          'Drehrichtung der Motoren
       Portc.4 = 0
    
       For I = 80 To 30 Step -1             'Beschleunigen
          Vl = I
          Vr = Vl
          Waitms 10
       Next I
    
       Schrittelinks = 0                    'Fahren
       Do
       Loop Until Schrittelinks = 1000
    
       For I = 30 To 80                     'Bremsen
          Vl = I
          Vr = Vl
          Waitms 10
       Next I
       Wait 1
    
    Stop Timer0
    
    End                                     'end program
    
    '*************************************************************************
    '              ------------------ Subs -------------------
    '*************************************************************************
    Motoren:
      Timer0 = 220
    
      If Vl > 0 Then
         If Vzl = 0 Then
           Vzl = Vl
           If Portc.3 = 0 Then
             Portc.3 = 1
             Incr Schrittelinks
           Else
             Portc.3 = 0
           End If
         Else
           Decr Vzl
         End If
      End If
    
      If Vr > 0 Then
        If Vzr = 0 Then
          Vzr = Vr
          If Portc.2 = 0 Then
            Portc.2 = 1
            Incr Schritterechts
          Else
            Portc.2 = 0
          End If
        Else
          Decr Vzr
        End If
      End If
    Return
    
    '===========================================
    2B or not 2B = FF

    Wenn etwas klemmt, wende keine Gewalt an,
    nimm einfach nen größeren Hammer.

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2005
    Beiträge
    25
    Zitat Zitat von Marvin
    [..]
    Der Trick bei der Ansteuerung von Schrittmotoren ist, diese Pulse in einem timergesteuerten Interruptprogramm zu erzeugen. Dadurch kommen die Pulse immer gleichmäßig und du brauchst im Hauptprogramm nicht auf das timing zu achten.
    [..]


    Hallo,
    erts mal vielen Dank für die Info mit dem timergesteuerten Interruptprogramm.
    Ich habe es das Timer-Beispiel von http://www.mc-project.de für mich abgeändert und ein paar Fortschritte gemacht.

    Hat jemand vielleicht ein WINAVR Code-Schnippel für mich?
    (ich programmiere in C und Bascom:keine Ahnung von

    Also ich benötige eine gleitende Frequenz von ca.5kHz...40kHz für die Anfahrt.

    Frage zur gleitende Frequenzn beim Anfahren, Bremsen:
    -linear Ansteigend
    -logarithmisch mit e-Funktion
    -Sinus-Funktion
    was ist besser ?

    mfg

  7. #7
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Da war doch mal was mit beschleunigung, geschwindigkeit und weg
    @Manf, Wissender, stimmt das ?

    b = du / dt beschleunigung
    u = b x t + u0 geschwindigkeit
    x = b / 2 x t2 + u0 x t + x0 Weg

    Stepper:
    Die gewünschte Beschleunigung setzt du einfach ein
    Getriebe:
    Bei getürkter Beschleunigung genauso
    sonst setzt du eine feste PWM-duty, die der Beschleunigung entspricht.

    (bremsen umgekehrt, logo)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2005
    Beiträge
    25
    Hallo zusammen.
    Und schon wieder einmal habe ich mir selbst geholfen
    Vielen Dank für die Anregungen.

    Hier mein Quellcode:
    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    
    //Zählvariablen
    int i=0;						//setzt den TCNT0
    int j=0;
    int z=0;
    
    
    
    //Motorparameter
    int steps=10000;				//Steps des Scrittmotors für eine volle Umdrehung
    int Richtung=1;					//wenn Richtung=0 ist => Linksinkslauf
    								//wenn Richtung=1 ist => Rechtslauf
    int steilheit=1200;				//großer  Wert: langsames Beschleunigen und Bremsen
    								//kleiner Wert: schnelles Beschleunigen und Bremsen
    int umdrehungen=30;				//Anzahl der Umdrehungen im Vollgasbetrieb
    
    int beschleunigen	=0;			//wenn beschleunigen = 1 ist, so beschleunigt der Motor
    int schneller		=0;			//Hilfsvariable beim Beschleunigen
    int bremsen			=0;			//wenn bremsen 		 = 1 ist, so bremst der Motor
    int langsamer		=0;			//Hilfsvariable beim Bremsen
    int vollgas			=0;			//wenn vollgas   	 = 1 ist, so hat der Motor seinen Maximum-Speed erreicht
    
    int maxspeed=255;				//Werte zwischen 0...255
    								//Der Timer-Wert TCNT0 wird mit maxspeed gesetzt
    								//kleiner Wert => Motor bei Vollgas langsam
    								//großer  Wert => Motor bei Vollgas schnell
    
    
    
    
    SIGNAL (SIG_OVERFLOW0) {
    	
    	
    if(beschleunigen)
    {
    	j++;
    	if(j==steilheit)
    	{
    		j=0;
    		schneller=1;
    	}		
    
    	if(schneller)
    	{
    		schneller=0;
    	
    		if(i<maxspeed)
    		{
    			i++;
    			if(i==maxspeed)
    			{
    				beschleunigen=0;
    				vollgas=1;
    			}
    		}
    	}
    }
    
    
    
    if(vollgas)
    {
    	i=maxspeed;
    
    	j++;
    	if(j==steps)
    	{	
    		j=0;
    		
    		z++;
    		if(z==umdrehungen)
    		{
    			z=0;
    			vollgas=0;
    			bremsen=1;		
    		}
    	}
    }
    
    
    
    if(bremsen)
    {
    	j++;
    
    	if(j==steilheit)
    	{
    		j=0;
    		langsamer=1;
    	}	
    
    	if(langsamer)
    	{
    		langsamer=0;
    		
    		if(i>1)
    		{
    			i--;
    			if(i==1)
    			{
    				beschleunigen=1;
    				bremsen=0;
    				
    				PORTD^=(1<<PD6);		//RICHTUNG:	Bit 6 in PORTD invertieren
    				
    				//Warteschleife
    				for(int u=0;u<32000;u++)
    				{
    					for(int v=0;v<8000;v++)
    					{
    					//nop
    					}
    				}
    			}
    		}
    	}	
    }
    	
    
    	
    	
    	TCNT0 = i;							// Timer-0 Startwert setzen	
    	PORTD^=(1<<PD4);					//PULS:		Port D: BIT PD4 invertieren (toggeln)
    
    }
    
    
    
    // HAUPTPROGRAMM
    int main (void) {
    /*
    _______________________
    PORT D des ATMEGA32 µC:
    _______________________
    
    PDx				PIN		Funktion							Bemerkung
    =========================================================================================
    PD0		(RXD)	14		RS232 empfangen
    PD1		(TXD)	15		RS232 senden
    PD2		(INT0)	16		
    PD3		(INT1)	17		
    PD4		(OC1B)	18		Puls:								für Schrittmotor
    PD5		(OC1A)	19		
    PD6		(ICP)	20		Richtung: 							links(low), rechts(high)
    PD7		(OC2)	21		TOR:								high=offen low=geschlossen
    
    __________________________________________________________________________________________
    */
    
    
    
    
    
    	beschleunigen=1;					//muss ein mal auf 1 gesetzt werden, um zu starten
    	
    	DDRD = 0xFF;   			 			// Setzt das Richtungsregister des Ports D auf 0xFF (alle Pins als Ausgang)
    	PORTD |= (1<<6);  					//RICHTUNG:	setzt Bit 6 in PORTD auf "1" für rechtslauf
    	PORTD |= (1<<7);  					//TOR:		setzt Bit 7 in PORTB auf "1" für TOR
    	
    	
    	//Timer-0 initialisieren
    	TIMSK |= (1<<TOIE0);				//Timer Overflow Interrupt enable
    	//TCCR0 = (5<<CS00);				// Timer-0 Vorteiler auf 1024
    	//TCCR0 = (1<<CS01) | (1<<CS00);	//Prescaler von 64 
    	TCCR0 = (1<<CS00);					//Prescaler von 1  
    	TCNT0 = 0;							// Timer-0 Startwert setzen
    	//Timer-0 initialisieren ENDE.
    	
    	
    	
    	
    	
        sei();	
        for (;;) {} 						// Endlosschleife
    
    }
    //HAUPTPROGRAMM ENDE.
    ok.

    Q.Was macht das Programm?
    Aas Programm generiert einen gleitenden Frequenzgang von über! 80kHz, das bedeutet mein Stepmotor mit 10000Steps/Vollumdrehung dreht im Vollgasmodus über 8x pro Secunde! Der Motor wird sanft beschleunigt und gebremst. Die Steilheit kann angegeben werden.

    Aber jetzt noch einige Probleme:
    -Ich will das ganze Programm in eine Funktion packen, damit ich über RS232 die Motorparameter übergeben kann.
    Q:Wie mache ich das? Kann ich der Funktion SIGNAL (SIG_OVERFLOW0) {...} Parameter übergeben?

    -Im Augenblick läuft das Programm ununterbrochen.
    Erst beschleunigt der Motor auf Maximum-Speed, dann dreht er sich ein paar Umdrehungen und dann bremst er wieder ab. (An dieser Stelle will ich eigendlich hier wieder aussteigen)
    Danach Kommt ein Richtungswechsel und eine Warteschleife für ca. 3 Sekunden. Danach geht das gleiche Spiel wieder in die Andere Richtung los.
    Q:Wie bringe ich das Programm dazu, dass es nach dem Bremsen aussteigt?

    Wie immer vielen Dank für alle! anregungen

    mfg

    PS: µC ist ein Atmega32@16MHz (RN-CONTROL)
    Angehängte Dateien Angehängte Dateien

  9. #9
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.836
    Hilfe zur Selbsthilfe ! So ist das auch gedacht.

    Da es von den ISR's ja nur einen Instanz gibt, kannst du globale Felder für Parameter verwenden (!volatile!).

    Exit: Ich hab das mal in einer Anwendung so gemacht:
    Wenn (Bremsen=on && Speed=minumum && position=target)
    { dreh ich den Saft ab und deaktiviere die Beteiligten. }
    Der Positionsvergleich kann natürlich auch ev. entfallen, bei mir war ein Mismatch andererseits auch der Grund, überhaupt aktiv zu werden und die Richtung zu bestimmen)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.07.2004
    Ort
    Mammendorf
    Alter
    61
    Beiträge
    1.058
    Schaut euch mal den StepRocker von Trinamic an, bei Reichelt.de als TMCM1110 zu beziehen. Da gibt es auch eine Version davon die mehr Strom liefern kann. Diese karten auf der basis der ICs von Trinamic hat eine Funktion die sich S-Ramp nennt. Da wird statt einem Geschwindigkeits-Trapez-Profil ein S-förmiger Verlauf der Beschleunigung und Verzögerung bereitgestellt, welche auch noch durch die Einstellung der maximal zulässigen Beschleunigung beeinflusst werden kann. Siehe dieses Video:



    Das lässst eigentlich keine Wünsche übrig und kann sogar eigenständig die Zeitpunkte ermitteln um eine bestimmte Position anzufahren!
    MfG

    Hellmut

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •