Timer Stepper Motor

Dear community, could you please help me with the error that I have in the programming code for the schedule.
I have two motors that must do a continuous routine for 3 hours and then they must rest for 30 minutes.

For now I am testing for shorter periods, but the problem is that it only executes a routine and the motors do nothing until the rest command arrives.

I attach the code that I have written.

Thanks!

#include "AccelStepper.h" 
#include <Wire.h>
#include <RTClib.h>


// AccelStepper configuracion

AccelStepper stepperY(AccelStepper::FULL4WIRE, 4, 5, 6,7);   
AccelStepper stepperX(AccelStepper::FULL4WIRE, 8, 9, 10, 11);   

// Define pins a usar para switches home

#define home_switchY 3 // Pin 3 conectado to Home Switch (MicroSwitch) Y

#define home_switchX 2 // Pin 2 conectado to Home Switch (MicroSwitch) X

int rele = 12;    // Define pin a usar para rele
RTC_DS3231 RTC; //declara parametro para reloj

bool inicio = true;
bool fin = true;


// Variables de viaje paso a paso

long initial_homingY=-1;  //Se utiliza para Home paso a paso en el arranque

long initial_homingX=-1;  //Se utiliza para Home paso a paso en el arranque


void setup() {
   
  Serial.begin(9600);  // inicia Serial monitor con velocidad de 9600 Baudios

  Wire.begin(); // Inicia el puerto I2C
  RTC.begin(); // Inicia la comunicaci¢n con el RTC

  //RTC.adjust (DateTime (__DATE__, __TIME__ )); 
  Serial.begin (9600);
  pinMode (rele, OUTPUT);

   
    pinMode(home_switchY, INPUT_PULLUP);
    pinMode(home_switchX, INPUT_PULLUP);
    pinMode (rele, OUTPUT); // Configurar rele como salida o OUTPUT
    delay(5);  // Espera para despertar  Driver 

  // Establecemos la velocidad máxima y la aceleración de cada Steppers en el inicio para el home

  stepperX.setMaxSpeed(100.0);     
  stepperX.setAcceleration(100.0);  
 
  stepperY.setMaxSpeed(100.0);      
  stepperY.setAcceleration(100.0);  


     // Establecemos posicion home

      
    homeX ();

    homeY ();

// Establecemos posicion neutral

      Serial.println("Estableciendo posicion neutral . . .");
      
      stepperX.runToNewPosition(1200);
      stepperY.runToNewPosition(700);
 
      Serial.println("Posicion neutral OK. . .");

}


void loop() {

//    if (initial_homingX > 0) {
//      digitalWrite (rele, HIGH);
//      }
//      else {
//        digitalWrite (rele, LOW);
//        }

    DateTime fecha = RTC.now () ;

  //  Serial.println("Inicia rutina 1  . . .");


  if ( fecha.hour () == 18 && fecha.minute () == 21 ){
    if (inicio == true ) {
      Serial.println ("Inicia rutina 1");
      digitalWrite (rele, HIGH);
      rutina1 ();
      inicio = false;   //desactiva alarma
    }
  }

    
     if ( fecha.hour () == 18 && fecha.minute () == 24 ){
      if (fin == true ) {
        digitalWrite (rele, LOW);
        apagado ();
        Serial.println ("Rutina 1 terminada");
        fin = false;   //desactiva alarma
      }
    } 

    delay (1000);

  if ( fecha.hour () ==  18 && fecha.minute() == 25 ) {
  inicio = true; //reactiva alarma
  fin = true; //reactiva alarma
  }

}



///////////// FUNCIONES by CMR ////////////

//FUNCION HOME MOTOR X


  void homeX()  {
    
                Serial.print("Posicionando Motor X al Home . . . . . . . . . . . ");

            
                while (digitalRead(home_switchX)) {  // Haz que el Stepper se mueva hacia la izquierda hasta que se active el interruptor  
                stepperX.moveTo(initial_homingX);  // Establecer la posición para moverse
                initial_homingX--;  // Disminuye en 1 para el siguiente movimiento si es necesario
                stepperX.run();  //Comienza a mover el paso a paso
                delay(5);
            }
            
              stepperX.setCurrentPosition(0);  // Establecer la posición actual como cero por ahora
              stepperX.setMaxSpeed(100.0);      // Establecer la velocidad máxima de pasos (más lento para obtener una mejor precisión)
              stepperX.setAcceleration(100.0);  // Establecer aceleración de paso a paso
              initial_homingX=1;
            
              while (!digitalRead(home_switchX)) { // Haz que el Stepper se mueva hacia la derecha hasta que el interruptor esté desactivado
                stepperX.moveTo(initial_homingX);  
                stepperX.run();
                initial_homingX++;
                delay(5);
              }
              
              stepperX.setCurrentPosition(0);
              Serial.println("Homing Motor X Completado");
              Serial.println("");
              stepperX.setMaxSpeed(200.0);      // Establecer la velocidad máxima de Stepper (más rápido para movimientos regulares)
              stepperX.setAcceleration(200.0);  // Establecer la aceleración de Stepper
                
                }

