dont understand how to use of millis() and "for" loop

Hi. I need help as soon as possible since it is a school project and we must compete in a couple of weeks.

I write this again but in english, I suppose that here will read people from all the world. If its necessary, I can delete the post in spanish. Thanks

I am programming a minisumo robot and I have the problem that the FOR loop that is in the configuration what is an incredible speed, without respecting the 3 sec that I think I have ordered. I leave the programming until that part:

int IN1 = 4;
int IN2 = 5;
int ENA = 11;
int IN3 = 6;
int IN4 = 7;
int ENB = 10;
// Sensores Linea
int sensor_linea_izq = A5;
int linea_izq = 0;
int sensor_linea_der = A4;
int linea_der = 0;
// Sensores Distanciia
int tri_der = 13;
int echo_der = 12;
int tri_izq = 9;
int echo_izq = 8; 
float tiempo_de_espera_izq,distancia_izq; 
float tiempo_de_espera_der,distancia_der;
byte x;

// millis()
const unsigned long derecha_ini_1 = 3000;        
const unsigned long izquierda_ini_1 = 3000;

unsigned long der_ini_startMillis;
unsigned long izq_ini_startMillis;
unsigned long currentMillis;

void setup(){ 
  Serial.begin(9600);
  Serial.println("iniciando lectura sensor");
  pinMode(13, OUTPUT); // PIN 13 TRIGGER derecho
  pinMode(12, INPUT);  // PIN 12 ECHO derecho
  pinMode(9, OUTPUT); // PIN 9 TRIGGER izquierdo
  pinMode(8, INPUT);  // PIN 8 ECHO izquierdo
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(A5, INPUT);
  pinMode(A4, INPUT);
  delay(5000);
  der_ini_startMillis = millis();    // guarda el tiempo de inicio

for(x=0;x<5;x=x+1){
  sensores();
  if((linea_izq>700)&&(linea_der>700)&&(distancia_der>20)&&(distancia_izq>20)) {
    currentMillis = millis();
    if(currentMillis - der_ini_startMillis <= derecha_ini_1) {
    derecha_f();
    Serial.println("derecha inicial");
    izq_ini_startMillis = currentMillis;
    }
    if(currentMillis - izq_ini_startMillis <= izquierda_ini_1) {
    izquierda_f();
    Serial.println("izquierda inicial");
  }
}
}
}

If there is an error in the use of millis (), explain to me how it is used please, because I am tired of walking forum by page, page by page, video by video trying to understand and it is getting complicated (I think I understand it but to the time to put it into practice does not seem good to me).

I also know that I have to put the distance sensors with millis (two HC-SR04), but I want to know that I'm doing it right at the beginning so I do not work on that by doing it incorrectly.

I leave the complete programming down as well in case it is necessary. I am using an Arduino one, bridge h l298n, and two infrared sensors tcrt5000.

Thanks since now

int IN1 = 4;
int IN2 = 5;
int ENA = 11;
int IN3 = 6;
int IN4 = 7;
int ENB = 10;
// Sensores Linea
int sensor_linea_izq = A5;
int linea_izq = 0;
int sensor_linea_der = A4;
int linea_der = 0;
// Sensores Distanciia
int tri_der = 13;
int echo_der = 12;
int tri_izq = 9;
int echo_izq = 8; 
float tiempo_de_espera_izq,distancia_izq; 
float tiempo_de_espera_der,distancia_der;
byte x;

// millis()
const unsigned long derecha_ini_1 = 3000;        
const unsigned long izquierda_ini_1 = 3000;

unsigned long der_ini_startMillis;
unsigned long izq_ini_startMillis;
unsigned long currentMillis;

