Projekt Schrittmotor & Treiber DRV8825

Servus, grüezi und Hallo Arduino Forum,

Vorab, dies ist mein erster Forum Beitrag überhaupt, also entschuldigt eventuelle Formfehler etc. (Natürlich habe ich mich auch in die "Forum Regeln" eingelesen aber vielleicht habe ich was vergessen)

Zum Projekt.
Ich bin gerade mit der Entwicklung einer Steuerung von 3 Schrittmotoren mittels 2 Joysticks beschäftigt (inkl. Endlagenschalter).
Folgende Teile verwende ich:
1x Elegoo Mega 2560
3x NEMA 17 Stepper. 2A
3x DRV8825 Driver
2x Joystick-Modul (Makerfactory)
6x Endlagenschalter
1x Step-Down Modul LM2596
1x Custom PCB
1x Schaltnetzteil 12V 3.4A

Was soll der Code können:

  • Jeweils eine Achse der Joysticks soll einen Steppermotor steuern
  • Die Endlagen der Motoren sollen abgesichert sein. (Ich habe 6 Taster verwendet, aber ich weiß mit Hilfe einer Library kann ich es auch 3 nutzen, aber dann muss ich Steps zählen etc. und da konnte ich mir nicht weiterhelfen)
  • Es sollen über einen separaten Taster 3 Geschwindigkeitsstufen anzusteuern sein
  • Mittels der Bedienung der Joysticks soll nur eine Geschwindigkeit zu verwenden sein
  • Da die Motoren bei Mittelstellung der Joysticks trotzdem aktiv sind und "piepen" möchte ich bei X und Y Achse mir den Sleep Pin vom Treiber zum Nutzen machen. (Die Z Achse (Vertikal) soll natürlich nicht absacken, wenn der Joystick nicht bedient wird) Diesen muss man auf Low ziehen damit der Ausgang des Treiber zu ist. Ich habe mich mit dieser Aufgabe auseinander gesetzt und es mit einem if Statement ausprobiert, hatte damit aber leider keinen Erfolg. Leider reichen meine Skills auch nicht aus um diese Funktion hinzuzufügen. Somit hoffe ich dass ihr mir bei dem letzten Punkt weiterhelfen könnt.
    Zum Testen und der Übersicht wegen habe ich das Projekt nur für einen Steppermotor aufgebaut. Der Rest ist ja quasi copy paste :slight_smile:

Als schaltplan kann ich leider nur einen von Fritzing zeigen, obwohl dies ungern getan wird. Ich habe ihn trotzdem mal angehangen.

Ich ergänze dass ich den Strom für die Motoren auf 1.2A begrenzt habe.
Und das Microstepping habe ich auf 1/32 gestellt.

Schrittmotor:
https://www.amazon.de/dp/B00PNEQKC0/ref=redir_mobile_desktop?encoding=UTF8&aaxitk=73657edda6d8eab263b5e7bf820f6141&hsa_cr_id=7897951240002&pd_rd_plhdr=t&pd_rd_r=0f183837-c273-4085-b6d7-e8b6566b3d2e&pd_rd_w=tDfSd&pd_rd_wg=igf7V&ref=sbx_be_s_sparkle_mcd_asin_0_img

(Den Code habe ich von dem Youtuber Brainy Bits)
Projekt:
https://www.brainy-bits.com/post/arduino-nema-stepper-control-with-joystick-and-limit-switches
Info zum Treiber:
https://www.pololu.com/product/2133
Retinomax Kalibriervorrichtung final_Schaltplan.pdf (3.3 MB)

#define step_pin 3  // Pin 9 connected to Steps pin on EasyDriver
#define dir_pin 2   // Pin 8 connected to Direction pin
#define slp 5     // Pin 12 connected to SLEEP pin

#define X_pin A0    // Pin A0 connected to joystick x axis

#define button 4  // Pin 4 connected to joystick switch

#define Limit01 6  // Pin 2 connected to Limit switch out
#define Limit02 7  // Pin 3 connected to Limit switch out

int step_speed = 1;  // Speed of Stepper motor (higher = slower)


void setup() {

  Serial.begin(9600);
  pinMode(dir_pin, OUTPUT);
  pinMode(step_pin, OUTPUT);
  pinMode(slp, OUTPUT);

  pinMode(Limit01, INPUT);
  pinMode(Limit01, INPUT);

  pinMode(button, INPUT);

  digitalWrite(slp, HIGH);
}

