Making somthing run for X amount of time

Hello guys!

We are working on a project where two motors will run (either simultaneous or after one another) for X seconds once a button is held. So when you press the button, the motors will run for X sec, then stop, and be ready to go for another X once the button is released and pressed again. The motors must also stop if the button is released prematurely, before X sec.

The Project is for a powder/water dispenser

What would be the best way to approach this?
The code here is where we are at right now…

Thank you <3

void setup() {
  // put your setup code here, to run once:
pinMode(4,OUTPUT);
pinMode(8,OUTPUT);
pinMode(2,INPUT);
Serial.begin(115200);
if(digitalRead(2))
{
  for(int i=0;i<1000;i++)
    {
      digitalWrite(4,HIGH);
      delay(1);
    }
    digitalWrite(4,LOW);
  for(int i=0;i<1000;i++)
    {
      digitalWrite(8,HIGH);
      delay(1);
    }
    digitalWrite(8,LOW);
}
else
{
  digitalWrite(4,LOW);
  digitalWrite(8,LOW);
}

}
int i;
void loop() {
  // put your main code here, to run repeatedly:
if(digitalRead(2))
{
  for(int i=0;i<1000;i++)
    {
      digitalWrite(4,HIGH);
      delay(1);
    }
    digitalWrite(4,LOW);
  for(int i=0;i<1000;i++)
    {
      digitalWrite(8,HIGH);
      delay(1);
    }
    digitalWrite(8,LOW);
}
else
{
  digitalWrite(4,LOW);
  digitalWrite(8,LOW);
}

}

OK, so have you read this tutorial?

I could of course write the code for you but - hey! You should be able to. :grin:

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

We would be forever gratefull good sir if you did write the code and shared it with us here!

We are looking at the tutorial right now and trying to make something out of it, but we struggle...

Then try my take on the subject
State Machine

A state machine approach might look something like this:

/*
 * We are working on a project where two motors will run (either simultaneous or 
 * after one another) for X seconds once a button is held. So when you press the 
 * button, the motors will run for X sec, then stop, and be ready to go for another 
 * X once the button is released and pressed again. The motors must also stop if 
 * the button is released prematurely, before X sec.
 */

const uint32_t K_MAXIMUM_DURATION = 7000ul;         //mS    7-sec   'X' as described in the above comment
const uint32_t K_PAUSE_DURATION = 2000ul;           //mS    2-sec   pause after motors stop before allowing them to start again
const uint32_t K_BTN_READ_TIME =  20ul;             //mS    20mS    button read period

const uint8_t pinButton = 2;                        //button input (wire so press grounds button; no-press is open circuit
const uint8_t pinMotor1 = 4;                        //motor 1
const uint8_t pinMotor2 = 8;                        //motor 2

const uint8_t pinLED = LED_BUILTIN;                 //"ready" light

uint8_t
    lastButton;

//button press return values
typedef enum
{
    NO_BUTTON=0,        //no button state change
    BTN_PRESSED,        //button went from not-pressed to pressed
    BTN_RELEASED        //button went from pressed to not-pressed
    
}eButtonStates_t;

//motor control states
typedef enum
{
    ST_INIT=0,          //initialize motors to "off"
    ST_IDLE,            //waiting for button press
    ST_RUNNING,         //motors running; waiting for button release or timeout
    ST_PAUSE            //after-run pause before re-enabling
    
}eMotorStates_t;

void setup( void ) 
{  
    Serial.begin(115200);           //debug/information messages
    
    pinMode( pinMotor1, OUTPUT );
    pinMode( pinMotor2, OUTPUT );
    pinMode( pinLED, OUTPUT );
    digitalWrite( pinLED, HIGH );   //turn on LED indicating "ready"
    //
    pinMode( pinButton, INPUT_PULLUP );    
    lastButton = digitalRead( pinButton );        

}//setup

void loop( void )
{
    MotorControl();

}//loop

uint8_t chkButton( void )
{
    static uint32_t
        timeButton = 0ul;
    uint32_t
        timeNow;

    //read the button at periodic intervals (once every K_BTN_READ_TIME milliseconds)
    timeNow = millis();
    if( (timeNow - timeButton) < K_BTN_READ_TIME )
        return NO_BUTTON;   //if not time for a read just return "no button"

    timeButton = timeNow;
        
    uint8_t nowButton = digitalRead( pinButton );   //read the state of the button now
    //different than last read?
    if( nowButton != lastButton )
    {
        //this read wasn't the same as the last
        lastButton = nowButton;        
        if( nowButton == LOW )
        {
            //if LOW now the button has been pressed
            Serial.println( "Button pressed" );
            return BTN_PRESSED;
            
        }//if
        else
        {
            //if HIGH now button has been released
            Serial.println( "Button released" );
            return BTN_RELEASED;
            
        }//else
        
    }//if

    //if we get here, button has not changed state so return "no button"
    return NO_BUTTON;
    
}//chkButton

void MotorControl( void )
{
    static uint8_t
        stateMotor = ST_INIT;
    static uint32_t
        timeMotor;
    uint32_t timeNow;
    uint8_t
        btnCond;

    timeNow = millis();     //get current millis count
    btnCond = chkButton();  //and check the button
    
    switch( stateMotor )
    {
        case    ST_INIT:
            //initial state; turn off the motors and proceed to idle
            digitalWrite( pinMotor1, LOW );
            digitalWrite( pinMotor2, LOW );
            stateMotor = ST_IDLE;
            
        break;
        
        case    ST_IDLE:
            if( btnCond == BTN_PRESSED )
            {
                //if we detect button pressed, start motors
                digitalWrite( pinMotor1, HIGH );
                digitalWrite( pinMotor2, HIGH );
                //turn OFF the LED to indicate system is busy
                digitalWrite( pinLED, LOW );
                //save this time so we can measure the run duration
                timeMotor = timeNow;

                Serial.println( "Motors running" );
                stateMotor = ST_RUNNING;
                
            }//if
            
        break;

        case    ST_RUNNING:
            if( (btnCond == BTN_RELEASED) || ((timeNow - timeMotor) >= K_MAXIMUM_DURATION) )
            {
                //button was released or we saw a time-out; turn off the motors
                digitalWrite( pinMotor1, LOW );
                digitalWrite( pinMotor2, LOW );
                //save the time so we can measure the pause duration
                timeMotor = timeNow;

                Serial.println( "Motors halted" );
                stateMotor = ST_PAUSE;
                
            }//if
            
        break;

        case    ST_PAUSE:
            //pause after running the motors
            if( timeNow - timeMotor >= K_PAUSE_DURATION )
            {
                //when pause is complete, turn on the LED indicating
                //ready for the another dispense
                Serial.println( "Ready" );
                digitalWrite( pinLED, HIGH );
                
                //and return to IDLE state                
                stateMotor = ST_IDLE;
                
            }//if
            
        break;
        
    }//switch
    
}//MotorControl

(compiles, lightly tested)

Absolute legend dude! Mad respect!