- Akku Tests und Balkonkraftwerk Speicher         
Ergebnis 1 bis 5 von 5

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

    LiFePo4 Akku selber bauen - Video
    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?

    ******
    zusatz:
    ******
    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


    Vielen Dank für jeden Hinweis.


    PS: Ich weis, das ist nicht nett einen Topic 2x im Forum zu posten, ich habe bereits unter:
    https://www.roboternetz.de/phpBB2/viewtopic.php?t=9729

    RoboterNetz.de Foren-Übersicht » Roboter-Foren » Motoren » Schrittmotor, PWM, Anfahrkurve und Bremskurve

    gepostet, aber irgendwie komme ich ohne Euch WinAVRler nicht richtig weiter.

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Hi, welchen AVR verwendest du, manche haben die Möglichkeit die Frequenz des PWms zu verändern. Eine andere Möglichkeit ist, über einen Timer alle x Takte einen Interrupt auszulösen, je nach Geschwindigkeit halt öfter oder weniger oft. Der Timer wird dann im Interrupt schon mit einem Startwert beladen, also nicht 0 sondern z.B. schon 200 von 255 und springt dann entsprechend schneller wieder in den Interrupt. Der PWM wird dich da in der Tat nicht sehr weit bringen.

    Ich habe mich jetzt mit dem Schrittmotor nicht näher beschäftigt, aber 10k Steps (0,036°)? Würde ja heißen, er macht bei 5Khz gerade mal eine Umdrehung in 2 Sekunden!

    Schau mla bei http://www.mc-project.de/ unter Timer, da wirst du fündig werden.

    Wenn du fragen hast, nur zu

  3. #3
    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

  4. #4
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    09.06.2004
    Ort
    Aachen
    Beiträge
    2.674
    Wie mache ich das? Kann ich der Funktion SIGNAL (SIG_OVERFLOW0) {...} Parameter übergeben?
    Du kannst einfach globale Variablen definieren:
    volatile int Variablenname;
    In die globale Variable kannst du dann z.B. schreiben welches Programm gerade laufen soll, Beschleunigen, Bremsen etc. und das in der ISR abfragen.

    Q:Wie bringe ich das Programm dazu, dass es nach dem Bremsen aussteigt?
    Du könntest den Interrupt-Enable für den Timer-Overflow löschen, dann springt er nicht mehr in die ISR. Soll dann ein neues Programm gestartet werden (z.B. Rückwärtslaufen) dann setzt du das Flag wieder.

    Das Senden von Motordaten würde ich nicht in Interrupts machen. Ich würde das einfach in main() laufen lassen. Wenn du über RS232 sendest, dann musst du ja eh immer warten, bis der Buffer zum senden leer ist.

    while (!(UCSRA & (1<<UDRE)));

    Du kannst ja unmöglich in der ISR warten! Hoffe, ich konnte helfen.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    02.03.2004
    Ort
    Paderborn
    Alter
    40
    Beiträge
    614
    Das UART löst auch einen eigenen Interrupt aus, wenn ein neues Bit vorliegt(in der ISR kannst du den Wert dann in 'ne globale Variable schreiben, die in der ISR für die Motorsteuerung verwendet wird.).
    Zu RCOs Vorschlag: Verstehe ich das richtig, dass der AVR über das UART die Motordaten EMPFANGEN soll(und dann den Motor entsprechend steuert)?
    it works best if you plug it (aus leidvoller Erfahrung)

Berechtigungen

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

12V Akku bauen