void loop() {

  if (digitalRead(button) == HIGH) { //  If Joystick switch is clicked
    delay(500);  // delay for deboucing
    switch (step_speed) {  // check current value of step_speed and change it
      case 1:
        step_speed = 250; // medium speed
        break;
      case 250:
        step_speed = 500; // slow speed
        break;
      case 500:
        step_speed = 1; // fast speed
        break;
    }
  }


  if (analogRead(X_pin) > 712) { //  If joystick is moved Left
    if (!digitalRead(Limit01)) {} // check if limit switch is activated

    else { //  if limit switch is not activated, move motor clockwise

      digitalWrite(dir_pin, LOW);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(step_pin, HIGH);
      delayMicroseconds(step_speed);
      digitalWrite(step_pin, LOW);
      delayMicroseconds(step_speed);
    }
  }

  if (analogRead(X_pin) < 312) { // If joystick is moved right
    if (!digitalRead(Limit02)) {} // check if limit switch is activated

    else { //  if limit switch is not activated, move motor counter clockwise

      digitalWrite(dir_pin, HIGH);  // (HIGH = anti-clockwise / LOW = clockwise)
      digitalWrite(step_pin, HIGH);
      delayMicroseconds(step_speed);
      digitalWrite(step_pin, LOW);
      delayMicroseconds(step_speed);



    }
  }
}

Ihr Beitrag wurde an seinen aktuellen Speicherort verschoben, da er besser geeignet ist.

Einen Link zu deinem Motor solltest Du noch posten. Nema 17 sagt nichts über die elektrischen Daten des Motors. Und 2A ist für den DRV8825 schon recht grenzwertig. Wenn Du nicht das volle Drehmoment brauchst, kannst ( und solltest ) Du den Strom am Treiber kleiner einstellen.

Dazu ist der enable Pin besser geeignet. Du willst ja nicht den ganzen Chip schlafen legen, sondern nur den Motorstrom abschalten.

Wenn der Joystick schon einen analogen Ausgang hat ( Poti), warum nimmst Du das nicht als Tempo? Je weiter Du den Joystick aus der Neutralstellung bewegst, umso schneller dreht der Motor.

Das sollte dann doch die Lib machen.

Scheint mir ein bisschen arg hoch. Ich glaube kaum, dass das der Stepper schafft. Das wäre ja eine Steprate von 2µs+loop Durchlaufzeit. D.h. eigentlich bestimmt da nur die Loopzeit die Steprate.
Wie hast Du die Microsteppings am Treiber eingestellt? Was brauchst Du tatsächlich als maximale Steprate?

Normalerweise ist es besser den internen Pullup zu verwenden, und als 'Failsafe' den Endschalter als NC gegen Gnd zu schalten. D.h. Beim Erreichen der Endlage öffnet er. Kabelbruch wirkt dann wie 'Endlage erreicht'.

Du könntest Dir mal meine MobaTools anschauen. Die haben eine Ansteuerung für einen Stepper ( optional mit automatischer Abschaltung bei Stillstand) , und Funktionen zum Einlesen der Buttons. Beispiele sind auch dabei.
Letztens gab's im englischen Forum auch eine Anfrage einen Stepper per Joystick zu steuern. Müsste man mal nach suchen

P.S.

Es gibt keine if-Schleifen :wink:

P.P.S Das hier stepper-motor-angle-and-speed-control war der oben angesprochene Thread. Da wurde auch ein Stepper per Joystick bewegt mit Limitierung der Bewegung.

Den Link zu den Motoren habe ich nachträglich hinzugefügt.

https://forum.arduino.cc/t/drv8825-enable-vs-sleep/640975

Hier wurde erwähnt dass bei dem Sleep Pin nur ein bisschen mehr Schaltkreise abgeschaltet werden, womit also mehr Leitsung gespart wird was ich gut finde. Die Punkte zu den Schritten sind mir nicht aufgefallen. Also der Motor verhält sich "gleich" beim aus- und anschalten des Treibers.
Leider kann ich dies auch nicht mehr ändern, da ich den enable Pin auf dem Platinenlayout, welches ich angefertigt habe, nicht mit einbezogegn habe ("Im nachhinein ist man immer schlauer").

Die Elektrik ist für eine Kalibrierbank, die sehr präziese arbeiten soll. Somit finde ich es einfacher, wenn man sich um die Fingerfertigkeit an den Joysticks keine Sorgen machen muss, da meine Joysticks nicht die beste Qualität haben (Wenn man sie über den Serial Monitor ausliest fällt auf dass ein großer Teil der Bewegung keine Änderung verursacht). Somit ändere ich lieber die Geschwindigkeit über einen Taster.

Ja eine Lib würde den Sketch nochmal "vereinfachen"
Ich habe mich über ein paar Libs versucht zu erkundigen. Leider hatte ich dort schwierigkeiten mich einzuarbeiten. Dann habe ich einen Sketch gefunden der verständlich für mich war und habe mich estmal für diese Variante entschieden. Kannst du mir eine Lib empfehlen wo man sich als newbie sich einlesen kann etc.?

Bezüglich der Schrittrate musste ich improvisieren, da ich für das Projekt nicht sagen kann, welche Schrittrate ich genau benötige. Dies muss ich sehen wenn die Elektronik an das Gestell montiert wird. Bis jetzt kann ich nur sagen, dass die delays keine Probleme verursachen.

