stop motor after 5 sec

i working in the project "automatic bottle filling and capping machine using arduino ".
This system uses ultrasonic sensor to measure the water level in the tank and turn on / off two pumps accordingly from other two tanks.then the mixer will turned on if water Tank Full for 5 sec but the motor keeps on spinning without stopping after 5 seconds.Can anyone help? Thanks in advance!

#define trig_pin 22 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define echo_pin 23 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define pump1 24  // define pin 24 for pump1
#define pump2 25  // define pin 25 for pump2
#define mixer 26  //define pin 26 for Mixer

//ultrasonic
int percent=0, percentage=0 , distance=0, tankHeight=20;
float waterLevel;
long duration;

//mixer
bool flag=false;
unsigned long startTime=0;
int motorState=0;
unsigned long interval=5000;
void setup() 
{
  Serial.begin(9600);
  pinMode(trig_pin,OUTPUT); 
  pinMode(echo_pin,INPUT);
  pinMode(pump1,OUTPUT);
  pinMode(pump2,OUTPUT);
  pinMode(mixer,OUTPUT);
}

void loop()
{
 percentage=getDistance();
 percent1();   
}

int getDistance()
{
 // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 digitalWrite(trig_pin,LOW);
 delayMicroseconds(2);
 digitalWrite(trig_pin,HIGH);
 delayMicroseconds(10);
 digitalWrite(trig_pin,LOW);
 // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  duration=pulseIn(echo_pin,HIGH);
  for(int x=0; x<5; x++)
  {
   distance+=duration/58;
   delay(50);
  }
  distance=distance/5;
  waterLevel=tankHeight-distance;
  
  percent=((waterLevel/tankHeight)*100)+8;//8% to avoid over flow and prevent sensor from water
  if(percent>100) percent=100;
  if(percent<0) percent=0;
  return percent;
  distance =0;
}
void percent1()
{
 if (percentage >= 80 && flag == false)
 {
  Serial.print("water Tank Full");
  digitalWrite(pump1, LOW);
  digitalWrite(pump2, LOW);
  flag = true;
  startTime = millis();
  motorState = 1;
 }else
 {
  flag = false;
 }
 if (motorState == 1)
 {
  digitalWrite(pump1, LOW);
  digitalWrite(pump2, LOW);
  if (millis() - startTime < interval)
  {
   digitalWrite(mixer, HIGH);
   Serial.println("Mixer Turned ON");
  }else
  {
   digitalWrite(mixer, LOW);
   Serial.println("Mixer Turned OFF");
   motorState = 0;
  }
 }//motor state
 else if (percentage < 20)
 {
  Serial.println("Low Water Level");
  digitalWrite(pump1, HIGH);
  digitalWrite(pump2, HIGH);
 }
 else if (percentage >= 20 && percentage < 80)
 {
  Serial.println("pump kept ON");
  digitalWrite(pump1, HIGH);
  digitalWrite(pump2, HIGH);
 }
}

Your logic is a bit convoluted. inside percent1() you test

  if (percentage >= 80 && flag == false)
  {
    Serial.print("water Tank Full");
    digitalWrite(pump1, LOW);
    digitalWrite(pump2, LOW);
    flag = true;
    startTime = millis();
    motorState = 1;
  } else
  {
    flag = false;
  }

which sets flag to true and turns off the pump the first time the tank is full. The next time through this loop, flag is false so the if() is false so the else clause gets executed which sets flag back to false. The next time through the loop, the if() is now true which resets the startTime so you never get to 5 seconds beyond startTime.

I think you are over complicated this.

  1. Run the pumps until the tank is full
  2. turn off the tanks
  3. run the mixer for 5 seconds

Just do them as a series of events.

Also, this code is silly

  duration = pulseIn(echo_pin, HIGH);
  for (int x = 0; x < 5; x++)
  {
    distance += duration / 58;
    delay(50);
  }
  distance = distance / 5;

since you are not averaging 5 distance readings. You take the same number add it 5 times and then divide by 5.

You have the code for checking the levels all mixed up with the code for operating the pumps. I suggest you move the pump code to its own function - perhaps called operatePump() and in the function you call percent1() I suggest you just set the variable motorState to the appropriate value.

I was going to post some suggested code but I realised I don't sufficiently understand all the pump requirements to make a sensible suggestion. Perhaps you can post an explanation.

...R

Maybe something like this

#define trig_pin 22 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define echo_pin 23 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define pump1 24  // define pin 24 for pump1
#define pump2 25  // define pin 25 for pump2
#define mixer 26  //define pin 26 for Mixer

//ultrasonic
const int tankHeight = 20;

//mixer
unsigned long startTime = 0;
int motorState = 0;
const unsigned long interval = 5000;


void setup()
{
  Serial.begin(9600);
  pinMode(trig_pin, OUTPUT);
  pinMode(echo_pin, INPUT);
  pinMode(pump1, OUTPUT);
  pinMode(pump2, OUTPUT);
  pinMode(mixer, OUTPUT);
}


void loop()
{
  int percent = getFillPercent();
  checkLevel(percent);
}

