Home y Limit switch para stepper motor

Hola, necesito una ayudita

Estoy siguiendo este tutorial: https://arduinogetstarted.com/.../arduino-stepper-motor...

Para usar accelstepper y la libreria ezbutton (muy buena por cierto, https://arduinogetstarted.com/tuto.../arduino-button-library)

En el tuto enseñan como usar un limit switch para detener un stepper y como usar dos limit switch para cambiar la direccion del mismo.

Lo que yo necesito hacer es que con un limit cambie la direccion y que con el otro (Home) lo detenga.

Estuve medio dia tratando y no logro terminar de entender lo suficiente como para combinar ambos ejemplos y hacer lo que necesito, lo mas cerca que estuve es hacer que cambie de direccion y que luego al presionar el limit del home cambie nuevamente y comienze a moverse super lento (step a step aparentemente) pero nunca llega a detenerse

Ahora no tengo acceso al codigo que hice, pero de todas formas no funciona ni de casualidad xD

Si a alguien se le ocurre como combinar ambos, me estaria ayudando muchisimo. O si conocen algun otro proyecto en donde me pueda fijar/guiar para conseguirlo se los agradeceria :3

Lee bien el primer tutorial porque explica como parar el motor con un final de carrera, como cambiar de dirección con un final de carrera y finalmente (o al menos hasta ahí llegué) cambiar de dirección con dos finales de carrera.
O sea, lo que necesitas está.

Por otro lado es de muy mal gusto que para ayudarte debamos tomarnos el trabajo de ir a ver los códigos a otra página, al menos hubieras copiado y pegado ambos ejemplos en tu post.

Saludos

Tienes razon, disculpad.

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-stepper-motor-and-limit-switch
 */

#include <ezButton.h>
#include <AccelStepper.h>

#define DIRECTION_CCW -1
#define DIRECTION_CW   1

#define STATE_CHANGE_DIR 1
#define STATE_MOVE       2
#define STATE_MOVING     3

#define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type)

ezButton limitSwitch_1(A0); // create ezButton object that attach to pin A0;
ezButton limitSwitch_2(A1); // create ezButton object that attach to pin A1;

AccelStepper stepper(AccelStepper::FULL2WIRE, 47, 46);

int stepperState = STATE_MOVE;
int direction    = DIRECTION_CW;
long targetPos   = 0;

bool isStopped = false;



void setup() {
  Serial.begin(9600);

  
  limitSwitch_1.setDebounceTime(50); // set debounce time to 50 milliseconds
  limitSwitch_2.setDebounceTime(50); // set debounce time to 50 milliseconds

  stepper.setMaxSpeed(1500.0);   // set the maximum speed
  stepper.setAcceleration(700.0); // set acceleration
  stepper.setSpeed(1000);         // set initial speed
  stepper.setCurrentPosition(0); // set position
}

void loop() {
  limitSwitch_1.loop(); // MUST call the loop() function first
  limitSwitch_2.loop(); // MUST call the loop() function first

  if (limitSwitch_1.isPressed()) {
    stepperState = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 1: TOUCHED"));
  }
  stepper.run(); // MUST be called in loop() function
 
  switch (stepperState) {
    case STATE_CHANGE_DIR:
      direction *= -1; // change direction
      Serial.print(F("The direction -> "));
      if (direction == DIRECTION_CW)
        Serial.println(F("CLOCKWISE"));
      else
        Serial.println(F("ANTI-CLOCKWISE"));

      stepperState = STATE_MOVE; // after changing direction, go to the next state to move the motor
      break;

    case STATE_MOVE:
      targetPos = direction * MAX_POSITION;
      stepper.setCurrentPosition(0); // set position
      stepper.moveTo(targetPos);
      stepperState = STATE_MOVING; // after moving, go to the next state to keep the motor moving infinity
      break;

    case STATE_MOVING: // without this state, the move will stop after reaching maximum position
      if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position
        stepper.setCurrentPosition(0);   // reset position to 0
        stepper.moveTo(targetPos);       // move the motor to maximum position again
      }
      break;
  }

  if (limitSwitch_2.isPressed()) {
    isStopped = true;
  }

  if (isStopped == false) {
    // without this part, the move will stop after reaching maximum position
    if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position
      stepper.setCurrentPosition(0);   // reset position to 0
      stepper.moveTo(MAX_POSITION);       // move the motor to maximum position again
    }

    stepper.run(); // MUST be called in loop() function
  } else {
    // without calling stepper.run() function, motor stops immediately
    // NOTE: stepper.stop() function does NOT stops motor immediately
    Serial.println(F("The stepper motor is STOPPED"));
  }
}

