Страница 3 из 4
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 10:34:26
BOB51
Была бы схема устройства с "хотелками" - можно было бы под адуринку приспособить.
Так сказать еще одна тренировка мозга (и добавка учебного примера в КОТУИНКЕ)...

Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 10:36:55
Dimon456
Demiurg, да, я балуюсь, вот проект под winavr + протеус
Пытаюсь понят что такое "конечный автомат"?:
Спойлер
-Если вот это Код: Выделить всё
proc_device ();
proc_motor ();
kbd_drv ();
proc_sensors ();
Process_Events ();
развернуть, то получится большая "простыня", как примерно у ТС.
-У меня во время остановки двигателя запускается таймер ожидания (5 секунд на остановку двигателя) тут же идет запрет на реагирование кнопок управления влево-вправо и датчика смены направления.
Во время этого запрета продолжаю сканировать один единственный датчик (датчик или кнопка СТОП) Код: Выделить всё
case PROC_DEVICE_IDLE:
if (check_sensor_1_on ())
{
direction = DIRECTION_STOP;
}
отменяющий следующую команду. Это "конечный автомат"? Или что такое "конечный автомат"?
Еще вопрос, у вас видимо есть код управление LCD 16*2, покажите начальную инициализация, всю не надо кусочек, мне интересно чем вы delay заменяете?
У меня допустим вот так идет Код: Выделить всё
LCDI2C_write4bits(0x03 << 4);
DelayMC(4500); // wait min 4.1ms
LCDI2C_write4bits(0x03 << 4);
DelayMC(4500); // wait min 4.1ms
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 11:06:51
ARV
конечный автомат - это вывернутый на изнанку обычный алгоритм

в обычном алгоритме мы рисуем квадратики/ромбики на действия и стрелками показываем очередность действий, а в конечном автомате мы кружочками рисуем состояния, а стрелочками - условия переходов между ними. теоретически доказано, что одно из другого может быть получено, т.е. фактически это лишь способ описания поведения программы. ну и потом, согласно этому описанию, построение этой программы.
иначе говоря, конечный автомат - это куча вложенных switch, в то время как "традиционная" программа - куча вложенных функций. если в самых общих чертах, конечно.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 11:13:44
NStorm
[uquote="Dimon456",url="/forum/viewtopic.php?p=3875230#p3875230"]Пытаюсь понят что такое "конечный автомат"?:[/uquote]
Грубо говоря (упрощение, применительно к МК) - некие состояния и переходы между ними. В реальности еще условия перехода (или события). Графически можно в виде графов представлять:

