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
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?
Pseudocode: loop{ solangeTasterVorwärtsGedrückt{ step(1); } solangeTasterRückwärtsGerückt{ step(-1); } }
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.
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.
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.
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.
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 | }
|
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.
Hab ich mir einfacher vorgestellt. Trotzdem vielen Dank für die Hilfe.
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.
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
Das wäre noch ein Grund für die AccelStep Lib weil die auch beschleunigen kann
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
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
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.
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
Helmut H. schrieb: > Aktuell macht er nur einen Step wenn ein IR_Signal empfangen wird. hmm, sagte ich das nicht schon weiter oben?
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);} |
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.