El problema lo tengo con el limitSwitch_2, si pongo solo el codigo de ese switch todo funciona como deberia, si pongo el codigo solo del limitSwitch_1 todo funciona como deberia.
PERO si pongo ambos codigos juntos, no funciona, ya intente ponerlo en diferentes lugares y formas, pero al final del codigo el switch 2 no detiene el stepper, solo lo cambia de direccion y hace que se mueva stepp x stepp en lugar de su velocidad normal.

Prueba comentando la primer sentencia

stepper.run()

que se ejecuta siempre para que solo se ejecute la siguiente, cuando isStopped es falsa.

Agrego:
Fíjate que hay un comentario en el código que dice que si stepper.run() no se ejecuta el motor se detiene de inmediato y justamente, en tu código, esa primera llamada se ejecuta siempre entonces el motor no se detiene nunca.

Aunque no lo miré en profundidad (son las 3:30 en Bs As :sleeping: ), creo que no hay otros errores .

Saludos

void loop() {
  limitSwitch_1.loop(); // MUST call the loop() function first
  limitSwitch_2.loop(); // MUST call the loop() function first

  if (limitSwitch_1.isPressed()) {
    stepperState = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 1: TOUCHED"));
  }
  stepper.run(); // MUST be called in loop() function

Si comento este primer stepper.run() el stepper no se mueve en absoluto. Si comento el ultimo stepper.run() (al final del codigo) no hay ningun cambio.
Si pongo el primer stepper.run() dentro del if

  if (limitSwitch_1.isPressed()) {
    stepperState = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 1: TOUCHED"));  
    stepper.run(); // MUST be called in loop() function

El stepper no se mueve a menos que presione el switch (pero solo lo hace por un milisegundo y no se mueve hasta que no lo presione de nuevo)

Estoy intentando otra aproximación pero tampoco me esta funcionando :frowning:

A ver así

/*
 * Created by ArduinoGetStarted.com
 *
 * This example code is in the public domain
 *
 * Tutorial page: https://arduinogetstarted.com/tutorials/arduino-stepper-motor-and-limit-switch
 */

#include <ezButton.h>
#include <AccelStepper.h>

#define DIRECTION_CCW -1
#define DIRECTION_CW   1

#define STATE_CHANGE_DIR 1
#define STATE_MOVE       2
#define STATE_MOVING     3

#define MAX_POSITION 0x7FFFFFFF // maximum of position we can set (long type)

ezButton limitSwitch_1(A0); // create ezButton object that attach to pin A0;
ezButton limitSwitch_2(A1); // create ezButton object that attach to pin A1;

AccelStepper stepper(AccelStepper::FULL2WIRE, 47, 46);

int stepperState = STATE_MOVE;
int direction    = DIRECTION_CW;
long targetPos   = 0;

bool isStopped = false;



void setup() {
  Serial.begin(9600);

  
  limitSwitch_1.setDebounceTime(50); // set debounce time to 50 milliseconds
  limitSwitch_2.setDebounceTime(50); // set debounce time to 50 milliseconds

  stepper.setMaxSpeed(1500.0);   // set the maximum speed
  stepper.setAcceleration(700.0); // set acceleration
  stepper.setSpeed(1000);         // set initial speed
  stepper.setCurrentPosition(0); // set position
}

void loop() {
  limitSwitch_1.loop(); // MUST call the loop() function first
  limitSwitch_2.loop(); // MUST call the loop() function first

  if (limitSwitch_1.isPressed()) {
    stepperState = STATE_CHANGE_DIR;
    Serial.println(F("The limit switch 1: TOUCHED"));
  }
  if (!isStopped) stepper.run(); // MUST be called in loop() function
 
  switch (stepperState) {
    case STATE_CHANGE_DIR:
      direction *= -1; // change direction
      Serial.print(F("The direction -> "));
      if (direction == DIRECTION_CW)
        Serial.println(F("CLOCKWISE"));
      else
        Serial.println(F("ANTI-CLOCKWISE"));

      stepperState = STATE_MOVE; // after changing direction, go to the next state to move the motor
      break;

    case STATE_MOVE:
      targetPos = direction * MAX_POSITION;
      stepper.setCurrentPosition(0); // set position
      stepper.moveTo(targetPos);
      stepperState = STATE_MOVING; // after moving, go to the next state to keep the motor moving infinity
      break;

    case STATE_MOVING: // without this state, the move will stop after reaching maximum position
      if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position
        stepper.setCurrentPosition(0);   // reset position to 0
        stepper.moveTo(targetPos);       // move the motor to maximum position again
      }
      break;
  }

  if (limitSwitch_2.isPressed()) {
    isStopped = true;
  }

  if (isStopped == false) {
    // without this part, the move will stop after reaching maximum position
    if (stepper.distanceToGo() == 0) { // if motor moved to the maximum position
      stepper.setCurrentPosition(0);   // reset position to 0
      stepper.moveTo(MAX_POSITION);       // move the motor to maximum position again
    }

    stepper.run(); // MUST be called in loop() function
  } else {
    // without calling stepper.run() function, motor stops immediately
    // NOTE: stepper.stop() function does NOT stops motor immediately
    Serial.println(F("The stepper motor is STOPPED"));
  }
}
1 Like

Sos un genio.
Ahora tengo que hacer un par de cosas mas, seguramente rompa algo y pregunte de nuevo jaja.
Muchisimas gracias, ahora va, toca el limit, vuelve, toca el home y para.
Le voy a poner que en lugar de ir desde un comienzo, vuelva buscando el home, y que luego del home se retire unos centimetros asi no queda presionado, luego de eso ire por un boton que inicie un programa... asi que como ves, tengo mucho para romper jaja

Bueno, me rompi la cabeza tratando de agregar algo a ese codigo (que no termino de entenderlo) asi que hice algo nuevo, mas simple, que hace lo que le pido (al menos x ahora, creo xD)

Que les parece?

#include <AccelStepper.h>
#include <ezButton.h>

#define MAX_POSITION 0x7FFFFFFF // maximum of position
#define DEG_PER_STEP 1.8
#define STEP_PER_REVOLUTION (360 / DEG_PER_STEP)

ezButton homeS(A1);
ezButton limitS(A0);
ezButton start(8);

AccelStepper stepper(AccelStepper::FULL2WIRE, 47, 46);

long Park = STEP_PER_REVOLUTION;
long go = MAX_POSITION;

void setup() {
  Serial.begin(9600);
  homeS.setDebounceTime(50);
  limitS.setDebounceTime(50);
  start.setDebounceTime(50);

  stepper.setAcceleration(100.0); 
  stepper.setSpeed(100);          
  stepper.setCurrentPosition(0);  

  go = -1 * go;       // cambia la direccion a CCW (para buscar el home)
  stepper.moveTo(go); // mueve el motor hasta el infinito y mas alla (home)
}

void loop() {
  homeS.loop(); // loop para botones y switchs
  limitS.loop();
  start.loop();
///////////////////////////////////////////////////////////

  if (homeS.isPressed())
    if (stepper.distanceToGo() != 0) {
      stepper.setCurrentPosition(0); // position to 0
      go = -1 * go; // cambia de nuevo a CW
      stepper.moveTo(Park); // move motor one revolution
    }

  if (limitS.isPressed())      
    if (stepper.distanceToGo() != 0) {
      stepper.setCurrentPosition(0); // reset position to 0
      go = -1 * go; // reverse direction
      stepper.moveTo(go);
      }

  if (start.isPressed())
    stepper.moveTo(go);

    
//////////////////////////////////////////////////////////
  stepper.run(); // MUST be called as frequently as possible
}

Otra duda, cuando intento poner un AND dentro de un If para comprobar dos botones, el codigo no funciona, si solo compruebo el estado de 1 boton, funciona correctamente.

  if (medida1.isPressed() && start.isPressed())
      stepper.moveTo(Park);```

Tengo algun error en el typeo? no termino de entender porque no lo comprueba

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.