Schrittmotor Starten/Stoppen

Gast #4994794
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
Gast #4994815
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.
Gast #4994887
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.
Gast #4994895
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.
#4994926
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.
Gast #4994950
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
}
Gast #4994969
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.
Gast #4995064
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
#4995299
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
Beitrag #4995343 wurde von einem Moderator gelöscht.
#4995358
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
 }
#4995491
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren