Serial.println("Sistema listo. Ingrese comandos Serial:");
Serial.println(" v <velocidad> : Establecer velocidad (mm/s)");
Serial.println(" x <aceleración> : Establecer aceleracion (mm/s^2)");
Serial.println(" c <distancia> : Establecer distancia maxima (mm)");
Serial.println(" a : Mover hacia la izquierda");
Serial.println(" b : Mover hacia la derecha");
}
void loop() {
// Process Serial commands if available
if (Serial.available() > 0) {
char comando = Serial.read();
if (comando == 'v' || comando == 'V') {
float valor = Serial.parseFloat();
if (valor > 0) {
velocidad_mm_s = valor;
stepper.setMaxSpeed(velocidad_mm_s * PASOS_POR_MM);
Serial.print("Velocidad establecida a: ");
Serial.print(velocidad_mm_s);
Serial.println(" mm/s");
}
}
else if (comando == 'x' || comando == 'X') {
float valor = Serial.parseFloat();
if (valor > 0) {
aceleracion_mm_s2 = valor;
originalAceleracion = aceleracion_mm_s2;
stepper.setAcceleration(aceleracion_mm_s2 * PASOS_POR_MM);
Serial.print("Aceleracion establecida a: ");
Serial.print(aceleracion_mm_s2);
Serial.println(" mm/s^2");
}
}
else if (comando == 'c' || comando == 'C') {
float valor = Serial.parseFloat();
if (valor > 0) {
if (valor > 400.0) {
maxDistance_mm = 400.0;
Serial.println("Distancia maxima establecida a: 400 mm (limite del riel)");
} else {
maxDistance_mm = valor;
Serial.print("Distancia maxima establecida a: ");
Serial.print(maxDistance_mm);
Serial.println(" mm");
}
}
}
// Command to move left ("a") if not already moving
else if ((comando == 'b' || comando == 'B') && !moviendo) {
direction = -1; // Negative direction
iniciarMovimiento();
Serial.println("Movimiento hacia la izquierda iniciado.");
}
// Command to move right ("b") if not already moving
else if ((comando == 'a' || comando == 'A') && !moviendo) {
direction = +1; // Positive direction
iniciarMovimiento();
Serial.println("Movimiento hacia la derecha iniciado.");
}
}
// If a movement has been initiated, run the motion profile
if (moviendo) {
stepper.run(); // This updates the motor position according to the acceleration profile
// Check if the traveled distance meets or exceeds the user-set limit:
// For rightward motion: currentPosition >= initialPosition + limitSteps
// For leftward motion: currentPosition <= initialPosition - limitSteps
if (!abruptStopTriggered) {
if (direction > 0 && stepper.currentPosition() >= initialPosition + limitSteps) {
Serial.println("Distancia maxima alcanzada (derecha). Deteniendo abruptamente...");
triggerAbruptStop();
} else if (direction < 0 && stepper.currentPosition() <= initialPosition - limitSteps) {
Serial.println("Distancia maxima alcanzada (izquierda). Deteniendo abruptamente...");
triggerAbruptStop();
}
}
// After triggering the stop, wait until the motor speed drops to zero
if (abruptStopTriggered && (stepper.speed() == 0)) {
// Restore the original acceleration for future moves
stepper.setAcceleration(originalAceleracion * PASOS_POR_MM);
moviendo = false;
}
}
}
//-------------------------------------------------
// Function to initiate movement in the chosen direction
//-------------------------------------------------
void iniciarMovimiento() {
// Record the starting position
initialPosition = stepper.currentPosition();
// Compute the travel limit (in steps) from the distance in mm
limitSteps = (long)(maxDistance_mm * PASOS_POR_MM);
// Reset the movement control flags
moviendo = true;
abruptStopTriggered = false;
// Set a faraway target in the desired direction to force uniform acceleration.
// For rightward movement, use a large positive target; for leftward, a large negative target.
if (direction > 0) {
stepper.moveTo(1000000);
} else {
stepper.moveTo(-1000000);
}
}
//-------------------------------------------------
// Function to trigger abrupt stop by temporarily boosting acceleration
//-------------------------------------------------
void triggerAbruptStop() {
// Temporarily set acceleration to a very high value (simulate an abrupt deceleration)
stepper.setAcceleration(1000000.0 * PASOS_POR_MM);
// Issue stop command; this sets the target to the current position.
stepper.stop();
abruptStopTriggered = true;
}
As I said, this code fulfills the function of stopping the motor abruptly, but it does not fulfill the condition of rapidly accelerating to an initial speed and continuing the movement from there, and furthermore the speed at which it reaches is well below the one that I introduce as the upper limit.