mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rampenfunktion bei Schrittmotorsteuerung


Autor: Michael L. (strompaedagoge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe einen Schrittmotor welcher sich auf Tastendruck einen Step oder 
eine Umdrehung weiterbewegen soll. Dies funktioniert soweit ganz gut. 
Jedoch zittert der Motor manchmal dabei. Komischerweise nur bei 
Linksdrehung. Meine Lösung wäre jetzt eine Rampenfunktion gewesen. 
Jedoch bin ich da bis jetzt nicht sondrlich weit mit gekommen, da meine 
Programmierkenntisse dafür alleine nicht ausreichen. Die Suche hat mich 
da auch nicht großartig weitergebracht. Ich bin dabei zwar auf eine 
AccelStepper Bibliothek gestoßen, jedoch bekomme ich diese nicht auf 
meinen Code angewandt. Die Beeispiele funktionieren jedoch auch nicht.

Verwendete Hardware ist ein ein Arduino Uno und ein Motorshield.

Der Code ist:

#include <Stepper.h>


/* STEPS muss auf die Anzahl der Stepps des verwendeten Motors angepasst werden */
#define STEPS 200
 
// eine Instanz aus der Klasse Stepper wird erzeugt
// sie bekommt die Anzahl der Steps und die Pins, an die der Schrittmotor
// angeschlossen ist übermittelt
Stepper stepper(STEPS, 3, 11, 12, 13);

//Pinbelegung

const int buttonPin1 = 5;
const int buttonPin2 = 4;
const int led1Pin = 7;
int drehrichtung = 0; 
int steps = 200;
//const int led2Pin = 8;
int buttonState1 = 0;
int buttonState2 = 0;


//---------------------------------------------------------------------------------------------

void setup() {
  // put your setup code here, to run once:
  
  stepper.setSpeed(10);             // setzt die Geschwindigkeit des Motors in Umdrehungen pro Minute
                                   // 10 gute Einstellung, 15 geht gar nicht, 30 dreht mancmal in die falsche Richtung
  
   pinMode(led1Pin, OUTPUT);
//   pinMode(led2Pin, OUTPUT);
   pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);


//---------------------------------------------------------------------------------------------


void loop() {
  // put your main code here, to run repeatedly:
  
 //1 Umdrehung =  200 Schritte 
  buttonState1 = digitalRead(buttonPin1);     // im Loop wird der Variable buttonState mit dem Befehl = digitalRead(buttonPin) 
  buttonState2 = digitalRead(buttonPin2);    // der aktuelle Zustand des Buttons übergeben (entweder HIGH oder LOW).

  
                                            
if (buttonState1 == HIGH) {
  digitalWrite(led1Pin, HIGH);
  stepper.step(steps);          // Drehung rechts
  drehrichtung = 1; 
}
else {
  digitalWrite(led1Pin, LOW);
}

if (buttonState2 == HIGH) {
  digitalWrite(led1Pin, HIGH);
  stepper.step(- steps);       // Drehung links
  drehrichtung = -1;
}
else {
  digitalWrite(led1Pin, LOW);
}

}




Beste Grüße

Michael (strompädagoge)

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>  stepper.step(steps);          // Drehung rechts
>  drehrichtung = 1;
...
>  stepper.step(- steps);       // Drehung links
>  drehrichtung = -1;

Was verlangt dein Motorshield zur Ansteuerung? Schritte+Richtung oder 
was anderes?

MfG spess

Autor: Michael L. (strompaedagoge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo spess,

das Motorshield benötigt eine Anzahl an Schritten. Hier gespeichert in 
dem Integer steps. Die Drehrichtung ist über das Vorzeichen geregelt.

MfG

Autor: W.S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael L. schrieb:
> Meine Lösung wäre jetzt eine Rampenfunktion gewesen.
> Jedoch bin ich da bis jetzt nicht sondrlich weit mit gekommen, da meine
> Programmierkenntisse dafür alleine nicht ausreichen.

Dann lerne dazu, so daß dann deine Kenntnisse ausreichen.
Zunächst brauchst du nen Timer, aber den hat ja wohl so ziemlich jeder 
µC heutzutage. Selbiger sollte in der Lage sein, irgend einen 
PWM-Ausgang direkt anzusteuern, das wird dann dein Taktsignal für den 
Motortreiber. Mach das PWM-Verhältnis einfach 1:1, also 50%.

Beim Überlaufen des Timers sollte eine Interrupt-Routine aktiviert 
werden, die ihrerseits die Timerfrequenz verändern kann. Also pro 
SM-Schritt ein Timerereignis.

Jetzt fängst du mit ner niedrigen Frequenz an und mit jedem Schritt 
erhöhst du selbige, bis du bei der höchsten (von dir selbst 
vorgegebenen) Frequenz angekommen bist. Die Anzahl N der dabei 
zurückgelegten Schritte zählst du mit. Anschließend fährst du mit 
konstanter Frequenz, bis du beim Schritt Gesamtschrittzahl-N angekommen 
bist. Ab da erniedrigst du die frequenz wieder. Ist die 
Gesamtschrittzahl kleiner als 2*N, dann fährst du eben bloß soweit hoch, 
bis 2*N >= Gesamtschrittzahl ist.

Das ist alles.

W.S.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael L. schrieb:
> Jedoch zittert der Motor manchmal dabei.

Hast du eine passende Last dran? Sonst kann es bei passender 
Schrittfrequenz schon mal zu Resonanzen kommen.

> Die Suche hat mich da auch nicht großartig weitergebracht.

Dann probiers doch mal mit der Application Note 446 von Atmel
AVR446: Linear speed control of stepper motor, Kap 2.3 Linear speed ramp
http://www.atmel.com/dyn/resources/prod_documents/...

Autor: Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für die Accelstep habe ich mal ein Beispiel gemacht. Dein Code oben 
scheint mir nicht vollständig zu sein? Oder hast du tatsächlich einen 
Motortreiber, der mit 4 Signalen angesteuert wird und nicht mit 
Takt/Richtung?
Stepper stepper(STEPS, 3, 11, 12, 13);
Wie wird hier die Pinzuordnung aufgelöst?

  stepper.setSpeed(10);             // setzt die Geschwindigkeit des Motors in Umdrehungen pro Minute
                                   // 10 gute Einstellung, 15 geht gar nicht, 30 dreht mancmal in die falsche Richtung

Ohne Rampen und bei einer einfachen H-Brücke ohne Stromregelung wundert 
mich das nicht.

Mit freundlichen Grüßen
Thorsten Ostermann

Autor: Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Link vergessen:
http://www.schrittmotor-blog.de/ansteuern-von-schr...

Mit freundlichen Grüßen
Thorsten Ostermann

Autor: Michael L. (strompaedagoge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolfgang schrieb:
> Dann probiers doch mal mit der Application Note 446 von Atmel
> AVR446: Linear speed control of stepper motor, Kap 2.3 Linear speed ramp
> http://www.atmel.com/dyn/resources/prod_documents/...

Hallo Wolfgang,
das Dokument habe ich vorher schon gefunden. Ich bekomme dies nicht so 
ganz in einen Programmcode umgesetzt :(

Thorsten O. schrieb:
> Ohne Rampen und bei einer einfachen H-Brücke ohne Stromregelung wundert
> mich das nicht.

Hallo Thorsten,
das Motorshield ist ja nur dieser einfache Aufsatz für das Arduinoboard. 
Soll später durch ein DM542a ersetzt werden. Dieser ist dann mit Takt 
und Richtung gesteuert soweit ich das verstanden habe. Ein TinyStep habe 
ich leider nicht bekommen ;) Deinen Programmcode funktioniert deswegen 
wahrscheinlich nicht mit dem einfachen Motorshield. Ich werde das Montag 
mal testen. Schöner Blog übrigens ;)

Beste Grüße

strompädagoge

Autor: Michael L. (strompaedagoge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thorsten O. schrieb:
> Link vergessen:
> http://www.schrittmotor-blog.de/ansteuern-von-schr...
>
> Mit freundlichen Grüßen
> Thorsten Ostermann

Hallo Thorsten,

leider ist mir dein Code etwas zu wenig kommentiert.
Was ist der Unterschied zwischen stepper.move und stepper.run?

Autor: Thorsten O. (Firma: mechapro GmbH) (ostermann) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Michael,

schau doch mal in die accelstepper.h...:
   /// Set the target position relative to the current position
    /// \param[in] relative The desired position relative to the current position. Negative is
    /// anticlockwise from the current position.
    void    move(long relative);

    /// Poll the motor and step it if a step is due, implementing
    /// accelerations and decelerations to achive the ratget position. You must call this as
    /// fequently as possible, but at least once per minimum step interval,
    /// preferably in your main loop.
    /// \return true if the motor is at the target position.
    boolean run();

Mit freundlichen Grüßen
Thorsten Ostermann

Autor: Michael L. (strompaedagoge)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Thorsten,

der Motor dreht sich langsam in die eine Richtung, nach einiger Zeit 
dreht er sich mit schnellen Tempo einmal Links und einmal Rechts rum und 
wechselt dann die Richtung.

So sollte dein Beispiel Sketch funtionieren oder? Ich hatte 
zwischendurch etwas Probleme mit dem Chip, deswegen frage ich.

MfG

Strompädagoge

Autor: m.n. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich weiß nicht, welche Hardware Du hast. Wenn Du die Pinbelegung anpaßt, 
sollte vorwärts - rückwärts mit beliebiger Geschwindigkeit funktionieren
http://mino-elektronik.de/Generator/takte_impulse.htm#bsp7 ff.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.