Не вдаваясь в специфику вашего кода (поскольку я не могу построить его для тестирования.) У меня есть только одно быстрое предложение:
Вместо использования серии 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;
}
Предложение по улучшению этой иллюстрации: Разверните этот код, чтобы прочитать его в файле профиля,Он может включать такие вещи, как значения параметров, типичные для вашего процесса, такие как профили температуры, профили вибрации, количество циклов и т. Д. С такой информацией все жесткое кодирование, используемое здесь в качестве иллюстрации, может быть заменено настраиваемыми параметрами времени выполнения. , позволяя системе использовать много разных профилей без необходимости каждый раз перекомпилировать исполняемый файл.
Другой пример конечного автомата .