Da gebe ich dir recht. Dies habe ich nochmal geändert.

Meine Progammier-Kenntnisse :man_facepalming: ... Habs geändert in if Statement

Vielen Dank für deine Unterstützung :pray:

Ok, Du sparst nochmal etwa 5mA. Wenn das für dich wichtig ist... Dafür braucht er beim Aufwachen etwas länger, was aber vermutlich kein Problem sein sollte.

Was erwartest Du von mir, wo ich doch selbst eine geschrieben habe :rofl: :joy:

Nicht gut, wenn Du deinen Ausgangspost änderst. Das hätte ich jetzt fast übersehen. Bei Microstepping musst Du noch berücksichtigen, dass Zwischenpositionen nicht so exakt angefahren und gehalten werden wie die Fullstep Positionen. Ob das für dich ein Problem sein kann, kann ich natürlich nicht beurteilen. Bei 1/32 brauchst Du natürlich schon eine deutlich höhere Steprate. Da könnte es mit MobaTools oder AccelStepper schon knapp werden. Allerdings ist analogRead() auch nicht gerade superschnell und könnte schon zu einer deutlichen Begrenzung führen - besonders wenn Du später die Joysticks für alle Motoren einliest. Da geht's dann u.U. mit einer Lib sogar schneller.
Welche Drehzahlen schaffst Du den mit deinem derzeitigen Programm?
Sollen sich deine Motore später auch alle gleichzeitig bewegen?

Dies ist für mich kein Problem.

Achsooo, ich schau mir mal deine an. Mir geht es ja letztendlich nur darum die schritte mit der Bibliothek zu zählen... (Geht das überhaupt ohne Inkrementalgeber?)

Stimmt, ich habe dies auch vergessen. Hier muss ich auch abwägen wenn ich alles zusammen gebaut habe.

Welche Drehzahl ich schaffe kann ich leider nicht sagen...

Es ist nicht relevant, dass sie sich gleichzeitig drehen.

Die Frage war "kann es vorkommen das die Schrittmotoren gleichzeitig drehen sollen?" Wenn Sie das mit unerschiedlicher Drehzahl machen sollen dann braucht man eine andere Art der Ansteuerung.
Bei der Antwort "ja"
ist es sehr wohl relevant wenn ein microcontroller mehrere Schrittmoten gleichzeitig mit verschiedenen Geschwindigkeiten ansteuern soll.

vgs

In dem Projekt werden alle Schrittmotoren mit der selben Geschwindigkeit gesteuert.
Zudem ist es in dem Projekt unwichtig, dass die Motoren so schnell wie möglich reagieren.
Wichtig wird die Präzision sein. Wie genau werde ich sehen wenn ich die Mechanik und Elektronik an den Rahmen montiert und getestet habe, einen anderen Weg sehe ich leider nicht mehr daten über Schritte und Präzision zu sagen. Mir geht es ja auch viel mehr um die Funktion zu sagen dass der Treiber im Schlaf-Modus ist wenn die Joysticks nicht bewegt werden.

Das ist die Kernfunktion der Lib, dass sie immer weis, wo der Motor gerade ist ( gerechnet in Schritten vom Referenzpunkt ). Diese Position kann man im Sketch auch jederzeit abfragen. Natürlich stimmt das nur, wenn der Motor nicht überlastet wurde und keine Schritte verloren hat. Wenn der Motor im Stillstand abgeschaltet wird, hat er aber kein Haltemoment mehr, und kann daher seine Positon von der Lib unbemerkt verändern. Das gilt umso mehr, wenn Mikroschritte verwendet werden. Mikroschritt-Positionen kann der Motor ohne Ansteuerung gar nicht halten. Wenn es dir auf Präzision ankommt, darfst Du nicht abschalten.
P.S. Oder Du brauchst eine Treiber, der in der Lage ist, im Stillstand den Strom zu reduzieren, ohne ihn ganz abzuschalten.

Okay ich schau einfach nochmal.
Und die wesentliche Funktion mit dem Schlaf-Modus kann ich mit einer if Bedingung hinbekommen?
Hast du da ein Beispiel für mich? Ich habe es ja bereits versucht und auch gegoogelt aber leider ohne Erfolg.

Wenn Du meine MobaTools verwendest, dann hat die dafür integrierte Funktionalität. Mit attachEnable kannst Du das aktivieren. Auszug aus der Dokumentation:

void myStepper.attachEnable( uint8_t pinEna, uint16_t delay, bool active );
Hiermit wird ein Pin definiert, über den der Motor ein- bzw ausgeschaltet oder in einen Stromsparmodus gebracht werden kann. Der Pin ist immer aktiv, während Steps ausgegeben werden.
pinEna: die Arduino Pinnummer

delay: Verzögerung zwischen Pin-Einschalten und 1. Step in ms, Ebenso zwischen letztem Step und Pin Ausschalten.

active: Ausgang HIGH aktiv oder LOW aktiv