Вот простейший автомат с 2 состояниями. Ну или 3мя, если начальную черную точку приять за состояние некоей "инициализации".
В простейшем виде на Си реализуется через switch-case. Пример:
http://digitrode.ru/articles/90-konechn ... -na-c.html
Но при большом кол-ве состояний становится громоздко и неудобно. Далее удобнее переходить к табличной или структурной реализации. Опять же пример:
https://habr.com/ru/post/241941/
Тут удобно использовать "магию" Си того, что указатели на функции можно сохранять в массивах. Т.е. создать массив (таблицу) всех переходов в зависимости от событий. При этом сам переход делается функцией (которая потом может вернуть следующее состояние после перехода).
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 12:07:13
Demiurg
[uquote="ARV",url="/forum/viewtopic.php?p=3875252#p3875252"]...[/uquote]
Опять 25. Конечный автомат - это и есть алгоритм. Не вывернутый, не завернутый. Где-то в недрах инета много лет назад прозвучали следующие слова: те кто пользуются RTOS, диспетчерами - это те, кто не освоил конечные автоматы.
Автоматное программирование, конечно же, не панацея. Не палочка выручалочка на все случаи жизни. Но! Любая программа, по сути и есть конечный автомат. Только состояниями служат другие сущности. В случае флагов, семафоров, условий - кол-во состояний равно разрядности кол-ва бинарных сущностей. Из-за этого есть проблема - запрещенные, неучтенные состояния. В случае конечного автомата этого нет. Количество состояний конечно и заранее предопределено.
И это не куча свитчей. Мало состояний - switch-case технология. Много состояний - индексный переход. Можно и if-ами вместо switch обойтись. Вот только код станет совсем нечитабелен...
Главные преимущества автоматного программирования - сокращения затрат на создание проектов в разы. И оно идеально подходит для блоков управления чего бы то ни было. Станки, оборудование, автоматика.
Добавлено after 20 minutes 41 second:
[uquote="NStorm",url="/forum/viewtopic.php?p=3875254#p3875254"]...[/uquote]
Много лет назад, на аасемблере был подобный пример. Берем за аксиому: чем больше данных, структур - тем меньше программа. И наоборот. В конечном итоге, в идеале, программа превращается в интерпретатор таблицы.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 12:13:10
BOB51
КТО КАК ХОЧЕТ ТАК И ......
Главное, чтоб умело, да результат был работоспособным!

Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 12:36:46
Demiurg
[uquote="Dimon456",url="/forum/viewtopic.php?p=3875230#p3875230"]...[/uquote]
Замечание первое. В proc_device у вас в самом начале стоит:
Код: Выделить всё
u08 event = Get_Event (EV_ID_KEY_PRESSED);
У автомата могут быть состояния, где это событие нахер не нужно. И если у события категория USER_EVENT, то событие сбрасывается. И когда оно действительно потребуется, оно сброшено. Также служба событий реализовано по следующему сценарию (из цикла статей Татарчевского), Событие живет текущую и следующую итерацию. По его идеологии, если не прочитали в следующей итерации, значит оно нахер не нужно. Я с этим и согласился и нет. Поэтому ввел категории сообщений. Живущее одну следующую итерацию и пока его не прочитают и не сбросят.
Поэтому, читайте события только в тех состояниях, где это действительно требуется. В дальнейшем озаботьтесь очисткой сообщений. Всех, или часть. Возможно, для некоторых автоматов потребуются свои наборы сообщений. Анализируйте свои проекты. Больше по этому поводу сказать нечего.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 13:26:22
ARV
NStorm писал(а):Тут удобно использовать "магию" Си того, что указатели на функции можно сохранять в массивах.
более интересным представляется способ, когда адрес функции и есть идентификатор состояния, т.е. нет нужды ни в массивах, ни в switch-ах:
Код: Выделить всё
void (*current)(void);
void STATE_1(void);
void STATE_2(void);
void STATE_3(void);
void STATE_1(void){
current = STATE_2;
}
void STATE_2(void){
current = STATE_3;
}
void STATE_3(void){
current = STATE_1;
}
int main(void){
current = STATE_1;
while(1){
current();
}
}
в самом обобщенном виде.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 14:00:53
NStorm
ARV, не всегда. Добавьте события и переходы от одного состояния к нескольким в зависимости от события - и это станет простыней из функций. А табличка в одном месте хотя бы и в табличке легко меняются связи.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 14:05:45
Demiurg
Структурирован е данных целесообразно, когда есть что обобщать, структурировать. Таблица отличный метод. Опять же, когда есть что структурировать. Но это и жёсткая логика. Поэтому, анализ, анализ и ещё раз анализ.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 15:10:26
ARV
[uquote="NStorm",url="/forum/viewtopic.php?p=3875362#p3875362"]ARV, не всегда. Добавьте события и переходы от одного состояния к нескольким в зависимости от события - и это станет простыней из функций. А табличка в одном месте хотя бы и в табличке легко меняются связи.[/uquote]
табличка - это хорошо, кто ж спорит. однако, если в КА слишком много состояний - это уже плохо для восприятия, ничем от макаронного кода не отличается. поэтому компромисс: малое количество "основных" состояний", а все остальные мелкие - в качестве внутренних функций, не являющихся частью главных состояний. Тогда и переходов немного, и, главное, всегда четко видна структура этих переходов: анализ какого бы состояния-функции мы не начали, всегда по структуре этой функции виден граф переходов по состояниям КА. при табличном варианте граф переходов очевиден только в том месте, где сама таблица.
кстати, подход КА вообще не приемлем при программировании а-ля Делфи: в этой парадигме вообще нет в принципе понятия состояние, есть только сообщения. при этом вполне логично и достаточно красиво реализуется и многопоточность. так что КА - далеко не панацея, хотя любая программа есть вариант КА.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 15:25:22
Demiurg
ARV, без обид. Мы давно уже, кажется, остались при своих. Не любите, ваше дело. Если влезаете в эту тему, исходите не из своих предпочтений, а приводите железобетонные факты. Моё мнение, вы их ни асилили, или просто... привычка, и что еще хуже, стиль мышления. Вы много слов говорите, а все сводится к "красивости". Красиво, но не эффективно. И это грустно. Все.
Много состояний? При традиционном программировании программу хер осилишь. Автоматное программирование хорошо тем, что проект раздроблен. На состояния. Разделяй и властвуй. Кубики, из которых возводишь здание.
Мои железобетонные факты: сокращение накладных расходов на создание проекта. Как минимум, временные затраты сокращаются в разы. Псевдопараллельность процессов. Мы можем запустить кучу параллельных процессов. Опрос кнопок, датчиков, вывод информации на дисплей, основной алгоритм проекта. И многое многое другое. Без использования диспетчеров, RTOS, и нечитабельных простыней и макаронины. Потому что, роль диспетчеров и RTOS выполняют конечные автоматы.
И самое главное - понятная логика работы любого устройства, написанного автоматным программированием. Подчеркиваю: конечные автоматы - кол-во состояний конечно и прогнозируемо. Нет скрытых и запрещенных состояний, которые хер отловишь БЫСТРО.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 15:37:06
ARV
Demiurg писал(а):Красиво, но не эффективно.
не просто красиво, а удобно. основное назначение программы на ЯВУ - быть понятной человеку. макаронный код плох не тем, что плохо работает (как правило, наоборот), а тем, что нечитаем (о сопровождении кода я вообще молчу - мы ж не профессионалы, а любители, какое там сопровождение?!). КА с огромным количеством состояний плох по той же причине. Чистый КА - это программа на ассемблере, машинные инструкции: каждое следующее состояние определяется текущим состоянием, кодом текущей операции и текущим состоянием данных, причем определяется однозначно - классика! но это очень неудобно, потому от машинных кодов с диким количеством состояний мы уходим в ЯВУ, где необходимости в них нет. остается лишь найти золотую середину между удобством чтения и простотой (еще вопрос) парадигмы КА.
Demiurg писал(а):Автоматное программирование хорошо тем, что проект раздроблен. На состояния. Разделяй и властвуй. Кубики, из которых возводишь здание.
традиционное программирование (раньше я называл это функциональным, но теперь смысл этого термина поменялся) то же самое: независимые функции-кубики, разделяй и властвуй. парадигма КА не в этом.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 15:41:24
Demiurg
"Красиво, эффектно, но не эффективно и красивые типа умные слова". Закрыли тему. Факты или идите окучивайте свои темы.
Поясню, коротко и ясно. Все люди разные. Мышление разное. Не вкуриваете тему, так и быть, работайте, как привыкли, как позволяет вам ваше мышление.
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 15:48:33
NStorm
традиционное программирование (раньше я называл это функциональным, но теперь смысл этого термина поменялся)
Наверное вы имеете в виду
процедурное программирование.
Кстати вот еще полезная ссылка по КА для ТС:
https://ru.wikipedia.org/wiki/%D0%90%D0 ... 0%B8%D0%B5
Re: Помогите пожалуйста с кодом С#
Добавлено: Ср авг 05, 2020 20:57:36
BOB51
Ну ужшш...
Никто не мешает ту "простыню из кучи прикладных функций" запрятать в библиотечку для "удобочитаемости" основного файла проекта...

