Delay without delay

Can anyone tell me how I can delay the start of a sketch without using the delay finction?

I know about the millis() function, but I can not get it to work as I want.

If i press a button it should wait for 10 seconds before running the sketch.

I can not get it to work as I want.

Post what you tried

Have you looked at Using millis() for timing. A beginners guide, Several things at the same time and the BlinkWithoutDelay example in the IDE

Here is my code. I just want it to start after 10 seconds after (knapp) is set HIGH,

int sensorInterrupt   = 0;
int sensorInterrupt2  = 1;  // interrupt 1
int sensorPin         = 2; //Digital Pin 2
int sensorPin2        = 3; //Digital Pin 3
int solenoidValve     = 8; // Digital pin 8
int solenoidValve2    = 9; // Digital pin 9
int knapp             = 5;
int reset             = 10;

unsigned int SetPoint = 400; //400 milileter
 
float calibrationFactor = 90; //You can change according to your datasheet
 
volatile int pulseCount   =0;
volatile int pulseCount2  =0;   
 
float flowRate    = 0.0;
float flowRate2   = 0.0;

unsigned int flowMilliLitres  =0;
unsigned int flowMilliLitres2 =0;

unsigned long totalMilliLitres  = 0;
unsigned long totalMilliLitres2 = 0;
unsigned long oldTime   = 0;
unsigned long oldTime2  = 0;

unsigned long test = 10000;
 
void setup(){
 
  Serial.begin(9600);
  pinMode(solenoidValve,    OUTPUT);
  pinMode(solenoidValve2,   OUTPUT);
  pinMode(sensorPin,        INPUT);
  pinMode(sensorPin2,       INPUT);
  pinMode(knapp,            INPUT);
  pinMode(reset,            OUTPUT);
  digitalWrite(sensorPin,   HIGH);
  digitalWrite(sensorPin2,  HIGH);
  digitalWrite(reset,       LOW);
  digitalWrite(knapp,       LOW); 
  
  attachInterrupt(sensorInterrupt, pulseCounter, FALLING); 
  attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING); 

  
}
 
void loop(){
  
  if(digitalRead(knapp) == LOW){ 

    digitalWrite(solenoidValve, LOW);
    digitalWrite(solenoidValve2, LOW);
    totalMilliLitres =0;
    totalMilliLitres2 =0;
    }

  if(digitalRead(knapp) == HIGH){

    
  if((millis() - oldTime) > 1000){
  
    detachInterrupt(sensorInterrupt);
    detachInterrupt(sensorInterrupt2);
 
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    flowRate2 = ((1000.0 / (millis() - oldTime)) * pulseCount2) / calibrationFactor;

    oldTime = millis();

    flowMilliLitres = (flowRate / 60) * 1000;
    flowMilliLitres2 = (flowRate2 / 60) * 1000;
 
    totalMilliLitres += flowMilliLitres;
    totalMilliLitres2 += flowMilliLitres2;
 
    unsigned int frac;
 
    Serial.print("Flow rate: ");
    Serial.print(flowMilliLitres);  
    Serial.print("mL/Second");
    Serial.print("\t");  
           
    Serial.print("Flow rate2: ");
    Serial.print(flowMilliLitres2);
    Serial.print("mL/Second");
    Serial.print("\t");  
 
    Serial.print("Output Liquid Quantity: ");        
    Serial.print(totalMilliLitres);
    Serial.println("mL"); 
    Serial.print("\t");   

    Serial.print("Output Liquid Quantity2: ");        
    Serial.print(totalMilliLitres2);
    Serial.println("mL"); 
    Serial.print("\t");  
        
    if (totalMilliLitres >= 30 && digitalRead(knapp) == HIGH){      
      digitalWrite(solenoidValve, LOW);
      }
      else{
        digitalWrite(solenoidValve, HIGH);
      }
           
      if (totalMilliLitres2 >= 30 && digitalRead(knapp) == HIGH){      
      digitalWrite(solenoidValve2, LOW);
      }
        else{
        digitalWrite(solenoidValve2, HIGH);
      }

    pulseCount  = 0;
    pulseCount2 = 0;
      
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);
  }
  }

}
 
