Controlar 2 motores paso a paso en base a la posicion de 1 motor

Hola gente, estoy armando una maquina que guía el paso a personas que tiene problemas para caminar o necesitan rehabilitación.
El prototipo cuenta con 2 motores paso a paso, uno que controla el movimiento en X, que en este caso es el desplazamiento del pie, y otro motor que maneja el movimiento en Y, que es el que regula la altura.
En primer medida utilice el codigo SERVO utilizando un servo en vez de un motor en el eje Y, pero debido al poco desplazamiento que tiene el servo, lo descarte.
Este codigo lo que hace es mapear la posicion en que se encuentra el motor del eje X, y en base a eso mueve el servo. Este codigo me funciono perfecto ya que realiza una curva como la de la foto 1.
Mi problema es cuando quiero usar un segundo paso a paso, que no puedo hacer que sea una curva perfecto, codigo PASO A PASO, ambos movimientos no me quedan sincronizados y me realiza una curva como la de la foto 2.
Se que se puede optimizar mucho en tema de no usar delay, usando millis para que la velocidad sea igual. Pero por ahora no le doy importancia, no puedo resolver la manera que ambos motores vayan sincronizados.
Espero que me puedan orientar! Muchas Gracias

FOTO 1

FOTO 2

CODIGO SERVO

#define dirpin 2
#define pulsopin 3
#define lmtpin 4
#include <Servo.h>
Servo myservo;
int x = 100; //mm que se desean mover(ahora probamos con 200mm, esto lo vamos a ajustar de otra manera)
int vel = 260;
int pasos = 0; // variable que controla la cantidad de pasos que se desean hacer
unsigned int pulsos = (x * 400) / 8; //divido entre 8 porque es lo que avanza la varilla en una revolucion, osea el paso de la varilla. Es una regla de 3 simple
int val = 0;
int pos = 0;
void setup() {
  pinMode(dirpin, OUTPUT);
  pinMode(pulsopin, OUTPUT);
  pinMode(lmtpin, INPUT);
  Serial.begin(9600);
  myservo.attach(7);

  val = digitalRead(lmtpin);
  while (val == HIGH) { //mientras el limite de carrera sea HIGH, va a home la maquina, es un seteo inicial
    digitalWrite(dirpin, 1);
    digitalWrite(pulsopin, 1);
    delayMicroseconds(400);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(400);
    val = digitalRead(lmtpin);
  }

  for (int i = 0; i < 400 ; i++) { //hago una separacion del limite de 8mm para que en cada paso no toque el final de carrera
    digitalWrite(dirpin, 0);
    digitalWrite(pulsopin, 1);
    delayMicroseconds(500);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(500);
  }

}

void loop() {
  digitalWrite(dirpin, 0);
  for (int i = 0 ; i < pulsos ; i++) { //va hacia adelante moviendo el servo de 0 a 180
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    pos = map(i, 0, pulsos, 0, 180);
    myservo.write(pos);
  }
  digitalWrite(dirpin, 1);
  for (int i = 0 ; i < pulsos ; i++) { // va hacia atras sin que se mueva el servo, uso map igual para que no se modifique la velocidad de movimiento
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    pos = map(i, 0, pulsos, 180, 180);
    myservo.write(pos);
  }
  digitalWrite(dirpin, 0);
  for (int i = 0 ; i < pulsos ; i++) { // va hacia adelante moviendo el servo pero en sentido contrario, de 180 a 0

    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    pos = map(i, 0, pulsos, 180, 0);
    myservo.write(pos);
  }
  digitalWrite(dirpin, 1);
  for (int i = 0 ; i < pulsos ; i++) {
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    pos = map(i, 0, pulsos, 0, 0);
    myservo.write(pos);
  }
}

CODIGO MOTOR PASO A PASO

#define dirpin 2
#define pulsopin 3
#define lmtpin 4
#define dirpiny 6
#define pulsopiny 5
#define lmtpiny 7

//int ppr = 400; //pulsos por revolucion (el motor necesita 200 pulsos por revolucion, pero como usamos micropasos 1/2, se necesitan 200*0,5=400 pulsos para dar una revulcion)
int x = 200;
int y = 50;
int vel = 300;
int pasos = 0; // variable que controla la cantidad de pasos que se desean hacer
unsigned int pulsos = (x * 400) / 8;
unsigned int pulsosy = (y * 400) / 8;//divido entre 8 porque es lo que avanza la varilla en una revolucion, osea el paso de la varilla. Es una regla de 3 simple
int val = 0;
int valy = 0;



