Nema 17 A4988 mit IR Fernbedienung steuern

Hallo zusammen,

ich möchte einen Nema 17 Schrittmotor mit einem A4988 per IR Fernbedienung steuern. Dabei sollte sich der Schrittmotor, wenn ich z. B. Taste 1 einmal gedrückt habe, drehen, bis ich z. B. Taste 2 gedrückt habe. Ich hatte dabei bisher das Problem, dass sich der Motor, nachdem ich Taste 1 gedrückt habe zwar gedreht hat, ich ihn aber nicht mit einer anderen Taste wieder stoppen konnte. Habt ihr eine Idee, wie ich die zwei folgenden Sketches kombinieren könnte, sodass mein Traum in Erfüllung geht? :wink:

bool Statusvariable = false;

#include "IRremote.h"

int receiver = 11; 

IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

void setup() {


}

void loop() {
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    switch (results.value)
    {
      // deine diversen case
      case 0xFFA25D:
        Statusvariable = false;
        break;

      case 0xFF6897:
        Statusvariable = true;
        break;
    }
    if (Statusvariable)
    {
      // hier soll was passieren wenn Statusvariable = true
    }
  }
}
// defines pins numbers
const int stepPin = 2; 
const int dirPin = 3;
#define ENA 1
 
void setup() {
  // Sets the two pins as Outputs
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);
  pinMode(ENA,OUTPUT);
  digitalWrite(ENA, LOW);
}
void loop() {
  digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for(int schritte = 0; schritte < 200; schritte++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(625); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(625); 
  }
  delay(1000); // One second delay
  
  digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 400 pulses for making two full cycle rotation
  for(int schritte = 0; schritte < 2000; schritte++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(800);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(800);
  }
  delay(1000);
  digitalWrite(ENA, HIGH);
  delay(1000);
  digitalWrite(ENA, LOW);
  
  
}

PS: Der folgende Sketch funktioniert per seriellem Monitor, aber macht genau das, was ich eben mit der IR Fernbedienung brauche.

#include <AccelStepper.h>

AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

int spd = 1000;    // The current speed insteps/second
int sign = 1;      // Either 1, 0or -1

void setup()
{  
  Serial.begin(9600);
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(400);    
}

void loop()
{  
  char c;
  if(Serial.available()) {
    c = Serial.read();
    if (c == 'f') {  // forward
      sign = 1;
    }
    if (c == 'r') {  // reverse
      sign = -1;
    }
    if (c == 's') {  // stop
      sign = 0;
    }
    if (c == '1') {  // medium 
      spd = 400;
    }
    if (c == '2') {  // fast
      spd = 800;
    }
    stepper.setSpeed(sign * spd);
  }
  stepper.runSpeed();
}

Viele Grüße und besten Dank vorab

Wenn der letzte Sketch das tut, was Du willst, dann musst Du doch nur die Befehle der seriellen Schnittstelle durch die IR-Befehle ersetzen.
Hier mal 1:1 umgesetzt:

#include <AccelStepper.h>
#include <IRremote.h>

int receiver = 11;

AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

int spd = 1000;    // The current speed insteps/second
int sign = 1;      // Either 1, 0or -1

IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

void setup()
{ 
  irrecv.enableIRIn(); // Start the receiver
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(400);   
}

void loop()
{ 
  long c;
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    c = results.value;
    if (c == 0xfd4ab5) {  // forward
      sign = 1;
    }
    if (c == 0xfd0af5) {  // reverse
      sign = -1;
    }
    if (c == 0xfd20df) {  // stop
      sign = 0;
    }
    if (c == 0xfd08f7) {  // medium
      spd = 400;
    }
    if (c == 0xfd6a95) {  // fast
      spd = 800;
    }
    stepper.setSpeed(sign * spd);
    irrecv.resume(); // Receive the next value
  }
  stepper.runSpeed();
}

Du musst natürlich die Codes durch die Codes deiner FB ersetzen.
Wobei Du in dem Sketch keine Anfahr- und Bremsrampe benutzt.

MicroBahner:
Wenn der letzte Sketch das tut, was Du willst, dann musst Du doch nur die Befehle der seriellen Schnittstelle durch die IR-Befehle ersetzen.
Hier mal 1:1 umgesetzt:

#include <AccelStepper.h>

#include <IRremote.h>

int receiver = 11;

AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

int spd = 1000;    // The current speed insteps/second
int sign = 1;      // Either 1, 0or -1

IRrecv irrecv(receiver);    // create instance of ‘irrecv’
decode_results results;      // create instance of ‘decode_results’

