Forum: Mikrocontroller und Digitale Elektronik Schrittmotor Starten/Stoppen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe an einen Nano einen Schrittmotor angeschlossen. Ich 
verwende die Bibliothek stepper.h Der Beispielsketch "Stepper One 
Revolution" funktioniert. Ich möchte nun den Schrittmotor auf 
Tastendruck einschalten und beim loslassen ausschalten. Der Motor soll 
solange drehen wie der Taster gedrückt wird. Mit einem anderen Taster 
das Gleiche anders herum. Ich vermisse aber in der Bibliothek die 
Funktionen ähnlich wie stepper.start() und stepper.stop(). Eigentlich 
könnte ich ja einen kleinen DC-Getriebemotor nehmen, da es auf eine 
genaue Positionierung nicht ankommt, aber ich habe nun mal gerade ein 
paar von diesen Steppern herum liegen. Die sind eigentlich optimal bei 
Drehzahl und Kraft. Vielen Dank für Tipps

von Zweifler (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gemeint ist wohl:
https://www.arduino.cc/en/reference/stepper


Ich würde dieses Beispiel ausbauen an Deiner Stelle ...
https://www.arduino.cc/en/Tutorial/StepperOneStepAtATime

Von einer while-Schleife hast Du sicher schon gehört?

von Martin K. (maart)


Bewertung
0 lesenswert
nicht lesenswert
Pseudocode:

loop{
  solangeTasterVorwärtsGedrückt{
     step(1);
  }

    solangeTasterRückwärtsGerückt{
      step(-1);
    }
}

von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ja, so ähnlich habe ich es schon versucht. Hier macht aber der Motor 
immer nur einen Schritt und stoppt dann kurz und die Drehzahl ist 
wesentlich langsamer  als wenn ich ihn z.B. eine ganze Umdrehung machen 
lassen würde. Ich habe auch schon versucht, eine sehr große Anzahl von 
Schritten einzugeben, aber dann habe ich ja keine Möglichkeit das Teil 
vorher (wenn die Taste losgelassen wird) zu stoppen.

von JojoS (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Der Pseudocode von Martin müsste funktionieren. Wenn die Lib wie hier 
oben genannt verwendet wurde muss ja noch die Geschwindigkeit gesetzt 
werden. Laut Doku ist die Funktion blockierend und step(1) sollte daher 
warten bis ein Schritt fertig ist, abhängig von der Geschwindigkeit. 
Wenn die Geschwindikeit sehr hoch ist und der Stepperdriver viele 
Mikroschritte macht dann wird die Schrittfrequenz auch sehr hoch und die 
Laufzeiten der Tastenabfrage spielen eine Rolle.

von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ja, ich glaube auch, das es funktioniert. So ähnlich hatte ich es auch 
schon probiert. Das Problem ist nur, das durch die einzelnen Schritte 
die Drehzal deutlich sinkt und auch der Lauf wesentlich rauher ist, als 
wenn man z.B.
1000 Schritte auf einmal macht. Aber dann ist ja das Problem, das 
steps()
den Nano blockiert und man keine Möglichkeit hat eine einmal begonnene 
Bewegung  (von z.B. 40000 Schritten) vorzeitig zu stoppen.

von Martin K. (maart)


Bewertung
0 lesenswert
nicht lesenswert
Zeig mal deinen Code.
1
#include <Stepper.h>
2
3
Stepper myStepper(200, 8, 9, 10, 11);
4
void setup() {
5
  // put your setup code here, to run once:
6
  myStepper.setSpeed(200);
7
  pinMode(2, INPUT);
8
}
9
10
void loop() {
11
  // put your main code here, to run repeatedly:
12
  int in;
13
  in = digitalRead(2);
14
  if(in == 1) {
15
    myStepper.step(1);
16
  }
17
}

Ich kann kein Rattern feststellen.

von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ich habe zum Starten keinen Taster sondern eine IR-Fernbedienung 
genommen. Der Motor soll so lange drehen, wie die Taste gedrückt wird. 
Es funktioniert, aber der Motor dreht total langsam.
1
#include <IRremote.h>
2
#include <Stepper.h>
3
#define MAX_TIME 200
4
5
long lastPressTime = 0;
6
int state = LOW;
7
int LED1=11;
8
int LED2=10;
9
const int stepsPerRevolution = 2048;
10
Stepper myStepper(stepsPerRevolution,2,3,4,5);
11
IRrecv irrecv(12);
12
decode_results results;
13
14
void setup()
15
{
16
  pinMode(LED1, OUTPUT);  // Status on pin 3 LED
17
  pinMode(LED2, OUTPUT);  
18
  irrecv.enableIRIn(); // Start the receiver
19
   myStepper.setSpeed(15);
20
  
21
}
22
23
void loop() {
24
  if (irrecv.decode(&results)) {
25
    Serial.println(results.value, DEC);
26
    //if (1) // Can check for a specific button here
27
    if (results.value == 58016) //richtige Taste erkannt
28
    {  Serial.println(results.value, DEC);
29
      if (state == LOW) { 
30
        state = HIGH;  // Button pressed, so set state to HIGH
31
        digitalWrite(LED1, HIGH);
32
       
33
      }
34
    }  
35
  if (state == HIGH) 
36
  {myStepper.step(1);}
37
      lastPressTime = millis();
38
     
39
    
40
    irrecv.resume(); // Receive the next value
41
  }
42
  if (state == HIGH && millis() - lastPressTime > MAX_TIME) {
43
    state = LOW; // Haven't heard from the button for a while, so not pressed
44
    digitalWrite(LED1, LOW);
45
    
46
  }
47
}

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Dann ist es wohl besser das Stepper Ojekt nicht zu benutzen und die 
Pulse 'von Hand' in einem Timer Interrupt selber zu erzeugen. Dann 
bleibt die Schrittfrequenz konstanter und ist unabhägig von der main 
loop.

von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hab ich mir einfacher vorgestellt. Trotzdem vielen Dank für die Hilfe.

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
einfacher ginge es mit Schrittmotortreiber in Hardware, da brauchst du 
nur einen Takt und die Richtung vorzugeben.

Wenn du bei der SW Lösung bleiben willst nimm eine Lib wie
http://www.airspayce.com/mikem/arduino/AccelStepper/classAccelStepper.html
Die arbeitet non-blocking und sollte auch funktionieren.

von Lutz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Danke, werde ich testen.

von Georg (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Lutz schrieb:
> Hab ich mir einfacher vorgestellt

Noch eine kleine Komplikation: ein Schrittmotor hat eine maximale 
Anlauffrequenz, die ist nur ein Bruchteil der maximal möglichen 
Schrittfrequenz. Wird die überschritten, läuft er nicht an, sondern 
brummt höchstens vor sich hin. Also muss man entweder sich auf diese 
niedrige Geschwindigkeit beschränken oder per Software die 
Schrittfrequenz in einer Rampe hochfahren.

Georg

von Johannes S. (jojos)


Bewertung
0 lesenswert
nicht lesenswert
Das wäre noch ein Grund für die AccelStep Lib weil die auch 
beschleunigen kann

von Walter S. (avatar)


Bewertung
0 lesenswert
nicht lesenswert
dein Programmaufbau verhindert eine schnellere Schrittfolge,
beim Überfliegen glaube ich das dein Programm immer auf ein Signal von 
der Fernbedienung wartet bis ein Step ausgeführt wird. Und das Signal 
kommt natürlich nicht ausreichend oft

von Helmut H. (helmuth)


Bewertung
0 lesenswert
nicht lesenswert
Würde zunächst mal das Überflüssige aus dem Code entfernen:
    Serial.println(results.value, DEC);
    Serial.println(results.value, DEC);
    digitalWrite(LED1, HIGH);
    digitalWrite(LED1, LOW);

Walter S. schrieb:
> beim Überfliegen glaube ich das dein Programm immer auf ein Signal von
> der Fernbedienung wartet bis ein Step ausgeführt wird.

irrecv.decode ist nicht blockierend, da ein Timer verwendet wird um den 
recvpin zu pollen, siehe 
https://github.com/z3t0/Arduino-IRremote/blob/master/irRecv.cpp

: Bearbeitet durch User
von Christian M. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ohne jetzt den Code studiert zu haben: Wahrscheinlich wird so nur alle 
ca. 25ms ein Schritt gemacht, wenn ein ganzes Telegramm eingegangen 
ist...?!?!

Gruss Chregu

Beitrag #4995343 wurde vom Autor gelöscht.
von Helmut H. (helmuth)


Bewertung
0 lesenswert
nicht lesenswert
Risiken und Nebenwirkungen der C&V Programmierung:

Aktuell macht er nur einen Step wenn ein IR_Signal empfangen wird.
Obiger Code richtig formatiert (Ctrl-T in der IDE):
1
 if (irrecv.decode(&results)) {
2
        Serial.println(results.value, DEC);
3
        //if (1) // Can check for a specific button here
4
        if (results.value == 58016) //richtige Taste erkannt
5
        {  
6
            Serial.println(results.value, DEC);
7
            if (state == LOW) { 
8
                state = HIGH;  // Button pressed, so set state to HIGH
9
                digitalWrite(LED1, HIGH);
10
            }
11
        }  
12
        if (state == HIGH) 
13
        {
14
            myStepper.step(1);
15
        }
16
        lastPressTime = millis();
17
        irrecv.resume(); // Receive the next value
18
    }

Original von 
https://github.com/z3t0/Arduino-IRremote/wiki/Receiving-with-the-IRremote-library
1
  if (irrecv.decode(&results)) {
2
    if (1) {  // Can check for a specific button here
3
      if (state == LOW) { 
4
        state = HIGH;  // Button pressed, so set state to HIGH
5
        digitalWrite(LED_PIN, HIGH);
6
      }
7
      lastPressTime = millis();
8
    }
9
    irrecv.resume(); // Receive the next value
10
  }

Richtig wäre es danach den Stepper aufzurufen, auch wenn kein Signal 
dekodiert wurde
1
 if (state == HIGH) 
2
 {
3
     myStepper.step(1);
4
 }

: Bearbeitet durch User
von Walter S. (avatar)


Bewertung
0 lesenswert
nicht lesenswert
Helmut H. schrieb:
> Aktuell macht er nur einen Step wenn ein IR_Signal empfangen wird.

hmm, sagte ich das nicht schon weiter oben?

von Helmut H. (helmuth)


Bewertung
0 lesenswert
nicht lesenswert
Walter S. schrieb:
> hmm, sagte ich das nicht schon weiter oben?

Ja, Sorry. Hatte das faslch interpretiert und nur auf die Formatierung 
geschaut und nicht auf die {}. Auf den ersten (Python-geschädigten) 
Blick sah das so aus, als ob der step nach dem "}" von "if 
(irrecv.decode(&results)) {" aufgerufen wird :
1
 if (irrecv.decode(&results)) {
2
    Serial.println(results.value, DEC);
3
    //if (1) // Can check for a specific button here
4
    if (results.value == 58016) //richtige Taste erkannt
5
    {  Serial.println(results.value, DEC);
6
      if (state == LOW) { 
7
        state = HIGH;  // Button pressed, so set state to HIGH
8
        digitalWrite(LED1, HIGH);
9
       
10
      }
11
    }  
12
  if (state == HIGH) 
13
  {myStepper.step(1);}

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]
  • [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.