Можно ли красивее написать эту функцию?

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

здраствуйте, вопрос вот в чем, есть следующая функция:

//переменная Clock содержит текущее время аля millis() 
unsigned char Flag_Platform_Start_Position = 0;

void Platform_Start_Position()
{
    static unsigned int Clock_Old = 0;              
    if(!Flag_Platform_Start_Position)              //этот код выполнится только один раз при первом входе в функцию  
    {                                                                           
        Flag_Platform_Start_Position = 1;
        Clock_Old = Clock;                                 //запоминаем значение времени   
    }
    if(Clock - Clock_Old > 200)                       
    {
        TOWEL_DOWN = ON;
    }
    if(Clock - Clock_Old > 300)
    {
 //если вписать Clock_Old = Clock сюда,как обычно пишут, то через некоторое
//время, между вызовами функции, данные времени будут искажены
        TOWEL_DOWN = OFF;
        Flag_Platform_Start_Position = 0;
        if(Flag_Main_Auto_Run)
        {
            State_Platform_Forward = SET;
        }
    }
}

вызывается она раз в 30-40 секунд, то есть сделать как в примере Блинк без delay не выйдет, вот и пошел через лес :) Так то работает, но уверен что есть способы и поизящнее :) немогли бы вы мне помочь?

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

а надо-то чо? штоб чо функция делала?

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

Уточнение : (цикличный вызов функции) ---> Если достигнут результат ---> (выполнение других задач 30 секунд) ---> (новый вызов этой функции) думаю так будет понятнее

b707
Offline
Зарегистрирован: 26.05.2017

semaawp пишет:

вызывается она раз в 30-40 секунд, то есть сделать как в примере Блинк без delay не выйдет

почему не выйдет? максимальный интервал, который можно отработать системным таймером УНО - порядка 49 дней, так что ваши 30 сек - ерунда.

В самом коде, возможно, проблемы в логике - если  Clock - Clock_Old > 300 - сработают оба условия.

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

DetSimen пишет:

а надо-то чо? штоб чо функция делала?

тележка движется прибл 30 секунд, как подъедет к концу, то  запускается эта функция, она опускает башню и дает команду на движение обратно 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

только, если Clock это миллисекунды, тип д.быть long.

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

давайте уточню, у меня что то вроде машины состояний (это еще неточно :) ) 

if(State_Platform_Forward)              {Platform_Forward();}
if(State_Platform_Backward)             {Platform_Backward();}
if(State_Platform_Start_Position)       {Platform_Start_Position();}
if(State_Platform_End_Position)         {Platform_End_Position();}

if(State_Towel_Up)                      {Towel_Up();}
if(State_Towel_Down)                    {Towel_Down();}
if(State_Towel_Up_Step)                 {Towel_Up_Step();}
if(State_Towel_Down_Step)               {Towel_Down_Step();}

еще нужно опрашивать кнопки, датчики и т.д (на них соответствующие состояния)

платформа начала движение:

if(State_Platform_Forward)

через какоето время она доедет до края (около 30-40 сек) и переходит к следующему состоянию:

if(State_Platform_End_Position)

тут она опускает башню и переходит к след состоянию: 

if(State_Platform_Backward)

как доедет до края:

if(State_Platform_Start_Position)

и все сначала

 

вот возьмем состояние 

if(State_Platform_Start_Position) 

(функцию из начала топика) и сделаем аналогию блинка без делей. то есть при совпадении двух велечин времени, мы выполняем чтото, затем сохраняем текущее время и уходим из функции. потом платформа начинает движение и только через  60 секунд мы вернемся к выполнению первой функции, а что мы там сохранили в переменной времени? очень старые данные...Мой ход мысли верный?

 

kalapanga
Offline
Зарегистрирован: 23.10.2016

Речь судя по всему о Clock и Clock_Old? Зачем Вам Clock_Old в каждой функции свой? Объявите его вместе с Clock глобально и обнуляйте при каждой смене состояния системы.

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

kalapanga пишет:

Речь судя по всему о Clock и Clock_Old? Зачем Вам Clock_Old в каждой функции свой? Объявите его вместе с Clock глобально и обнуляйте при каждой смене состояния системы.


Если бы у меня всегда было бы активным только одно из нескольких состояний, тогда я еще более менее представляю картину, ту что вы описываете. Но у меня могут быть активны сразу несколько состояний с разными требуемыми временными задержками. Или я опять что то непонял?

kalapanga
Offline
Зарегистрирован: 23.10.2016