void setup()
{
  irrecv.enableIRIn(); // Start the receiver
  stepper.setMaxSpeed(1000);
  stepper.setSpeed(400); 
}

void loop()
{
  long c;
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    c = results.value;
    if (c == 0xfd4ab5) {  // forward
      sign = 1;
    }
    if (c == 0xfd0af5) {  // reverse
      sign = -1;
    }
    if (c == 0xfd20df) {  // stop
      sign = 0;
    }
    if (c == 0xfd08f7) {  // medium
      spd = 400;
    }
    if (c == 0xfd6a95) {  // fast
      spd = 800;
    }
    stepper.setSpeed(sign * spd);
    irrecv.resume(); // Receive the next value
  }
  stepper.runSpeed();
}



Du musst natürlich die Codes durch die Codes deiner FB ersetzen.
Wobei Du in dem Sketch keine Anfahr- und Bremsrampe benutzt.

Vielen Dank. Es hat geklappt… Du hast mir sehr geholfen! Jetzt noch eine Frage: Wie könnte ich noch eine Anfahr- und Bremsrampe benutzen? Wäre das möglich, wenn du die noch zu dem folgenden Sketch hinzufügen würdest? Würde mich sehr freuen…

#include <AccelStepper.h>
#include <IRremote.h>

int receiver = 4;
int enable = 5;

AccelStepper stepper(AccelStepper::DRIVER, 2, 3);

int spd = 800;    // The current speed in steps/second
int sign = 1;      // Either 1, 0or -1

IRrecv irrecv(receiver);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

void setup()
{ 
  Serial.begin(9600);
  pinMode(enable, OUTPUT);
  irrecv.enableIRIn(); // Start the receiver
  stepper.setMaxSpeed(800);
  //stepper.setSpeed(800);  
  digitalWrite(enable, HIGH); 
}

void loop()
{ 
  long long c;
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
    Serial.println(results.value, DEC);
    c = results.value;
    if (c == 3763387878 || c == 4014923603) {  // forward
      digitalWrite(enable, LOW);
      delay(30);
      sign = 1;
      spd = 800;
    }
    if (c == 139672439 || c == 1599490922) {  // reverse
      digitalWrite(enable, LOW);
      delay(30);
      sign = -1;
      spd = 800;
    }
    if (c != 3763387878 && c != 4014923603 && c != 139672439 && c != 1599490922) {  // stop
      sign = 0;
      delay(30);
      digitalWrite(enable, HIGH);
    }

//    if (c == 0xfd08f7) {  // medium
//      spd = 800;
//    }
//    if (c == 0xfd6a95) {  // fast
//      spd = 800;
//    }

    stepper.setSpeed(sign * spd);
    irrecv.resume(); // Receive the next value
  }
  stepper.runSpeed();
}

Viele Grüße und besten Dank im Voraus

Hi

Da Du die ACCEL Stepper-Lib benutzt, möchte ich fast wetten, daß Diese bereits Rampen eingebaut hat - Du musst Diese 'nur' einstellen.

Allerdings wirst Du beim Stop die Stop-Position 'weiter in Fahrtrichtung' setzen müssen, da sonst bei STOP die aktuelle Position als Haltepunkt benutzt wird, was zu einem Bremsen (Volle Fahrt auf Null) und in Gegenrichtung beschleunigen um direkt wieder abzubremsen um am Haltepunkt zum Stehen zu kommen.

Du musst also abschätzen, wie lang die Rampe ist und den Stop-Punkt dahin setzen, daß der Stepper bis dahin auch zum Stehen kommt - zur Not hilft hier Versuch und Irrtum - wenn der Stepper nach dem Bremsen noch ein Stück wieder zurück fährt, war der Endpunkt noch nicht weit genug weg.

MfG

Die bisher verwendeten Aufrufe eignen sich nicht um mit Rampe zu fahren. Da muss das Ganze etwas umgestellt werden.
Statt setSpeed -> setMaxSpeed
Statt runSpeed -> run
Da muss dann aber auch eine Zielposition gesetzt werden, damit sich der Stepper dreht. Vorwärts/Rückwärtsfahren ergibt sich durch einen entsprechenden Zielpukt. Im Gegensatz zu setSpeed hat setMaxSpeed kein Vorzeichen.
Der stop-Aufruf setzt die Zielposition selbständig so, dass er mit der aktuellen Rampe bei sofortigem Bremsen dort zum Stehen kommt. In Gegenrichtung fährt er dann nicht mehr.