Festgefahren ... Geschwindigkeitssteuerung Stepper Motor

Hallo Foristi,

zuerst einmal als Status: ich habe bereits das Ein oder Andere zum Laufen bekommen, bin aber nicht der Könner sondern muss mich da immer behelfen.
So bringt mich der folgende Code an den Rand des Wahnsinns.
Ich will die Geschwindigkeit eines Stepper-Motors 57HS112-3004426-D21 mit DM556 einem Arduino Nano und einem 10kOhm Schieberegler steuern. Außerdem hätte ich gerne einen Ein-Ausschalter und einen Taster zum Richtungswechsel, jeweils entgegengesetzt der gerade aktiven Richtung.
Folgenden Code habe ich mir zurechtgedacht. Leider liefert der Code auch nach Tausch des Motors samt Treiber und Maßnahmen zur sicheren Verdrahtung, beim betätigen des Potis immer nach erreichen der Deadline die rote Dauer-LED am DM556.

const int potPin = A0;
const int stepPin = 3;
const int dirPin = 4;
const int switchPin = 5;
const int dirButtonPin = 6;
const int enablePin = 7;

const int stepsPerRevolution = 1600;
const int maxRPM = 200;
const float maxStepsPerSecond = (float(maxRPM) * stepsPerRevolution) / 60.0;

const int potThreshold = 20;

bool motorOn = false;
bool currentDir = true;
bool lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50;

void setup() {
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
  pinMode(enablePin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  pinMode(dirButtonPin, INPUT_PULLUP);

  digitalWrite(dirPin, currentDir);
  digitalWrite(enablePin, HIGH);  // Motor aus bei Start
}

void loop() {
  motorOn = (digitalRead(switchPin) == LOW);

  bool reading = digitalRead(dirButtonPin);
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading == LOW && lastButtonState == HIGH) {
      currentDir = !currentDir;
      digitalWrite(dirPin, currentDir);
    }
  }
  lastButtonState = reading;

  if (motorOn) {
    int potValue = analogRead(potPin);
    float stepsPerSecond = 0;

    if (potValue > potThreshold) {
      stepsPerSecond = map(potValue, potThreshold, 1023, 0, maxStepsPerSecond);
    }

    if (stepsPerSecond > 0) {
      digitalWrite(enablePin, LOW);  // Motor aktiv
      float delayMicros = 1e6 / stepsPerSecond / 2;

      digitalWrite(stepPin, HIGH);
      delayMicroseconds((int)delayMicros);
      digitalWrite(stepPin, LOW);
      delayMicroseconds((int)delayMicros);
    } else {
      digitalWrite(enablePin, HIGH);  // Motor deaktiviert
      delay(10);
    }
  } else {
    digitalWrite(enablePin, HIGH);  // Motor aus
    delay(10);
  }
}

Jetzt hoffe ich, es hat jemand einen Tipp, woran das liegen kann ...

Beste Grüße
Christoph

Hallo.

mag der Compiler diese Codezeile verdauen?

Wenn JA, was ist der Sinn und Zweck der Codezeile?

Ja, es entspricht motorOn = ( !digitalRead(switchPin) );

Was soll ich mir darunter vorstellen?

1 Like

Hallo,
du könntest ein paar Serial.print() einbauen damit Du den Sketch debuggen kannst um ein paar Variable anzuzeigen.
insbesondere wäre der Wert für

float delayMicros = 1e6 / stepsPerSecond / 2;

wichtig. Warum nimmst Du da einen float um anschliessend wieder einen Int draus zu machen

 delayMicroseconds((int)delayMicros);

was kommen denn da so für Wete raus ?

Genau das soll auch der Inhalt sein.

Also mit
const int potThreshold = 20;
war geplant, dass der Motor bei kleiner 20RPM abschaltet um nicht von einem schwierig zu treffenden Nullpunkt abhängig zu sein. Das hatte ich als Deadline interpretiert.

Hallo,
zu Deinen Fragestellungen und Vorschlägen müsste ich jetzt erst wieder recherchieren um halbwegs sinnvoll darauf eingehen zu können. Wie gesagt, habe ich mich bisher immer autodidaktisch durchgehangelt und stoße jetzt halt an die Grenzen.
Ich würde mich freuen, wenn Du mir Vorschläge machen könntest. Ich könnte das ja dann testen und das Ergebnis wieder posten ...

Die was bedeutet?

Guten Morgen,
ich möchte nochmal betonen, dass ich mich nicht wirklich auskenne mit dem Schreiben von Codes für dem Arduino oder anderen Boards mit Mikroprozessor.
Ich wäre aktuell abhängig von Eure Hinweise, falls Ihr eine Fehlerquelle erkennt.
Ich habe aber auch nichts gegen eine "Belehrung".

Beste Grüße

Moin,
meine Recherche ergab, dass ein Dauerrot am DM556 entweder auf fehlerhafte Stromversorgung, Defekt am Treiber oder Fehler bei der Verkabelung hinweist.
Die Stromversorgung von eingestellten 23,5 Volt kommt von einem Schaltnetzteil und schwankt sozusagen 0,0.
Den Treiber habe ich ausgetauscht und erhalte an dem fabrikneuen Austauschtreiber die gleiche "Meldung".
Die Verkabelung habe ich mehrmals mit fehlerfreiem Ergebnis überprüft und dann nochmal von Grund auf neu gemacht.
Demzufolge kann ich mir die rote LED nicht erklären.
Für mich steht jetzt eher der Code im Focus ...

Ich nämlich auch nicht ...
Die LED kennt nur 3 Zustände laut Doku und blinkt nur.