void setup(){ 
  Serial.begin(9600);
  Serial.println("iniciando lectura sensor");
  pinMode(13, OUTPUT); // PIN 13 TRIGGER derecho
  pinMode(12, INPUT);  // PIN 12 ECHO derecho
  pinMode(9, OUTPUT); // PIN 9 TRIGGER izquierdo
  pinMode(8, INPUT);  // PIN 8 ECHO izquierdo
  pinMode(7, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(A5, INPUT);
  pinMode(A4, INPUT);
  delay(5000);
  der_ini_startMillis = millis();    // guarda el tiempo de inicio

for(x=0;x<5;x=x+1){
  sensores();
  if((linea_izq>700)&&(linea_der>700)&&(distancia_der>20)&&(distancia_izq>20)) {
    currentMillis = millis();
    if(currentMillis - der_ini_startMillis <= derecha_ini_1) {
    derecha_f();
    Serial.println("derecha inicial");
    izq_ini_startMillis = currentMillis;
    }
    if(currentMillis - izq_ini_startMillis <= izquierda_ini_1) {
    izquierda_f();
    Serial.println("izquierda inicial");
  }
}
}
}


void loop(){

  sensores();
  
  // ACCIONES
  if((linea_izq>700)&&(linea_der>700)&&(distancia_izq<=10)&&(distancia_der<=10)){ // si ambos detectan suelo negro y objeto
    adelante_f();                  // adelante fuerte
    Serial.println("avanza");
  }

  if((linea_izq>700)&&(linea_der>700)&&(distancia_izq>10)&&(distancia_der>10)){ // si detectan suelo negro y ningun objeto
    izquierda_f();                // izquierda despacio
    Serial.println("busca");
  }

  if((linea_izq>700)&&(linea_der>700)&&(distancia_izq<=10)&&(distancia_der>10)){ // si detectan suelo negro y objeto a la izquierda
    izquierda_f();         // izquierda fuerte
    Serial.println("izquierda fuerte");
  }

  if((linea_izq>700)&&(linea_der>700)&&(distancia_izq>10)&&(distancia_der<=10)){  // si detectan suelo negro y objeto a la derecha 
    derecha_f();          // derecha fuerte 
    Serial.println("derecha fuerte");
  }

  if((linea_izq<=700)||(linea_der<=700)&&(distancia_der>20)&&(distancia_izq>20)){                   // si cualquiera detecta linea blanca 
    reversa_f();                   // atras fuerte
    Serial.println("retrocede");
    delay(700);                 // confugurarlo bien
  }
}

  // VOID SENSORES

void sensores(){
  linea_izq = analogRead(A5);  // SENSORES LINEA 
  linea_der = analogRead(A4);

  
  digitalWrite (13, 0);     // SENSORES DISTANCIA
  delayMicroseconds(2);
  digitalWrite (13, 1); 
  delayMicroseconds (10);    
  digitalWrite (13, 0); 
  
  tiempo_de_espera_der = pulseIn (12, 1);              // pulseIn recibe la señal emitida por trigger
  distancia_der = (tiempo_de_espera_der/2)/29.15;        // calcula la distancia

  digitalWrite (9, 0);
  delayMicroseconds(2);
  digitalWrite (9, 1);
  delayMicroseconds (10); 
  digitalWrite (9, 0); 

  tiempo_de_espera_izq = pulseIn (8, 1);
  distancia_izq = (tiempo_de_espera_izq/2)/29.15;
}

  // VOID MOTORES

void adelante_f(){  // avanza hacia adelante fuerte
  digitalWrite(IN1, 1);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 1);
  digitalWrite(IN4, 0);
  analogWrite(ENA, 255);
  analogWrite(ENB, 255);  
}

void adelante_d(){  // avanza hacia adelante despacio
  digitalWrite(IN1, 1);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 1);
  digitalWrite(IN4, 0);
  analogWrite(ENA, 125);
  analogWrite(ENB, 125);
}

void reversa_f(){  // retrocede fuerte
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 1);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 1);
  analogWrite(ENA, 255);
  analogWrite(ENB, 255);
}

void derecha_f(){  // mueve hacia la derecha fuerte
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 1);
  analogWrite(ENA, LOW);
  analogWrite(ENB, 255);
}

void derecha_d(){  // mueve hacia la derecha despacio
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 1);
  analogWrite(ENA, LOW);
  analogWrite(ENB, 125);
}

void izquierda_f(){  // mueve hacia la izquierda fuerte
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 1);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
  analogWrite(ENA, 255);
  analogWrite(ENB, LOW);
}

void izquierda_d(){  // mueve hacia la izquierda despacio
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 1);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
  analogWrite(ENA, 125);
  analogWrite(ENB, LOW);
}

void detener(){     // se detiene
  digitalWrite(IN1, 0);
  digitalWrite(IN2, 0);
  digitalWrite(IN3, 0);
  digitalWrite(IN4, 0);
  analogWrite(ENA, LOW);
  analogWrite(ENB, LOW);
}

What should it do ? How should it behave ?

Your question in Spanish: Uso de millis() y for para sumorobot - Software - Arduino Forum
Did you use Google Translate for the English question ?

The use of millis() is often done in the Arduino loop(), because the loop() is executed repeatedly.
I don't understand why you use millis() in the Arduino setup() function.

Koepel:
What should it do ? How should it behave ?

Your question in Spanish: Uso de millis() y for para sumorobot - Software - Arduino Forum
Did you use Google Translate for the English question ?

The use of millis() is often done in the Arduino loop(), because the loop() is executed repeatedly.
I don't understand why you use millis() in the Arduino setup() function.

I put that loop in the setup() function because i want that the robot only do this accion at the beggining.