void setup() {
  pinMode(dirpin, OUTPUT);
  pinMode(pulsopin, OUTPUT);
  pinMode(lmtpin, INPUT);
  Serial.begin(9600);
  pinMode(dirpiny, OUTPUT);
  pinMode(pulsopiny, OUTPUT);
  pinMode(lmtpiny, INPUT);
  val = digitalRead(lmtpin);
  while (val == HIGH) { //mientras el limite de carrera sea HIGH, va a home la maquina, es un seteo inicial
    digitalWrite(dirpin, 1);
    digitalWrite(pulsopin, 1);
    delayMicroseconds(400);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(400);
    val = digitalRead(lmtpin);
  }
  for (int j = 0; j < 400 ; j++) { //hago una separacion del limite de 8mm para que en cada paso no toque el final de carrera
    digitalWrite(dirpin, 0);
    digitalWrite(pulsopin, 1);
    delayMicroseconds(500);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(500);
  }
  valy = digitalRead(lmtpiny);
  while (valy == HIGH) { //mientras el limite de carrera sea HIGH, va a home la maquina, es un seteo inicial
    digitalWrite(dirpiny, 0);
    digitalWrite(pulsopiny, 1);
    delayMicroseconds(400);
    digitalWrite(pulsopiny, 0);
    delayMicroseconds(400);
    valy = digitalRead(lmtpiny);
  }
  for (int j = 0; j < 400 ; j++) { //hago una separacion del limite de 8mm para que en cada paso no toque el final de carrera
    digitalWrite(dirpiny, 1);
    digitalWrite(pulsopiny, 1);
    delayMicroseconds(500);
    digitalWrite(pulsopiny, 0);
    delayMicroseconds(500);
  }

}

void loop() {
  digitalWrite(dirpin, 0);
  digitalWrite(dirpiny, 1);

  for (int i = 0 ; i < pulsos / 2 ; i++) {
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    if (i < pulsosy) {
      digitalWrite(pulsopiny, 1);
      delayMicroseconds(vel);
      digitalWrite(pulsopiny, 0);
      delayMicroseconds(vel);
    }
  }
  digitalWrite(dirpiny, 0);
  for (int i = 0 ; i < pulsos / 2 ; i++) {
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
    if (i < pulsosy) {
      digitalWrite(pulsopiny, 1);
      delayMicroseconds(vel);
      digitalWrite(pulsopiny, 0);
      delayMicroseconds(vel);
    }
  }
  digitalWrite(dirpin, 1);
  digitalWrite(dirpiny, 0);

  for (int i = 0 ; i < pulsos ; i++) {
    digitalWrite(pulsopin, 1);
    delayMicroseconds(vel);
    digitalWrite(pulsopin, 0);
    delayMicroseconds(vel);
  }
}

Usa AccelStepper: AccelStepper library for Arduino en lugar de Stepper.
Verás que es una librería no bloqueante.

Intente con esa libreria moviendo solo el motor del eje X, hace el seteo inicial, que es un final de carrera, luego comienza a ir de adelante hacia atras, pero cuando va hacia atras, se pasa de largo, es decir, mueva mucho mas hacia atras que hacia adelante.

#include <AccelStepper.h>

// The X Stepper pins
#define STEPPER1_DIR_PIN 2
#define STEPPER1_STEP_PIN 3
// The Y stepper pins
#define STEPPER2_DIR_PIN 6
#define STEPPER2_STEP_PIN 5

// Define some steppers and the pins the will use
AccelStepper stepper1(AccelStepper::DRIVER, STEPPER1_STEP_PIN, STEPPER1_DIR_PIN);
AccelStepper stepper2(AccelStepper::DRIVER, STEPPER2_STEP_PIN, STEPPER2_DIR_PIN);
#define lmtpin1 7
#define lmtpin 4
int val = 0;
int val1 = 0;
int x = 500;
void setup()
{  
    stepper1.setMaxSpeed(1500.0);
    stepper1.setAcceleration(1000.0);
    stepper1.setSpeed(1000);
    
    stepper2.setMaxSpeed(1500.0);
    stepper2.setAcceleration(1000.0);
    stepper2.setSpeed(1000);
  
    
 pinMode(lmtpin, INPUT);
 pinMode(lmtpin1, INPUT);
  
  val = digitalRead(lmtpin);
  while (val == HIGH) { //mientras el limite de carrera sea HIGH, va a home la maquina, es un seteo inicial
     stepper1.setSpeed(1000);
     stepper1.runSpeed();
      val = digitalRead(lmtpin);
  }
stepper1.setCurrentPosition(0);
stepper1.runToNewPosition(-150);
stepper1.setCurrentPosition(0);

   val1 = digitalRead(lmtpin);
  while (val1 == HIGH) { //mientras el limite de carrera sea HIGH, va a home la maquina, es un seteo inicial
     stepper2.setSpeed(-1000);
     stepper2.runSpeed();
      val1 = digitalRead(lmtpin1);
  }
stepper2.setCurrentPosition(0);
stepper2.runToNewPosition(150);
stepper2.setCurrentPosition(0);

}
void loop() {
stepper1.moveTo(-500);
while(stepper1.distanceToGo() != 0) {
stepper1.run();
}
stepper1.moveTo(500);
while(stepper1.distanceToGo() != 0) {
stepper1.run();
}
}

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