julius12345
20.06.2011, 02:40
Hallo ihr lieben
Mein Schrittmotor verliert haufenweise schritte und zwar schon im µC Programm.
Ich will einen Schrittmotor im Sinus hin und her drehen lassen. Das ziel ist es mit zwei Schrittmotoren so eine Kreisbewegung zu erzeugen, wobei sich dann die beiden Sinus-Bewegungen zu einem Kreis überlagern.
aber erst mal geht es nur um die X-Achse.
Bei meinem Projekt ist es wichtig, dass die Zeit exakt eingehalten wird. (die Frequenz des Sinus)
Deshalb kann ich nicht wie üblich die Schrittmotoren so ansteuern, dass sie einfach ihre Steps abfahren, bis der Job erledigt ist. (das dauert nämlich nicht immer gleich lange.
Deshalb habe ich Folgendes Programm geschrieben. Es läuft auf einem Arduino bestückt mit einem ATMEGA 320 Was da für ein Schrittmotor Treiber dran hängt ist erst mal egal, da meine Probleme schon im Programm liegen.
Das Programm generiert eine Sinuskurve, die die anzufahrende Position zu einer bestimmten Zeit darstellt. alle 0.1 Sekunden wird diese Position mit der vorherigen abgeglichen und der Motor mit der entsprechenden Geschwindigkeit weiterbewegt, um die nächste Position in der richtigen zeit zu erreichen.
Das ganze funktioniert auch auf den ersten Blick, aber leider gehen viele Schritte verloren.
So ist eine exakte Ansteuerung nicht möglich.
ich gehe mal davon aus, dass das an der Programmlaufzeit liegt, die den Motor Takt durcheinander bringt.
aber wie kann ich das besser programmieren? ich würde mich über Hilfe sehr freuen.
das kann ja nicht so schwer sein ein Schrittmotor exakt im Sinus laufen zu lassen.
hier der code:
int stepperXPin = 13;
int stepperXDirPin = 4;
float i = 0.0000001;
int amplitude = 2000;
int motor_statusX = 0; // motor pin HIGH oder LOW
float stepsX = 0; // Anzahl an Schritten die der Motor im naechsten Intervall fahren soll
int stepCountX = 0; // Anzahl der noch zu fahrenden schritte
float positionOldX = 0;
float positionX = 0;
long previousMillis = 0; // Timer fuer Interval
long zeitaltX = 0; // Timer fuer Motor-Takt
void setup() {
pinMode(stepperXPin, OUTPUT);
pinMode(stepperXDirPin, OUTPUT);
}
void loop()
{
//-----------------Sinus Signal Erzeugung-------------------------//
long interval = 100000; //0.1 sekunden // Aufloesung in der die Sinuskurve in Geraden unterteilt wird.
if (micros() - previousMillis > interval) { // takt für das ubergeben des nechsten sinus werts.
previousMillis = micros();
positionX = ((sin(i)*amplitude)); // erzeugen des sinus signals multipliziert mit der Amplitude (Anzal der Schritte)
stepsX = positionOldX - positionX; // zu gehende schitt anzahl wird ermittet.
stepCountX = abs(stepsX);
positionOldX = positionX;
if(stepsX < 0){ //setting the motor direction
digitalWrite(stepperXDirPin, HIGH);
}
else {
digitalWrite(stepperXDirPin, LOW);
}
i = i+0.1; // der zaehler für die Sinuskurve wird um 0.1 erhoeht. das ergibt bei der Sinus laenge von 2 pi eine Aufloesung von 63 pro Sinus durchlauf
}
//-----------------Motor Steuerung-------------------------//
if(stepCountX > 0){ // solange es noch schritte zu gehen gibt
if (micros() - zeitaltX >= (interval/abs(stepsX*2)) ) { // wird der motor im entsprechenden takt gepulst. (zeit geteilt durch schritte)(schitte mal zwei, da pro Schritt eimal HIGH und LOW geschaktet werden muss
zeitaltX= micros();
if (motor_statusX == 1){
digitalWrite(stepperXPin, LOW);
stepCountX--;
motor_statusX = 0;
}
else
{
digitalWrite(stepperXPin, HIGH);
motor_statusX = 1;
}
}
}
}
Mein Schrittmotor verliert haufenweise schritte und zwar schon im µC Programm.
Ich will einen Schrittmotor im Sinus hin und her drehen lassen. Das ziel ist es mit zwei Schrittmotoren so eine Kreisbewegung zu erzeugen, wobei sich dann die beiden Sinus-Bewegungen zu einem Kreis überlagern.
aber erst mal geht es nur um die X-Achse.
Bei meinem Projekt ist es wichtig, dass die Zeit exakt eingehalten wird. (die Frequenz des Sinus)
Deshalb kann ich nicht wie üblich die Schrittmotoren so ansteuern, dass sie einfach ihre Steps abfahren, bis der Job erledigt ist. (das dauert nämlich nicht immer gleich lange.
Deshalb habe ich Folgendes Programm geschrieben. Es läuft auf einem Arduino bestückt mit einem ATMEGA 320 Was da für ein Schrittmotor Treiber dran hängt ist erst mal egal, da meine Probleme schon im Programm liegen.
Das Programm generiert eine Sinuskurve, die die anzufahrende Position zu einer bestimmten Zeit darstellt. alle 0.1 Sekunden wird diese Position mit der vorherigen abgeglichen und der Motor mit der entsprechenden Geschwindigkeit weiterbewegt, um die nächste Position in der richtigen zeit zu erreichen.
Das ganze funktioniert auch auf den ersten Blick, aber leider gehen viele Schritte verloren.
So ist eine exakte Ansteuerung nicht möglich.
ich gehe mal davon aus, dass das an der Programmlaufzeit liegt, die den Motor Takt durcheinander bringt.
aber wie kann ich das besser programmieren? ich würde mich über Hilfe sehr freuen.
das kann ja nicht so schwer sein ein Schrittmotor exakt im Sinus laufen zu lassen.
hier der code:
int stepperXPin = 13;
int stepperXDirPin = 4;
float i = 0.0000001;
int amplitude = 2000;
int motor_statusX = 0; // motor pin HIGH oder LOW
float stepsX = 0; // Anzahl an Schritten die der Motor im naechsten Intervall fahren soll
int stepCountX = 0; // Anzahl der noch zu fahrenden schritte
float positionOldX = 0;
float positionX = 0;
long previousMillis = 0; // Timer fuer Interval
long zeitaltX = 0; // Timer fuer Motor-Takt
void setup() {
pinMode(stepperXPin, OUTPUT);
pinMode(stepperXDirPin, OUTPUT);
}
void loop()
{
//-----------------Sinus Signal Erzeugung-------------------------//
long interval = 100000; //0.1 sekunden // Aufloesung in der die Sinuskurve in Geraden unterteilt wird.
if (micros() - previousMillis > interval) { // takt für das ubergeben des nechsten sinus werts.
previousMillis = micros();
positionX = ((sin(i)*amplitude)); // erzeugen des sinus signals multipliziert mit der Amplitude (Anzal der Schritte)
stepsX = positionOldX - positionX; // zu gehende schitt anzahl wird ermittet.
stepCountX = abs(stepsX);
positionOldX = positionX;
if(stepsX < 0){ //setting the motor direction
digitalWrite(stepperXDirPin, HIGH);
}
else {
digitalWrite(stepperXDirPin, LOW);
}
i = i+0.1; // der zaehler für die Sinuskurve wird um 0.1 erhoeht. das ergibt bei der Sinus laenge von 2 pi eine Aufloesung von 63 pro Sinus durchlauf
}
//-----------------Motor Steuerung-------------------------//
if(stepCountX > 0){ // solange es noch schritte zu gehen gibt
if (micros() - zeitaltX >= (interval/abs(stepsX*2)) ) { // wird der motor im entsprechenden takt gepulst. (zeit geteilt durch schritte)(schitte mal zwei, da pro Schritt eimal HIGH und LOW geschaktet werden muss
zeitaltX= micros();
if (motor_statusX == 1){
digitalWrite(stepperXPin, LOW);
stepCountX--;
motor_statusX = 0;
}
else
{
digitalWrite(stepperXPin, HIGH);
motor_statusX = 1;
}
}
}
}