delay interfering in millis()

Don´t know how but I am working with 2 intervals (5000 and 10000 milliseconds) that happens after a procedure. That procedure works with a delay(1000) and then, the interval takes place. I notice that the intervals become 4000 and 9000 milliseconds where it should be 5000 and 10000 milliseconds, respectively. I have lost entire day trying to understand it and I wasn´t sucessful. The code is below:
I can translate variables names to english if it gets confusing.

int solenoide = 2;
int bomba = 3;
int ventilador = 4;
int botaoDeParada = 6;

void setup() {
Serial.begin(9600);
pinMode(solenoide, OUTPUT);
pinMode(bomba, OUTPUT);
pinMode(ventilador, OUTPUT);
digitalWrite(solenoide, HIGH);
digitalWrite(bomba, HIGH);
digitalWrite(ventilador, HIGH);
}

void liga_ciclo(){
  digitalWrite(solenoide, LOW);
  delay(1000);
  digitalWrite(bomba, LOW);
}
void desliga_ciclo(){
  digitalWrite(bomba, HIGH);
  delay(1000);
  digitalWrite(solenoide, HIGH);
}
void loop() {
 static int leBotao; 
 static int estado = 0;
 static int estadoDoCiclo = 1;
 static unsigned long int previousMillis = 0;
 static unsigned long int currentMillis;
 int intervaloLigado = 5000;
 int intervaloDesligado = 10000; 
 if(estadoDoCiclo == 1){ 
 liga_ciclo();
 previousMillis = currentMillis;
 while(estado == 0){
  currentMillis = millis();
  if((currentMillis - previousMillis) >= intervaloLigado){
    estado = 1;    
  }
  else{
    leBotao = digitalRead(botaoDeParada);
    if(leBotao == HIGH){
      estado = 1;
      estadoDoCiclo = 0;
      delay(500);
    }
  }
 }
 desliga_ciclo();
 previousMillis = currentMillis;
 while(estado == 1){
  currentMillis = millis();
  if((currentMillis - previousMillis) >= intervaloDesligado){
    estado = 0;
  }
  else{
    leBotao = digitalRead(botaoDeParada);
    if(leBotao == HIGH){
      estado = 0;
      estadoDoCiclo = 0;
      delay(500);
    }
  }
 }
 }
 else{
  leBotao = digitalRead(botaoDeParada);
  if(leBotao == HIGH){
    estado = 0;
    estadoDoCiclo = 1;
  }
 }

}

I've loaded your sketch and trying to interpret the portuguese and your code was just a step too far but I can suggest a few things.

  • Move the constant delays (intervaloLigado and its twin) outside of the loop and make them global.
  • Put some serial.print statements in the code so it can print what it actually happening as opposed to what you think is happening
  • If necessary, slow down the main loop so your Serial Monitor window isn't flooded by messages - you need to read them and interpret them

Then post back where you think you have an issue. I know it can be very frustrating but less so than trying to do this for a living (don't ask me how I know this) :o

Exactly. You can't mix delay() and millis() in the same sketch to control the timing of events and hope to get usable results.
In principle, you should anyway avoid delay(). It is crude and blocks everything and is only really for very simple applications.

So you have to look at your delay() statements and convert these to millis() type statements, or otherwise restructure your code to get rid of them.

P.S. in the time I was writing this you have had another approach from Ralph_S_Bacon which I'm sure is a valid alternative.

Ralph_S_Bacon:
I've loaded your sketch and trying to interpret the portuguese and your code was just a step too far but I can suggest a few things.

  • Move the constant delays (intervaloLigado and its twin) outside of the loop and make them global.
  • Put some serial.print statements in the code so it can print what it actually happening as opposed to what you think is happening
  • If necessary, slow down the main loop so your Serial Monitor window isn't flooded by messages - you need to read them and interpret them

Then post back where you think you have an issue. I know it can be very frustrating but less so than trying to do this for a living (don't ask me how I know this) :o

I will put Serial.print statements as you sugested! I will keep you aware!

I changed the old one

void liga_ciclo(){
  digitalWrite(solenoide, LOW);
  delay(1000);
  digitalWrite(bomba, LOW);
}

to the new one:

void liga_ciclo(){
  digitalWrite(solenoide, LOW);
  currentMillis = millis();
  previousMillis = currentMillis;
  while((currentMillis - previousMillis) < 1000){
    currentMillis = millis();  
  }
  digitalWrite(bomba, LOW);
}

…and it worked like a charm! Thank you guys!! really appreciate your help!! thank you very much!!

That shouldn't work any differently. All you've essentially done is inline the code from delay into your code. What you've written there is exactly what delay would have done.