Как получить условное утверждение, которое выполняет две задачи? сначала один, а затем другой в цикле - PullRequest
1 голос
/ 02 октября 2019

Итак, я пытаюсь закодировать программу на arduino, которая выполняет задачу в течение 2 минут, а затем еще одну задачу в течение 5 минут. сначала одно, а затем другое в цикле, пока не будет выполнено другое условие.

Я пытался сделать это с помощью операторов if и while, но я теряюсь во временной части, я думаю

//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);
  }
}

Я хочу включить режим вибрации на 2 минуты, а затем выключить его на 5 минут. до тех пор, пока Temp_Data (T_9) <500. если оно больше 500, оно должно оставаться выключенным. </p>

1 Ответ

4 голосов
/ 02 октября 2019

Не вдаваясь в специфику вашего кода (поскольку я не могу построить его для тестирования.) У меня есть только одно быстрое предложение:

Вместо использования серии if-then-else (или ее вариантов) рассмотримиспользуя конечный автомат. Реализации часто включают использование switch() внутри цикла while(expression){...}. Ниже приведен очень простой пример того, как вы можете выполнить шаги, необходимые для этой конструкции:
( Примечание , это сочетание C и псевдокодадля иллюстрации. Он близок к компилируемому, но содержит несколько неопределенных элементов.)

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;
}

Предложение по улучшению этой иллюстрации: Разверните этот код, чтобы прочитать его в файле профиля,Он может включать такие вещи, как значения параметров, типичные для вашего процесса, такие как профили температуры, профили вибрации, количество циклов и т. Д. С такой информацией все жесткое кодирование, используемое здесь в качестве иллюстрации, может быть заменено настраиваемыми параметрами времени выполнения. , позволяя системе использовать много разных профилей без необходимости каждый раз перекомпилировать исполняемый файл.

Другой пример конечного автомата .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...