//FUNCION HOME MOTOR Y

  void homeY () {

            Serial.print("Posicionando Motor Y al Home . . . . . . . . . . . ");

 
            
              while (digitalRead(home_switchY)) {  // Haz que el Stepper se mueva hacia la izquierda hasta que se active el interruptor  
                stepperY.moveTo(initial_homingY);  // Establecer la posición para moverse
                initial_homingY--;  // Disminuye en 1 para el siguiente movimiento si es necesario
                stepperY.run();  //Comienza a mover el paso a paso
                delay(5);
            }
            
              stepperY.setCurrentPosition(0);  // Establecer la posición actual como cero por ahora
              stepperY.setMaxSpeed(100.0);      // Establecer la velocidad máxima de pasos (más lento para obtener una mejor precisión)
              stepperY.setAcceleration(100.0);  // Establecer aceleración de paso a paso
              initial_homingY=1;
            
            
              while (!digitalRead(home_switchY)) { // Haz que el Stepper se mueva hacia la derecha hasta que el interruptor esté desactivado
                stepperY.moveTo(initial_homingY);  
                stepperY.run();
                initial_homingY++;
                delay(5);
              }
              
              stepperY.setCurrentPosition(0);
              Serial.println("Homing Motor Y Completado");
              Serial.println("");
              stepperY.setMaxSpeed(200.0);      // Establecer la velocidad máxima de Stepper (más rápido para movimientos regulares)
              stepperY.setAcceleration(200.0);  // Establecer la aceleración de Stepper



                }    
  


// FUNCION RUTINA A

    void rutina1 () {

      stepperX.runToNewPosition(1500);
      stepperY.runToNewPosition(800);
      delay(500);
          
      stepperX.runToNewPosition(800);
      stepperY.runToNewPosition(1000);
      delay(500);
  
      stepperX.runToNewPosition(1500);
      stepperY.runToNewPosition(1200);
      delay(500);
                
      stepperX.runToNewPosition(800);
      stepperY.runToNewPosition(1400);
      delay(500);
  
      stepperX.runToNewPosition(1500);
      stepperY.runToNewPosition(1600);
      delay(500);
  
      stepperX.runToNewPosition(800);
      stepperY.runToNewPosition(1800);
      delay(500); 
      
    }



    void apagado (){
      digitalWrite (4, LOW);
      digitalWrite (5, LOW);
      digitalWrite (6, LOW);
      digitalWrite (7, LOW);
      digitalWrite (8, LOW);
      digitalWrite (9, LOW);
      digitalWrite (10, LOW);
      digitalWrite (11, LOW);

      Serial.print ("Motores a reposo");
      }


[code/]

Try some serial debug statements to print out the RTC times and other variables of interest.

aarg:
Try some serial debug statements to print out the RTC times and other variables of interest.

Do I do that by placing comments on each line of code?

cessariuss:
Do I do that by placing comments on each line of code?

No. A comment is something that is read by the author of the program. If you use meaningful names for variables and functions comments are not generally required on lines of code. You might write a comment at the top of a function or of a section of code to remind yourself of what it is intended to do or to note any special requirements.

A Serial.print statement shows the value of a variable while the program is running - so you can check whether it is doing what you think it should be doing.

…R

Hi cessariuss,

to adapt following the answers to your knowledge-level I have a question

If you estimate how mcuh of the details of the posted code doyou understand in detail?

a rough estimation is enough.

a. maybe 10%
b. 60%
c. everything

another question about your project
Will the motors run over midnight? Yes or no?

if no you could use a variable that is counting minutesOfTheDay as

MinutesOfDay = hours * 60 + minutes

example: MinutesOfDay = 18 * 60 + 24 = 1104
three hours later is 1104 + 3 * 60 = 1284

again half an hour later is 1284 +30 = 1314

another possability is to use the function millis()
which returns the amount of milliseconds since booting the microcontroller
millis() rolls over every 4294967296 milliseconds which is 49 days
but there are ways to calculate the elapsedtime that are correct even if the millis()-timer rolls over

here is the explanation how it works
secure coding with millis()

best regards

Stefan

Robin2:
No. A comment is something that is read by the author of the program. If you use meaningful names for variables and functions comments are not generally required on lines of code. You might write a comment at the top of a function or of a section of code to remind yourself of what it is intended to do or to note any special requirements.

A Serial.print statement shows the value of a variable while the program is running - so you can check whether it is doing what you think it should be doing.

...R

I understand, using Serial.Print

Thanks a lot!

StefanL38:
Hi cessariuss,

to adapt following the answers to your knowledge-level I have a question

If you estimate how mcuh of the details of the posted code doyou understand in detail?

a rough estimation is enough.

a. maybe 10%
b. 60%
c. everything

another question about your project
Will the motors run over midnight? Yes or no?

