-         

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

Thema: Schrittmotor im Sinus laufen lassen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    14.12.2006
    Beiträge
    20

    Schrittmotor im Sinus laufen lassen

    Anzeige

    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:

    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;
          }
        }
      }
    
    }
    
    

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Welche Last hängt am Schrittmotor? Hast du ein Oszi?

    Es gibt verschiedene Möglichkeiten. Das erste wäre ein Fehler im Programm bzw µC. Die 2te Möglichkeit wäre, dass der Motor Schritte verliert, weil er eine zu hohe Last anliegt.

    Verwendest du als Takt einen Interrupt? Ich kann keinen erkennen. Um einen exakten Takt zu erzeugen ist es sinvoll einen Interrupt zu verwenden. Je nach Quarz und Presacaler hast du verschiedene Zeiten, die du nutzen kannst.

    MfG Hannes

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    14.12.2006
    Beiträge
    20
    der Fehler liegt im Programm.

    ja, interrupt wäre sicherlich gut, aber ich habe noch nie damit gearbeitet. wie geht das?
    ich kenne das nur, das eine interrupt ausgefürt wird, wenn ein bestimmter imput kommt, also ein imput-pin wird von aussen HIGH oder LOW geschaltet.
    bei mir brauche ich es ja genau anders herumm.
    Wie geht das?
    geht das mit arduino?

    hier die Dokumentation von arduinos interrupt Funktion:
    http://www.arduino.cc/en/Reference/AttachInterrupt

    gibt es irgendwo Beispiel Coder für Schrittmotor Steuerung mit Interrupts?

    vielen dank!

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Also ich würde versuchen, das ganze etwas anders zu lösen. Hab mir jetzt den Code nicht wirklich angeguckt, aber hatte mir darüber schonmal ein wenig Gedanken gemacht. Bei einer Sinusfunktion geht das sogar relativ einfach über die Umkehrfunktion. Um die exakten Schrittzeitpunkte berechnen zu können braucht man eine Funktion der Zeit in Abhängigkeit vom Weg (also anders herum, als gewohnt). Wenn jetzt also meinetwegen x(t)=R*sin(a*t) und y(t)=R*cos(a*t) sind, dann ließe sich t1(x)=asin(x/R)/a und t2(y)=acos(x/R)/a berechnen. t1 und t2 sind die Zeitfunktionen der jeweiligen Achsen, nun könnte man für die x- und y-Werte die aktuelle Schrittzahl*Schrittweite nehmen und wenn man davon die Differenz mit dem nächsten Schritt, also Schrittweite*(aktuelle Schrittzahl+1), nimmt, erhält man immer die nötige Zeitdifferenz zum nächsten Schritt. Was höchstens Probleme machen könnte ist der Rechenaufwand zwischen den einzelnen Schritten, sowie beide Achsen simultan laufen zu lassen. Da fiele mir jetzt aber auch nichts zu ein.

  5. #5
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Vielleicht hilft Dir das weiter:
    http://www-i1.informatik.rwth-aachen...o32/algo32.pdf

    Habe ich vor vielen Jahren mal erfolgreich in einer CNC Fräse angewendet.
    Bei Kreisformen ist der Frequenzverlauf ziemlich "glatt", so weit ich mich erinnern kann.
    mfG
    Willi

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Das PDF ist sehr interessant, wie hast du das denn in ein Programm für die Schrittmotoren umgesetzt? Erst alle Punkte berechnen lassen oder während der Fahrt "frisch" berechnen?

  7. #7
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Der Vorteil dieses Algoritmus ist die einfache (Integer) und damit schnelle Berechnung.
    Eine Schleife läuft z.B. für die X-Koordinate und in dieser wird dann die Y-Koordinate berechnet (während der Fahrt).

    Das Ganze geht natürlich auch mit Geraden. Dabei ergeben sich aber u.U. (bei entsprechenden Deltawerten) unsaubere Frequenzen die dann unangenehm auf die Motoren wirken (Geräuschentwicklung / Schrittverlust).

    Habe das früher mit einem 6502 gemacht. Den Code habe ich leider nicht mehr.
    mfG
    Willi

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Interessant^^
    Das hieße, dass eine Achse in einer konstanten Geschwindigkeit fährt und die andere sich dann nach der Funktion ausrichtet? Konstante Geschwindigkeit am Endpunkt ist so wohl eher nicht möglich.

    Mich interessiert im Grunde, wie man (fast) beliebige Funktionen für die Zeitverläufe recht genau für Schrittmotoren übersetzt. Am interessantesten wäre es wohl, wissenschaftliche Arbeiten dazu zu lesen, irgendwer wird sich doch wohl schon damit beschäftigt haben, allerdings weiß ich nicht, wo ich suchen muss. Glaub nicht, dass sich an unserer Uni schonmal jemand damit beschäftigt hat. Aber es gibt ja schon genügend CNC-Maschinen, die auch komplizierte Kurvenmuster (zB. geschwungene Schrift) sehr genau realisieren, jedoch wird es da wohl eher über nen PC laufen. Ich hör allerdings irgendwie dauernd, dass PCs für Echtzeitverfahren ungeeignet sind...hmmmm

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    14.12.2006
    Beiträge
    20
    hallo,

    danke für die antworten!
    habe das Problem jetzt gelöst. allerdigs nur für Sinus kurven und andere mathematische funktionen.
    Der tip kam vom MaWin aus dem Mikrocontroller.net

    hier das Programm:

    Code:
    int stepperXPin =  13;   
    int stepperXDirPin =  4;   
    
    float pi = 3.14159265;
    
    float i = 0.0000001; 
    int amplitude = 2000;
    float frequenz = 3.97;
    
    int motor_statusX = 0;   // motor pin HIGH oder LOW
     int positionOldX = 0; 
    int positionX = 0;
    long t = 0;   // Timer fuer Interval
    long zeitaltX = 0;         // Timer fuer Motor-Takt
    
    
    void setup()   {       
    Serial.begin(115200);
      pinMode(stepperXPin, OUTPUT); 
      pinMode(stepperXDirPin, OUTPUT);     
    }
    
    
    
    void loop()
    
    
    {
      
    
      
      t=micros(); // immer nur 1 Aufruf des Zeitgebers in der Schleife!
      positionX=sin(t/(100000.0*pi*(frequenz/2)))*amplitude; // sonst unterschiedliche
       
        
        
      if(positionX>positionOldX)              // Zeiten möglich
        digitalWrite(stepperXDirPin, HIGH);    // (ich verwende sie eh nur 1x)
      else
        digitalWrite(stepperXDirPin, LOW);
     
     
      if(positionX!=positionOldX)
      {
       if(abs(positionX-positionOldX)>1)
      {
        Serial.println("cpu zu langsam");
      }
      
       
       
        digitalWrite(stepperXPin, motor_statusX=!motor_statusX); // Zuweisung!
        positionOldX=positionX;
      }
    }
    es läuft die ganze zeit so schnell es geht, und sobald die zu fahrende funktion einen weiteren vollen schritt ergibt wird Dieser sofort ausgeführt.
    Leider funktioniert das nur bei mathematischen Funktionen in Abhängigkeit der zeit.
    bei x y Koordinaten, die z.b. Wegpunkte sind auf denen zwischendurch interpoliert werden muss geht das nicht.

    auch die Berechnungen die man in dem Programm machen kann sind sehr begrenzt, da sonst das zeitlich nicht mehr hin haut. (mehr als ein schritt pro Programm Durchlauf).

  10. #10
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    31.05.2009
    Beiträge
    251
    Zitat Zitat von Geistesblitz Beitrag anzeigen
    Interessant^^
    Das hieße, dass eine Achse in einer konstanten Geschwindigkeit fährt und die andere sich dann nach der Funktion ausrichtet?
    Richtig !

    Zitat Zitat von Geistesblitz Beitrag anzeigen
    Konstante Geschwindigkeit am Endpunkt ist so wohl eher nicht möglich.
    ????
    Start- und Endpunkt sollten von einer Rampe eingehüllt sein.
    mfG
    Willi

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Servo schnell und langsam laufen lassen
    Von Dennis2006 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 27.03.2010, 09:37
  2. Motoren schneller laufen lassen
    Von asuromatze im Forum Asuro
    Antworten: 3
    Letzter Beitrag: 25.05.2007, 19:37
  3. Programm auf Simulator laufen lassen?
    Von StoredProc im Forum Asuro
    Antworten: 4
    Letzter Beitrag: 04.04.2007, 00:45
  4. zwei motoren syncron laufen lassen?
    Von el_net_fun im Forum Motoren
    Antworten: 14
    Letzter Beitrag: 23.02.2006, 11:37
  5. Programm von einer Speicherkarte laufen lassen
    Von im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 07.12.2004, 10:22

Berechtigungen

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