void pulseCounter()
{
  pulseCount++;
}
void pulseCounter2()
{
  pulseCount2++;
}

it is probably an easy thing to do, but I'm not seeing it right now.

Why can't you do the same as you did with 'oldTime'? Only this time, save millis() when knapp-pin becomes high (tip: state change).

Have you got a pulldown resistor in place keeping knapp LOW when it is not HIGH ?

there is another aspect in your code
you do detach the interrupts at the beginning
then you do the calculations and all the printing and after all this is done -
and in terms of a fast running loop - a lot of time has passed by you attach the interrupts again at the end.

This might lead to missed pulses. You should copy the values of pulseCount / pulseCount2 to another variable and work with this copy for the calculations and then immediately attach interrupts again. This will keep the time where no pulses are counted as short as possible.

  if((millis() - oldTime) > 1000){
 
    detachInterrupt(sensorInterrupt);
    detachInterrupt(sensorInterrupt2);
    
    pulseCountForCalc = pulseCount;
    pulseCountForCalc2 = pulseCount2;

    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);

best regards Stefan

I'm sorry but I don't understand what you meen. :slight_smile:

frodv:
If i press a button it should wait for 10 seconds before running the sketch.

I presume this will happen within setup() and it seems to be a situation where delay() would be appropriate and the simplest solution.

...R

frodv:
I'm sorry but I don't understand what you meen. :slight_smile:

You do not say what you don't understand

UKHeliBob:
You do not say what you don't understand

Or even who for that matter...

your loop()

void loop(){
 
  if(digitalRead(knapp) == LOW){

    digitalWrite(solenoidValve, LOW);
    digitalWrite(solenoidValve2, LOW);
    totalMilliLitres =0;
    totalMilliLitres2 =0;
    }

  if(digitalRead(knapp) == HIGH){

   
  if((millis() - oldTime) > 1000){
 
    detachInterrupt(sensorInterrupt);
    detachInterrupt(sensorInterrupt2);
 
    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCount) / calibrationFactor;
    flowRate2 = ((1000.0 / (millis() - oldTime)) * pulseCount2) / calibrationFactor;

// ..... doing a lot of additional command and at the end
...
....
...
    pulseCount  = 0;
    pulseCount2 = 0;
     
    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);

this means some pulses are not counted because the time passing by
between
detaching the interrupts at the top and
re-attaching the interrupts at the bottom
is pretty long

it will be more accurate if you code
especially see the different variables pulseCountForCalc and pulseCountForCalc2

    detachInterrupt(sensorInterrupt);
    detachInterrupt(sensorInterrupt2);
   
    pulseCountForCalc = pulseCount;
    pulseCountForCalc2 = pulseCount2;
    pulseCount  = 0;
    pulseCount2 = 0;

    attachInterrupt(sensorInterrupt, pulseCounter, FALLING);
    attachInterrupt(sensorInterrupt2, pulseCounter2, FALLING);   

// AFTER RE-attaching interrupts doing all the calculations and serial prints etc.

    flowRate = ((1000.0 / (millis() - oldTime)) * pulseCountForCalc) / calibrationFactor;
    flowRate2 = ((1000.0 / (millis() - oldTime)) * pulseCountForCalc2) / calibrationFactor;

    oldTime = millis();

    flowMilliLitres = (flowRate / 60) * 1000;
    flowMilliLitres2 = (flowRate2 / 60) * 1000;

I have another idea:
If I rember right you want to fill in a certain amount of volume into bottles.
Another approach would be to count up until the amount of flow-meter-pulses that represent
the volume.you want to fill in and then set a flag-variable in the ISR that indicates "volume reached close valve"
the main code checks for the flag and closes the valve.
or even faster do the closing of the valve immediately in the ISR.

if (CountVolPulses >= FillINPulses) {
      digitalWrite(solenoidValve, LOW);
}

best regards Stefan

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