if no you could use a variable that is counting minutesOfTheDay as

MinutesOfDay = hours * 60 + minutes

example: MinutesOfDay = 18 * 60 + 24 = 1104
three hours later is 1104 + 3 * 60 = 1284

again half an hour later is 1284 +30 = 1314

another possability is to use the function millis()
which returns the amount of milliseconds since booting the microcontroller
millis() rolls over every 4294967296 milliseconds which is 49 days
but there are ways to calculate the elapsedtime that are correct even if the millis()-timer rolls over

here is the explanation how it works
secure coding with millis()

best regards

Stefan

Hi Stefan,

The code or programming I understand about 50%.

Regarding working hours, it should also work at night. The ideal is that it works 24 hours a day, but for the health of the engines, I want to take a 30-minute break.

Hi,

so I would recommend using the millis()-function

    unsigned long currentMillis = millis();

    // Read the sensor when needed.
    if (currentMillis - previousMillis >= interval) {
        previousMillis = currentMillis;
        //set bool-variable to "STOP-Stepper"
    }
[color=var(--black-750)]
[/color]

You would set the interval to 3 * 3600 * 1000 = 10800000
3 hours * 3600 seconds per hour * 1000 milliseconds per second

after each stop of the motor you would set the interval to 0,5 hours * 3600 seconds * 1000 milliseconds per second

0.5 * 3600 * 1000 = 1800000

with two boolean-variables it switches between 3 hours running haf and hour pausing

void setup() 
{
  bool motor_runs   = true;
  bool motor_pauses = false;
}

void loop() 
{
    unsigned long currentMillis = millis();

    if (motor_runs && !motor_pauses)
    {
        if (currentMillis - previousMillis >= runtime_interval) 
        {
          previousMillis = currentMillis;
          motor_runs   = false
          motor_pauses = true;
        }
    }    

    if (!motor_runs && motor_pauses)
    {
        if (currentMillis - previousMillis >= pausingtime_interval) 
        {
          previousMillis = currentMillis;
          motor_runs   = true
          motor_pauses = false;
        }
    }
}

you might ask why I'm using two boolean variables.
with using two boolean-vars it is easier to handle other situations than motor is in run/pause-sequence
for maintaing or setting up other things you need a mode where
motor_runs = false
motor_pausing = false

with only using one variable and checking if not motor_runs might make the pausing function to pause
but if pausing-time is over suddenly starts the steppermotor.

It surely can be done in other ways. I find this way easy to understand
It depends on the complete control-logic you will code
best regards

Stefan

aarg:
Try some serial debug statements to print out the RTC times and other variables of interest.

thank you very much..!! With this suggestion I realized why it did not work well. Now I work on the corrections.

Robin2:
No. A comment is something that is read by the author of the program. If you use meaningful names for variables and functions comments are not generally required on lines of code. You might write a comment at the top of a function or of a section of code to remind yourself of what it is intended to do or to note any special requirements.

A Serial.print statement shows the value of a variable while the program is running - so you can check whether it is doing what you think it should be doing.

...R

Robin 2, thanks for your help. It allowed me to detect the error in the program.
Another question, what driver do you suggest for this stepper motor?

Is a model 50BYJ26-30. 12 V, 2 phase, 30Ω

if you still have this question which steppermotor to drive your 12V/30 Ohm steppermotor
Ususally for steppermotors the current and inductivity is given in the specs.
In the specs of the website you gave tey say nothing about current and inductivity.

I have doubts that you can drive it with 12V/30 Ohm = 0,4 A. 30 Ohm is pretty high for stepper-motors
but it is a tiny one with big stepping-angle 7,5 degrees per step.
Usual steppermotors have 1,8 degree stepping-angle with just 2 phases = half the electronics.

4phase and 7,5 degree per step to me seems a bad choice.
What di you want to do in the end?
a stepper-motor is no self-purpose
best regards

Stefan

StefanL38:
if you still have this question which steppermotor to drive your 12V/30 Ohm steppermotor
Ususally for steppermotors the current and inductivity is given in the specs.
In the specs of the website you gave tey say nothing about current and inductivity.

I have doubts that you can drive it with 12V/30 Ohm = 0,4 A. 30 Ohm is pretty high for stepper-motors
but it is a tiny one with big stepping-angle 7,5 degrees per step.
Usual steppermotors have 1,8 degree stepping-angle with just 2 phases = half the electronics.

4phase and 7,5 degree per step to me seems a bad choice.
What di you want to do in the end?
a stepper-motor is no self-purpose
best regards

Stefan

Hello Stefan!

Sorry for so much delay in my response.

From the link that I send, the stepper motor that I am using is the first in the list. The 2 phase with 7.5 degree angle.

Finally what I need to do is move an outdoor PanTilt that holds a housing with a laser inside. I do not need great precision in the movement, only that I am able to work continuously day and night with the rest times that I have discussed in this post.

Thank you for your comments.