Я бы постарался всё-таки систему к классике свести - в момент времени активно одно состояние. Одновременно активные состояния либо делятся на несколько последовательных состояний, либо одно состояние конечного автомата может само быть конечным автоматом со своими состояниями и внутри него надо тогда оба счетчика (текущее и предыдущее время) свои иметь.

Здесь ЕвгенийП пару раз с примерами эти автоматы разбирал. Поищите темы, может чего пригодится.

b707
Offline
Зарегистрирован: 26.05.2017

semaawp пишет:

 у меня могут быть активны сразу несколько состояний с разными требуемыми временными задержками.

это неправильно. Конечный автомат характеризуется в каждый момент ОДНИМ ЕДИНСТВЕННЫМ состоянием. Если у вас не так - это не конечные автоматы.

Что за несколько состояний у вас реализуются одновремеенно? - если состояния относятся к разным процессам. то для них надо делать отдельные автоматы. Автоматов в программе может быть много, они могут запускаться параллельно, последовательно или вкладываться один в другой. Но то, что у каждого автомата в каждый момент только одно состояние - основополагающий принцип.

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

b707 пишет:

semaawp пишет:

 у меня могут быть активны сразу несколько состояний с разными требуемыми временными задержками.

это неправильно. Конечный автомат характеризуется в каждый момент ОДНИМ ЕДИНСТВЕННЫМ состоянием. Если у вас не так - это не конечные автоматы.

Что за несколько состояний у вас реализуются одновремеенно? - если состояния относятся к разным процессам. то для них надо делать отдельные автоматы. Автоматов в программе может быть много, они могут запускаться параллельно, последовательно или вкладываться один в другой. Но то, что у каждого автомата в каждый момент только одно состояние - основополагающий принцип.

Например у меня могут быть сразу активны состояния платформы и башни, то есть платформа подъехала к концу и ждет 4 секунды, что бы вся механика тормознулась, а в этот момент на промежуток в 2 секунды опускается башня на пару сантиметров вниз, как прошло 4 секунды с момента остановки платформы, она начинает двигаться в обратном направлении. Так же постоянно нужно отслеживать контур безопасности, кнопки, отображение данных на дисплее и тд

b707
Offline
Зарегистрирован: 26.05.2017

semaawp пишет:
Например у меня могут быть сразу активны состояния платформы и башни, то есть платформа подъехала к концу и ждет 4 секунды, что бы вся механика тормознулась, а в этот момент на промежуток в 2 секунды опускается башня на пару сантиметров вниз, как прошло 4 секунды с момента остановки платформы, она начинает двигаться в обратном направлении.

ну вы уже наверно сами догадались - вам нужно отдельный автомат для платформы и отдельный для башни.  Но автоматы должны быть не полностью независимы. а обмениваться данными. Например, когда платформа подъехала к концу - она выдает башне сигнал. что той пора опускаться - и продолжает выполнять свои стадии. А башня выполняет свои.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если у вас объект у которого есть куча параметров-состояний ,то разбейте на суб-объекты так что бы у каждого был только один параметр состояния. Параметр- состояние это переменая у которой может быть одно из состояний 0,1,2 и тд. Разумеется лучше отвести каждый объект - это одна независимая подзадача .И наконец организовать псевдомногозадачную систему.

ПС:https://tproger.ru/translations/finite-state-machines-theory-and-implementation/

semaawp
semaawp аватар
Offline
Зарегистрирован: 29.05.2017

Всем спасибо за подсказки, буду изучать автоматы глубже)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Давно уже делал что-то подобное для упрощения программирования автоматос состояний. Посмотрите https://github.com/dimanus/ARHAT_H там есть файлики  tsc.h,tsc.c в них реализация чего-то подобного. Сборка рабочая под версию 1.6.4, далее не обновлялась. Можете самостоятельно для себя приспособить всё что понравится. Описание есть, много комментариев по тексту, есть примеры.

Logik
Offline
Зарегистрирован: 05.08.2014

qwone пишет:

Параметр- состояние это переменая у которой может быть одно из состояний 0,1,2 и тд.

Ниче подобного. Может быть и набор переменных с их комбинаторикой, как захочится. Подумайте сам: одна переменная инт (2 байта) или две переменные по байту. Какая разница если одно приводится к другому легким движением руки.

qwone пишет:

Разумеется лучше отвести каждый объект - это одна независимая подзадача

Это может быть разумным. От задачи зависит как её разбивать. Или не разбивать.