int getFillPercent()
{
  long distance = 0;
  int percent = 0;
  float waterLevel = 0;

  // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
  // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
  digitalWrite(trig_pin, LOW);
  delayMicroseconds(2);
  digitalWrite(trig_pin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trig_pin, LOW);
  // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
  long duration = pulseIn(echo_pin, HIGH);
  for (int x = 0; x < 5; x++)
  {
    distance += duration / 58;
    delay(50);
  }
  distance = distance / 5;
  waterLevel = tankHeight - distance;

  percent = ((waterLevel / tankHeight) * 100) + 8; //8% to avoid over flow and prevent sensor from water
  if (percent > 100) percent = 100;
  if (percent < 0) percent = 0;
  return percent;
}


void checkLevel(int percentage)
{
  if (percentage >= 80)
  {
    Serial.print("water Tank Full");
    digitalWrite(pump1, LOW);
    digitalWrite(pump2, LOW);
    if (startTime == 0  )
    {
      startTime = millis();
      digitalWrite(mixer, HIGH);
      Serial.println("Mixer Turned ON");
    }
  }
  else if (percentage < 20)
  {
    Serial.println("Low Water Level");
    digitalWrite(pump1, HIGH);
    digitalWrite(pump2, HIGH);
  }
  else if (percentage >= 20 && percentage < 80)
  {
    Serial.println("pump kept ON");
    digitalWrite(pump1, HIGH);
    digitalWrite(pump2, HIGH);
  }

  if (startTime && millis() - startTime >= interval)
  {
    digitalWrite(mixer, LOW);
    Serial.println("Mixer Turned OFF");
    startTime = 0;
  }
}

The main function of the two pumps is to transfer the liquid from the tank to the third tank containing the mixer as long as the third tank is not full. Once the fluid level reaches the required level (high level), the mixer turns on for five seconds and then turns off again.

Now, I want to start the engine for only 5 seconds and turn it off, even if the ratio is 80% (high level), what happens is that the motor runs for five seconds and turns off and on again

How can I modify the code to run the motor for 5 sec and then turns off completely?
Many thanks in advance!

I try another code but the same problem the motor keeps on spinning without stopping after 5 seconds. I want to start the motor for only 5 seconds and turn it off, even if the ratio is 80% (high level).
Can anyone help? Thanks in advance!

#define trig_pin 22 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define echo_pin 23 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define pump1 24  // define pin 24 for pump1
#define pump2 25  // define pin 25 for pump2
#define mixer 26  //define pin 26 for Mixer

//ultrasonic
const int tankHeight = 20;

//mixer
bool lastTrip, tripped;
unsigned long startTime=0;
int motorState=0;
unsigned long interval=5000;
void setup() 
{
  Serial.begin(9600);
  pinMode(trig_pin,OUTPUT); 
  pinMode(echo_pin,INPUT);
  pinMode(pump1,OUTPUT);
  pinMode(pump2,OUTPUT);
  pinMode(mixer,OUTPUT);
}

void loop()
{
 int percent = getFillPercent();
 checkLevel(percent);   
}

int getFillPercent()
{
 long distance = 0;
 int percent = 0;
 float waterLevel = 0;
 
 // The sensor is triggered by a HIGH pulse of 10 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 digitalWrite(trig_pin,LOW);
 delayMicroseconds(2);
 digitalWrite(trig_pin,HIGH);
 delayMicroseconds(10);
 digitalWrite(trig_pin,LOW);
 // Read the signal from the sensor: a HIGH pulse whose
  // duration is the time (in microseconds) from the sending
  // of the ping to the reception of its echo off of an object.
 long duration=pulseIn(echo_pin,HIGH);
  for(int x=0; x<5; x++)
  {
   distance+=duration/58;
   delay(50);
  }
  distance=distance/5;
  waterLevel=tankHeight-distance;
  
  percent=((waterLevel/tankHeight)*100)+8;//8% to avoid over flow and prevent sensor from water
  if(percent>100) percent=100;
  if(percent<0) percent=0;
  return percent;
  distance =0;
}
void checkLevel(int percentage)
{
 tripped =(percentage >= 80 ? 1:0);
 if(tripped)
 {
  Serial.print("water Tank Full");
  digitalWrite(pump1, LOW);
  digitalWrite(pump2, LOW);
  if(tripped !=lastTrip)
  {
   startTime = millis();
   motorState = 1;
  }
 }
 lastTrip=tripped;
 
 if (motorState == 1)
 {
  digitalWrite(pump1, LOW);
  digitalWrite(pump2, LOW);
  if (millis() - startTime < interval)
  {
   digitalWrite(mixer, HIGH);
   Serial.println("Mixer Turned ON");
  }else
  {
   digitalWrite(mixer, LOW);
   Serial.println("Mixer Turned OFF");
   motorState = 0;
  }
 }//motor state
 else if (percentage < 20)
 {
  Serial.println("Low Water Level");
  digitalWrite(pump1, HIGH);
  digitalWrite(pump2, HIGH);
 }
 else if (percentage >= 20 && percentage < 80)
 {
  Serial.println("pump kept ON");
  digitalWrite(pump1, HIGH);
  digitalWrite(pump2, HIGH);
 }
}

Seems fine. Since I don't have your hardware, I tested it by faking the percentage as gradually increasing to 85 and it works as I would expect.

What does the Serial output look like?

the code for checking the levels has no problems but the motor is running continuously after reaches to the high level(85%) but I want it to work for five seconds and it stops completely because there is another completion of the project there is a conveyor that pushes empty bottles towards the filling head. The filling head is responsible for filling of bottles with water.

It prints on serial “Mixer Turned ON” after reaches to the high level.

Grab the serial output including the fill and ten seconds of mixing and post it.