1

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.

1 Answers1

4

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.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • So when i do all of this dont i need to call to each case in a function? – Noah Levine Oct 02 '19 at 21:25
  • @NoahLevine - No. The whole reason for this construct is to set the process in motion with an initial call to `RunProcess()` (or whatever you choose to call it.) and let the natural process flow occur until the conditions indicating the process is finished are met. Then leave with a status. The only condition now is temperature rising above the set-point, however I think it would be good to add either max_cycles or max_time. Typically environment stress screening systems, use a max_cycles. – ryyker Oct 03 '19 at 11:55
  • what is the SLEEP mode mean? – Noah Levine Oct 03 '19 at 20:57
  • @NoahLevine - Sleep State is a rest. This is a place where the naturally occurring physical things that _need_ to happen _can_ happen. Without a Sleep in the loop in at least one location, the loop is at risk of free wheeling too fast between states, unnecessarily sampling temperature and elapsed time for example. If there are natural latencies in some of the data acquisition functions calls, Seep may not be necessary. I put it in because it is a commonly seen state in constructs such as this. – ryyker Oct 03 '19 at 21:25