Schrittmotor, PWM, Anfahrkurve und Bremskurve
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
Liste der Anhänge anzeigen (Anzahl: 1)
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?
A:Das 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)