Да и особой разницы между позициями от
ARV и
Demiurg при практическом программировании в большинстве случаев только для ГУРМАНОВ можно усмотреть.
Чаще смесь разных методик и приемов используется.

Re: Помогите пожалуйста с кодом С#
Добавлено: Чт авг 06, 2020 19:35:44
Dimon456
Господа програмисты, вопрос по способу 2.
[uquote="Demiurg",url="/forum/viewtopic.php?p=3874831#p3874831"]Способ 2. Индексный переход. Создается таблица с указателями на функции-обработчики состояний. Индексом служит переменная-состояние.
Спойлер
Код: Выделить всё
_proc_device.h
//************************************************************************
//************************ Главный автомат *******************************
//************************************************************************
//==================
STATE (PROC_DEVICE_INIT, proc_device_init)
STATE (PROC_DEVICE_WEIGHT_MODE, proc_device_weight_mode)
STATE (PROC_DEVICE_DOSER_IDLE_MODE, proc_device_doser_idle_mode)
STATE (PROC_DEVICE_DOSER_MODE, proc_device_doser_mode)
STATE (PROC_DEVICE_IDLE, proc_device_idle)
STATE (PROC_DEVICE_EMERG_MODE, proc_device_emerg_mode)
//==================
//==================
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "_proc_device.h"
#undef STATE
PROC_DEVICE_STATES,
} proc_device_t;
//----------
void proc_device (void);
//----------
void proc_device_init (void);
//----------
void proc_device_weight_mode_init (void);
void proc_device_weight_mode (void);
//----------
void proc_device_doser_idle_mode_init (void);
void proc_device_doser_idle_mode (void);
//----------
void proc_device_doser_mode_init (void);
void rst_proc_device_doser_mode (void);
void proc_device_doser_mode (void);
//----------
void proc_device_idle_init (void);
void proc_device_idle (void);
//----------
void set_proc_device_emerg_mode (u08 err_id);
void proc_device_emerg_mode (void);
//==================
//==================
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "_proc_device.h"
#undef STATE
};
//----------
static proc_device_t _proc_device;
static u08 _proc_device_slave;
//----------
void proc_device (void)
{
// proc_meter (); // Важно!!! Инициализация!
proc_fsm_func (proc_device_func, _proc_device);
}
//==================
[/uquote]Компилятор winavr avr-gcc (GCC) 9.2.0 у меня не переварил в таком виде.
Переварил только так: вынес в отдельный файл func.h (ни должно быть ни чего лишнего в этом файле, иначе приводит к ошибке)
Спойлер
Код: Выделить всё
#ifndef FUNC_H
#define FUNC_H
//==================
STATE (PROC_DEVICE_INIT, proc_device_init)
STATE (PROC_DEVICE_WAIT_SWITCH_MODE, proc_device_wait_switch_mode)
//STATE (PROC_DEVICE_MANUAL, proc_device_manual_mode)
//STATE (PROC_DEVICE_AUTOMAT, proc_device_automat_mode)
//STATE (PROC_DEVICE_EMERG_MODE, proc_device_emerg_mode)
//==================
#endif
в файле _proc_device.h оставил это
Спойлер
Код: Выделить всё
#ifndef PROC_DEVICE_H
#define PROC_DEVICE_H
#define __flash const
//==================
typedef void (*FUNC)(void);
//==================
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "func.h"
#undef STATE
PROC_DEVICE_STATES,
}proc_device_t;
void proc_device (void);
void proc_device_init (void);
void proc_device_wait_switch_mode (void) ;
void proc_fsm_func (FUNC __flash *ptr_func, unsigned char s);
__flash FUNC proc_device_func [PROC_DEVICE_STATES] ;
#endif
в основном файле _proc_device.с это
Спойлер
Код: Выделить всё
#include "_proc_device.h"
static proc_device_t _proc_device;
void proc_device (void)
{
_proc_device = PROC_DEVICE_INIT;
proc_fsm_func (proc_device_func, _proc_device);
}
void proc_device_init (void) {
PORTC = (1 << 0);
}
void proc_device_wait_switch_mode (void) {
PORTC = (1 << 1);
}
void proc_fsm_func (FUNC __flash *ptr_func, unsigned char s)
{
ptr_func [s] ();
}
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "func.h"
#undef STATE
};
В таком виде компилятор собирает, но не работает.
Не заполняется перечисление
Спойлер
Код: Выделить всё
typedef enum _proc_device
{
#define STATE(name, func) name,
#include "func.h"
#undef STATE
PROC_DEVICE_STATES,
}proc_device_t;
работает только в таком виде
Спойлер
Код: Выделить всё
typedef enum _proc_device
{
PROC_DEVICE_INIT,
PROC_DEVICE_WAIT_SWITCH_MODE,
PROC_DEVICE_STATES,
}proc_device_t;
Господа, программисты, кто что подскажет?
Re: Помогите пожалуйста с кодом С#
Добавлено: Пт авг 07, 2020 08:02:31
ARV
кроме автора, в этом коде мало кто разберется. а у него, вангую, ответ будет "было давно, не помню сейчас (или - некогда вспоминать), но код рабочий, читайте книги".
однако, вот это место
Dimon456 писал(а):#define STATE(name, func) name,
лично меня настораживает: запятая в конце дефайна явно свидетельствует, что макрос STATE - очень контекстно-зависимый макрос, что, имхо, очень нехорошо. если подобных вещей по исходнику много - совсем беда для тех, кто захочет разобраться.
Re: Помогите пожалуйста с кодом С#
Добавлено: Пт авг 07, 2020 09:58:50
Dimon456
Обратите внимание в c-файле _proc_device.с есть функция
Спойлер
Код: Выделить всё
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
#define STATE(name, func) func,
#include "func.h"
#undef STATE
};
где "это" нормально работает.
Не работает только в h-файле, в перечислении enum. Возникает вопрос - по чему?
Может есть другой способ, просканировать файлик func.h и в перечисление enum вписать соответствующие строчки?
Понятно что автор автоматизировал процесс. У него IAR, там свой компилятор.
ARV, я уже встречался с таким, что компилятор компилятору рознь, и по разному могут обрабатывать "это".
Для интереса, вечером, проверю как "это" проглотит компилятор gcc_arm.
Re: Помогите пожалуйста с кодом С#
Добавлено: Сб авг 08, 2020 20:18:16
Dimon456
ARV, в общем "это" ни где нормально не работает. IAR-?
gcc_arm не проглотил, но работает так же как и winavr.
Потом решит попробовать на С++ на срр файлах, думал что там сверх естественное что-то есть,
на winavr мне С++ не удалось создать, вспомнил что eclips умеет, eclips в связке с тем же avr-gcc (GCC) 9.2.0.
На С++ то же не пошло, кроме всего прочего еще потребовалось и явное указание
Спойлер
Код: Выделить всё
__flash FUNC proc_device_func [PROC_DEVICE_STATES] =
{
//#define STATE(name, func) func,
//#include "func.h"
//#undef STATE
proc_device_init,
proc_device_wait_switch_mode,
};
и что то ему там с __flash не понравилось, и двойное определение.
Следом попробовал на eclips в связке с тем же avr-gcc (GCC) 9.2.0 но на С, проект нормально собрался, но опять же потребовалось явное указание как и на С++.
Странно, winavr так, eclips эдак, а avr-gcc один и тот же.
На IAR проверю как нибудь в другой раз.