Answering your question:
I want that when starting my mini-sumo robot, make a search move ONLY at the beginning (that is repeated until something is detected with the two distance sensors, or a maximum of 5 times). After this happens, I'm not interested in being repeated, I do not want that to happen, so I'm writing in the void setup (). After that, the robot must look for rivals in the ring and remove it from it, trying not to leave the ring during the search

I am using an UNO arduino, two sensors hc sr04 for distance, two tcrt500 for the ground, and a bridge H l298n. regards

Then the for-loop is for maximum of 5 times.

bool search_for_rival = true;
for( int i=0; i<5 && search_for_rival; i++)
{
  look for a rival
  if(  a rival is found
  {
    search_for_rival = false;    // stop the loop
  }
}

What has millis() to do with this ?
The millis() function returns the number of milliseconds, it is used for timekeeping, for delays, for intervals, and so on.

Looking at this piece of code

for(x=0;x<5;x=x+1){
  sensores();
  if((linea_izq>700)&&(linea_der>700)&&(distancia_der>20)&&(distancia_izq>20)) {
    currentMillis = millis();
    if(currentMillis - der_ini_startMillis <= derecha_ini_1) {
    derecha_f();

I think you need to check for millis() before you do the FOR. The way it is written now it checks 5 times in quick succession but the time will have advanced very little.

You need to wait a certain time between each test - i.e. check the time before you do a test

numTests = 0;
while (numTests < 5);
   if (millis() - timeOfLastTest >= testInterval) {
       timeOflastTest = millis();
       // code to do another test
       numTests ++
    }
}

...R

Robin2:
Looking at this piece of code

for(x=0;x<5;x=x+1){

sensores();
  if((linea_izq>700)&&(linea_der>700)&&(distancia_der>20)&&(distancia_izq>20)) {
    currentMillis = millis();
    if(currentMillis - der_ini_startMillis <= derecha_ini_1) {
    derecha_f();



I think you need to check for millis() before you do the FOR. The way it is written now it checks 5 times in quick succession but the time will have advanced very little.

You need to wait a certain time between each test - i.e. check the time before you do a test


numTests = 0;
while (numTests < 5);
  if (millis() - timeOfLastTest >= testInterval) {
      timeOflastTest = millis();
      // code to do another test
      numTests ++
    }
}




...R

Thanks, I'm trying things with what you told me but I cant do anything.

I'm getting frustrated already, I do not know if I do not understand, if they do not understand me, or what hahahah.

I just want that my robot turn first to the left and then to the right, five times, only when I stiwtch it on. I can do it with delays, but i cant do it with millis, and I know that is necessary use millis

I'm going to try to do it but only using "if", putting the void "turn left" ("izquierda_f" in my program) and "turn right" ("derecha_f"), five alternate times, I hope it works

In the Arduino setup() function you can use delays.
Unless you want to test a input (for example a button) while doing something.
You could also move that code to the loop() and run it once with the help of a boolean variable.

27ivan27:
Thanks, I'm trying things with what you told me but I cant do anything.

You have to post the program that you tried if we are to be able to help you.

...R

Robin2:
You have to post the program that you tried if we are to be able to help you.

...R

Koepel:
In the Arduino setup() function you can use delays.
Unless you want to test a input (for example a button) while doing something.
You could also move that code to the loop() and run it once with the help of a boolean variable.

Hi, excuse me if I've delayed writing. I understand what you say, and tomorrow I will to test what you say about handling it in the loop using a Boolean variable.

But for the meantime, I leave the code with delay that works perfectly.

for(x=0;x<5;x=x+1){
  sensores();
  if((linea_izq>700)&&(linea_der>700)&&(distancia_der>20)&&(distancia_izq>20)) {
    derecha_f();
    Serial.println("derecha inicial");
    delay(3000);

    izquierda_f();
    Serial.println("izquierda inicial");
    delay(3000);
  }else {
    break;
  }
}
}

can you pass it to delay? just that, to see how it is done, I have two more codes (one to clear areas, and another line follower - obstacle evader) in which I must change delay () by millis (). So, if I see what procedure you follow in this part of my code, maybe I will understand it once and for all, and do the other codes by myself.

In case you are interested in knowing, it is a robotics triathlon (sumo, line follower and evader, and clear areas)

There is nothing wrong with those delays.
A delay in the Arduino loop() function is a problem, because then nothing else can be done. A delay during the setup() function that is often no problem.

Koepel:
There is nothing wrong with those delays.
A delay in the Arduino loop() function is a problem, because then nothing else can be done. A delay during the setup() function that is often no problem.

Yes I understand. But the problem is that if it detects an opponent until it ends the action of moving (set by the delay) does not attack. That is, it does not leave the FOR loop until the end of both functions (derecha() and izquierda())

I want it to barely detect, act the "break" and leave the for loop, and not delay until the delay to leave it.