Noah Levine
Noah Levine

Reputation: 5

How can I have a conditional statement that performs two tasks? first one and then the other in a loop

So I am trying to code a program in arduino that does a task for 2 minutes and then another task for 5 mins. first one and then the other in a loop until a different condition is met.

Ive been trying to do this with if statements and while loops but im getting lost in the time part i think

//Pneumatic feed system

    double minute = 1000*60;
    double vibTime = 2 * minute;   //2 mins
    //double vibTime = 5000;
    double execTime = millis();
    double waitTime = 5 * minute; //time waits between vibrating 
    //double waitTime = 10000;

void DoPneuFeed() {
    //Serial.print("Delta:");
    //Serial.println(millis()-execTime);

    if(Temp_Data[T_9] < 500)
    {

          if(execTime + vibTime < millis())
          {
              //turn on vibration for 2 mins
              execTime = millis();
              Serial.println("VIBRATING");
          }

          if(execTime + waitTime < millis())
          {
                //turn off vibration for 5 mins
                execTime = millis();
                Serial.println("WAITING");
          }

}

    if(Temp_Data[T_9] > 500)
    {
          relayOff(3);
          relayOff(7);

    }
}

void PneuFeed()
{
  if(execTime + vibTime > millis())
  {
    //air pressure open
    relayOn(3);
    //vibrator on
    relayOn(7); 
  }
  else if(execTime + waitTime > millis())
  {
    relayOff(3);
    relayOff(7);
  }
}

I want to turn on the vibration mode for 2 mins and then turn it off for 5 mins. as long as the Temp_Data(T_9) < 500. if it is greater than 500 it should stay off.

Upvotes: 1

Views: 346

Answers (1)

ryyker
ryyker

Reputation: 23226

Without going into the specifics of your code (since I cannot build it to test.) I only have one quick suggestion:

Instead of using a series of if-then-else (or variations of it) consider using a state machine. Implementations often include use of a switch() inside a while(expression){...} loop. The following is a very simple example of how you might be able to do the steps you need in this construct:
(Note, this is a mix of C and pseudo code for illustration. It is close to compilable , but contains a few undefined items.)

typedef enum {
    START,      
    SET_VIB,
    CHECK_TEMP,
    GET_TIME,
    CLEANUP,
    SLEEP,
    MAX_STATE
}STATE;

enum {
    IN_WORK,
    FAILED,
    SUCCESS
};

enum {// durations in minutes
    MIN_2,
    MIN_5,
    MIN_10,
    MAX_DUR// change/add durations as profile needs
};
const int dur[MAX_DUR]  = {120, 300, 600};

int RunProcess(STATE state);

int main(void)
{
    STATE state = START;

    RunProcess(state);

    return 0;
}

int RunProcess(STATE state)//Add arguments here for temperature, 
{                          //Sleep duration, Cycles, etc. so they are not hardcoded.
    int status;
    time_t elapsed = 0; //s
    BOOL running = TRUE;
    double temp, setpoint;
    int duration;
    time_t someMsValue;


    while(running)
    switch (state) {
        case START:
            //Power to oven
            //Power to vibe
            //initialize state and status variables
            duration = dur[MIN_2];
            state = SLEEP;
            status = IN_WORK;
            break;
        case SET_VIB:
            //test and control vibe
            if(duration == dur[MIN_2]) 
            {
                duration = dur[MIN_5];
                //& turn off vibe
            }
            else
            {
                duration = dur[MIN_2];
                //& turn on vibe
            }
            //init elapsed
            elapsed = 0;           
            status = IN_WORK;            
            state = CHECK_TEMP;
            break;
        case CHECK_TEMP:
            //read temperature
            if(temp < setpoint) 
            {
                state = SLEEP;
                status = IN_WORK;
            }
            else 
            {
                state = CLEANUP;
                status = SUCCESS;            
            }
            break;
        case GET_TIME:
            elapsed = getTime();
            if(elapsed > duration) state = SET_VIB;
            else state = SLEEP;
            status = IN_WORK;            
            break;
        case CLEANUP:
            //turn off heat
            //turn off vibe
            running = FALSE;
            break;
        case SLEEP:
            Sleep(someMsValue);
            state = GET_TIME;
            status = IN_WORK;
            break;
        default:
            // called with incorrect state value
            // error message and exit
            status = FAILED;
            state = CLEANUP;
            break;
    }
    return status;
}

Suggestion for improvement to this illustration: Expand this code to read in a "profile" file. It could include such things as parameter values typical to your process, such as temperature profiles, vibration profiles, number of cycles, etc. With such information, all of the hard-coding used here as illustration could be replaced with run-time configurable parameters, allowing the system to use many different profiles without having to recompile the executable each time.

Another state machine example.

Upvotes: 4

Related Questions