Millis function starting 2 motors at different times

Hello People

Thanks for the pointers on my last post.

I managed to wrap my head around the Millis funcion, which I have been able to make work with LEDs and a DC Motor.

However, I have again hit a wall. The second motor needs to start about 15 seconds after the first motor is finished. Yet, If I just duplicate the code, and alter the variables, they only work simultaneously.

Also, after both are running, about 30 seconds later the startup procedure repeats itself but now in reverse, in order to shut down (and in this case this does happen simultaneously).

Could anyone give me some orientation on what to do here??
Again, I have some experience with arduino and I'm good at programming but I guess this is part of the learning curve.

Here's the code I have so far:

#define A1 10  // Motor A pins
#define A2 9
#define B1 11 // Motor B pins
#define B2 12

int i1 = 0;
int i2 = 0;

long engine1Time = 600;
long engine2Time = 600;
unsigned long hobbsEng1 = 0;// ON time for Eng1
unsigned long hobbsEng2 = 0;// ON time for Eng2

unsigned long engine2Start = 25000;
unsigned long elapsedTime = 0;


void setup() {

  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(B1, OUTPUT);
  pinMode(B2, OUTPUT);
  
  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}



void loop() {

unsigned long timeNow = millis();

//Controlling Engine Number 1
if(timeNow - hobbsEng1 > engine1Time){
  hobbsEng1 += engine1Time;
  if(i1 <= 25){
    engine1Time = 800;
    Serial.println(engine1Time);
    Serial.println(i1);
    analogWrite(A1, i1);
    i1++;
  }
  else if(i1 > 25){
    engine1Time=100;
    analogWrite(A1, i1);
    Serial.println(engine1Time);
    Serial.println(i1);
    i1+=2;
  }
  if(i1 > 255){
    i1 = 255;
    Serial.println(engine1Time);
    Serial.println(i1);
  }



//Controlling Engine Number 2
if(timeNow - hobbsEng2 > engine2Time){
  hobbsEng2 += engine2Time;
  if(i2 <= 25){
    engine2Time = 800;
    Serial.println(engine2Time);
    Serial.println(i2);
    analogWrite(B1, i2);
    i2++;
  }
  else if(i2 > 25){
    engine2Time=100;
    analogWrite(B1, i2);
    Serial.println(engine2Time);
    Serial.println(i2);
    i2+=2;
  }
  if(i2 > 255){
    i2 = 255;
    Serial.println(engine2Time);
    Serial.println(i2);
  }
}

  
}

Please tell in words how the sequence of events is, or even better, draw a picture with a timeline :yum:

A sequence can be put in a table and the millis-timer executes the table (good), or the sequence can be in code (boring) or you can use a Finite State Machine (fancy).

I autoformatted your code and it is below. The "Controlling Engine Number 2" block of code is contained in the "Controlling Engine Number 1" block of code. Is this really what you want?

#define A1 10  // Motor A pins
#define A2 9
#define B1 11 // Motor B pins
#define B2 12

int i1 = 0;
int i2 = 0;

long engine1Time = 600;
long engine2Time = 600;
unsigned long hobbsEng1 = 0;// ON time for Eng1
unsigned long hobbsEng2 = 0;// ON time for Eng2

unsigned long engine2Start = 25000;
unsigned long elapsedTime = 0;


void setup() {

  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(B1, OUTPUT);
  pinMode(B2, OUTPUT);

  Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
}


void loop() {

  unsigned long timeNow = millis();

  //Controlling Engine Number 1
  if (timeNow - hobbsEng1 > engine1Time) {
    hobbsEng1 += engine1Time;
    if (i1 <= 25) {
      engine1Time = 800;
      Serial.println(engine1Time);
      Serial.println(i1);
      analogWrite(A1, i1);
      i1++;
    }
    else if (i1 > 25) {
      engine1Time = 100;
      analogWrite(A1, i1);
      Serial.println(engine1Time);
      Serial.println(i1);
      i1 += 2;
    }
    if (i1 > 255) {
      i1 = 255;
      Serial.println(engine1Time);
      Serial.println(i1);
    }

    //Controlling Engine Number 2
    if (timeNow - hobbsEng2 > engine2Time) {
      hobbsEng2 += engine2Time;
      if (i2 <= 25) {
        engine2Time = 800;
        Serial.println(engine2Time);
        Serial.println(i2);
        analogWrite(B1, i2);
        i2++;
      }
      else if (i2 > 25) {
        engine2Time = 100;
        analogWrite(B1, i2);
        Serial.println(engine2Time);
        Serial.println(i2);
        i2 += 2;
      }
      if (i2 > 255) {
        i2 = 255;
        Serial.println(engine2Time);
        Serial.println(i2);
      }
    }
  }

I've actually managed to do it!!!

Though I'm not sure It is the most efficient way but I'm pretty happy with the result.


#define A1 10  // Motor A pins
#define A2 9
#define B1 11 // Motor B pins
#define B2 12

int i = 0;                            // Contador General, variable para valor de Motor 1 para arranque y determina cuando arrancar motor 2 y apagado
int j = 0;                            // Contador motor 2, variable para valor de Motor 2 para arranque
int k = 120;                          // Contador de apagaddo. Variable utilizada solamente para decremento en apagar los motores

long engineTimer = 850;               // Valor al que se repite el ciclo de motor. Es cambiado durante la operación del mismo.

unsigned long hobbsEng = 0;           // Variable de tiempo de encendido desde el ultimo milisegundo.


unsigned long previousLED1Blink = 0;  // valor al que arranque el LED1
unsigned long LED1BlinkDelay = 900;   // Valor al que se repite el cilco del LED1.
int LEDState1 = LOW;                  // Valor inicial del LED1

unsigned long previousLED2Blink = 0;  // valor al que arranque el LED1
unsigned long LED2BlinkDelay = 960;   // Valor al que se repite el cilco del LED2.
int LEDState2 = HIGH;                 // Valor inicial del LED2



void setup() {

  // Activo Pines de los Motores
  pinMode(A1, OUTPUT);
  pinMode(A2, OUTPUT);
  pinMode(B1, OUTPUT);
  pinMode(B2, OUTPUT);

  // Activo Pines de los LEDs y determino su estado inicial
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  digitalWrite(7, LEDState1);
  digitalWrite(6, LEDState2);

  // Activo monitor en Serie.
  Serial.begin(9600);
}



void loop() {

/*
 * La variable timeNow toma el valor de la funcion millis(); la cual determina el numero de milisegundos desde el que el arduino empieza a funcionar. 
 * Obviamente, el valor de esta variable se incrementa rápidamente conforme pasa el tiempo. Para poder utilizar numeros tan grandes es necesario tener la variable
 * de capacidad máxima de arduino (long) y al ser unsigned (elimina números negativos) permite 
 */
unsigned long timeNow = millis(); 

/* 
 *  Compara el tiempo actual con el tiempo de demora. Si es verdadero, detecta el valor del LED y lo invierte.
 */
if(timeNow - previousLED1Blink > LED1BlinkDelay){
  previousLED1Blink += LED1BlinkDelay;
  if(LEDState1 == HIGH)
    LEDState1 = LOW;
   else
    LEDState1 = HIGH;
  digitalWrite(7, LEDState1);
}

/* 
 *  Compara el tiempo actual con el tiempo de demora. Si es verdadero, detecta el valor del LED y lo invierte.
 */
if(timeNow - previousLED2Blink > LED2BlinkDelay){
  previousLED2Blink += LED2BlinkDelay;
  if(LEDState2 == HIGH)
    LEDState2 = LOW;
   else
    LEDState2 = HIGH;
  digitalWrite(6, LEDState2);
}





/* 
 *  Compara el tiempo actual con el tiempo de demora. Si es verdadero,
 *  Si el contador general es menor a 25, cambia la duración del ciclo a mayor y hace girar el motor 1 en incrementos de 1 para simular un encendido gradual
 */
if(timeNow - hobbsEng > engineTimer){
  hobbsEng += engineTimer;
  if(i <= 25){
    engineTimer = 850;
    Serial.print(i);
    Serial.print("i ");
    Serial.print(j);
    Serial.print("j ");
    Serial.print(k);
    Serial.println("k ");
    analogWrite(A1, i);
    i++;
  }

  //Una vez que el contador general alcanza 25 regresa a velocidad normal hasta llegar a 120 de velocidad del motor 1.
  else if(i >= 25){
    engineTimer=80;
    Serial.print(i);
    Serial.print("i ");
    Serial.print(j);
    Serial.print("j ");
    Serial.print(k);
    Serial.println("k ");
    analogWrite(A1, i);
    if (i >= 120)
      analogWrite(A1, 120);
    i++;


    //Una vez que el contador general alcanza 300 repite la rutiina para el arranque del motor 2.
    if(i >= 300){ //normal 380
      engineTimer=850;
      Serial.print(i);
      Serial.print("i ");
      Serial.print(j);
      Serial.print("j ");
      Serial.print(k);
      Serial.println("k ");
      analogWrite(B1, j);
      i++;
      j++;
      
      if(j >= 25){
        engineTimer = 80;
        Serial.print(i);
        Serial.print("i ");
        Serial.print(j);
        Serial.print("j ");
        Serial.print(k);
        Serial.println("k ");
        analogWrite(B1, j);
        
        if (j >= 120){
          analogWrite(B1, 120);
          j = 120;
        }
      }
    }

  //Una vez que el contador general alcanza 1200 Comienza la secuencia de apagado. Decrementa el valor del contador de apagado y lo alimenta a ambos motores.
    if(i >= 1200){
        Serial.print(i);
        Serial.print("i ");
        Serial.print(j);
        Serial.print("j ");
        Serial.print(k);
        Serial.println("k ");
        analogWrite(A1, k);
        analogWrite(B1, k);
        k--;
        
      
        // Una vez que el contador de apagado alcanza 25, incrementa la duración del ciclo del motor para simular un apagado mas gradual.  
        if(k <= 25)
          engineTimer = 850;


        /* 
         *  Abajo de 10, el voltage proporcionado a los motores no es suficiente para que giren. Para evitar cualquier movimiento es mandado a 0.  
         *  Esto es importante debido a q K va a decrementar a valores negativos para extender la duraación entre el fin de la rutina y el comienzo de la nueva.
         *  Para evitar k mande valores negativos y cualquier movimiento de los motores durante este periodo, ambos son mandados a 0.
         */
        if(k <= 2){
        analogWrite(A1, 0);
        analogWrite(B1, 0);
        }

        // Se decrementa k a -5 para extender el tiempo entre fin de la rutina y el comienzo de la nueva (mediante reiniciar las variables de control de ciclos).
        if(k == -5){

          i = 0;
          j = 0;
          k = 120;
      }
    }
  }
}

}

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