Hier heißt es im letzten Beitrag: Kaputt

Ich versuch grad auch durch den Code durchzusteigen, bin irgendwie verwirrt aber auch noch nicht wach.

AVR?
Dann ist int 16Bit breit und natürlich Vorzeichen behaftet
Micros ist 32Bit und Vorzeichen los

Der Cast verfälscht mit ziemlicher Sicherheit die Daten bis zur Unnutzbarkeit.

Mein Rat: Kundig machen, und nicht nur über Datentypen.
z.B. ein C++ Grundlagenbuch.

Oder wenn du gewöhnt bist technische Dokus zu lesen, dann hier:

Hier ist ein Demo-Code der die MobaTools für die Schalter / Taster und den Schrittmotor benutzt

Das ist eine Ausgangsbasis von der aus du das anpassen kannst.

Ansonsten:

Du benennst den Schrittmotortyp 57HS112-3004426-D21 und den Treiber "DM556"

Dann schreibst du noch

Und auf der dürftigen Informationsbasis sollen jetzt andere einen funktionerenden Code anliefern.

Unverständlich. "um nicht von einem schwierig zu treffenden Nullpunkt abhängig zu sein" ?? Hä ??? Was ???

Also du solltest jetzt einen Link von exakt genau dem Schrittmotortreiber DM556 den du gekauft hast posten. Es gibt als Hersteller Leadshine und dann gibt es mehrere Nachbauten von anderen Herstellern die sich dann natürlich vom Original unterscheiden können.

Du arbeitest an einem Informatik-Projekt und das was in einem Informatikprojekt am meisten gebraucht wird ist detaillierte Information.

Das heißt in diesem Fall eine detailiierte und präzise Beschreibung was du beobachtest wenn du das Programm testest.

Du hast den Schieberegler auf welcher Position stehen langsam oder schnell ?
Was macht dein Programm dann mit dem Schrittmotor dreht er sich oder nicht?

Du schiebst den Schieberegler in Richtung langsamer / schneller?
Was macht der Schrittmotor dann ?
Was macht der Schrittmotor kurz bevor die rote LED angeht?
Was macht der Schrittmotor wenn die rote LED leuchtet?

Hallo,
vielen Dank für Deinen Post und den Link.

Das habe ich nie erwartet und schon gar nicht so dargestellt.
Ich hatte gehofft, dass man mit den entsprechenden Kenntnissen einen Fehler erkennen kann.
Scheint aber nicht so zu sein, also muss ich den Rat von combie aufnehmen

Beste Grüße

Dir ist klar, dass die map-Funktion in dem Fall bei potVal-Werten <20 negative Ergebnisse liefert? map() begrenzt nicht auf die beiden Extremwerte, es definiert nur eine 'Gerade' für die Umsetzung. Die Umsetzung funktioniert auch außerhalb der gesetzten Endwerte.
Wenn Du auf die entsprechenden Endwerte begrenzen willst, brauch Du noch ein 'constrain()'

Ja kann man. Aber dazu müssen die anderen AUCH Kenntnisse über deinen AUFBAU und das gezeigte VERHALTEN des Schrittmotors haben.
Mann ! Ist das so schwer zu verstehen ??!!

Stell dir vor du rufst beim Arzt an und sagst "Mir geht es schlecht können sie mir helfen?"
Mit So wenig Infos kann dir der Arzt NICHT helfen. Selbst die größte Koryphäe nicht

Und du kannst selber ganz viele Fehler erkennen wenn du

Das ist die Selbsthilfemethode die in ganz vielen Fällen weiterhilft.
Meistens ganz direkt in dem du selber erkennt wo der Fehler steckt.
Und falls du es nicht selbst erkennst macht es die Analyse für alle anderen einfacher weil man den kompletten Programmablauf eben nicht im Kopf durchdenken muss sondern die Ausgaben auf den seriellen Monitor mitbenutzen kann.

So meinste jetzt du kannst endlich mal ausführlich Infos anliefern?

Na klar, kann ich ...
Ich stelle die benötigten Infos mal zusammen.
Danke schon mal vorab!!

Mach mal erstmal das, was schon vorgeschlagen war.
Entferne den cast auf intaus der Übergabe an das delayMicroseconds und las Dir die Zeit auf dem sermon ausgeben.

Hallo,
Nach Doku gibt die rote LED einen Hardware Fehler an , wenn sie blinkt. Kann ja auch noch sein das bei dem Motor was falsch verdrahtet ist. Dann muss man eigentlich nicht nach der Software suchen. Ich würde jetzt erst mal den Motor abklemmen und sehen was die LED dann sagt. Achtung vorher Spannung ausschalten, Motor nie unter Spannung an oder abklemmen.
Zu deinem Sketch , mach doch erst mal ganz was einfaches , Motor laufen lassen mit konstanter Speed , in eine Richtung. Entweder nimmst Du ein einfachen Beispiel aus einer Lib. Dazu bieten sich die bereits angesprochenen Mobatools ja bestens an.

oder wenn dir das zu viel Aufwand ist z.B sowas hier, damit müsste er zumindest langsam drehen.

void Loop(){
   digitalWrite(enablePin, LOW);  // Motor aktiv
   digitalWrite(stepPin, HIGH);
   delay(2);
   digitalWrite(stepPin, LOW);
   delay((2);
}

Heinz

Nur damit mein Schweigen nicht als Desinteresse verstanden wird:
Ich werde mich erst am Mittwoch nächster Woche wieder mit dem Fall beschäftigen können.

Ich wünsche Frohe Ostern

1 Like