Перейти к содержанию

Конечный автомат.


Рекомендуемые сообщения

Здравствуйте. Хочу разобраться с "конечным автоматом"

Думаю эта тема будет очень полезна для начинающих ,а для меня особенно)

Поморгать светодиодом,прочитать состояние с кнопки и вывести значение на индикатор могу.

Как дело касается более сложного алгоритма - там нужен (желателен)конечный автомат..а так как язык Си ,язык высокого уровня абстракции то весьма сложно применить чьи-то наработки,т.к каждый пишет по своему,а примеров по запросу Гугла не так много... попрошу вас выложить свои наработки в этом направлении,чтобы было больше примеров,а так же была возможность задать вопрос касательно кода.

P.s:Возникла необходимость отремонтировать мой старый автомобиль,схему заменяющую на реле я собрал. Но захотелось более технологичного решения на МК авр, попытавшись написать код,я зашёл в тупик,опытные участники подсказали что лучший вариант - конечный автомат. 

Спасибо за внимание, надеюсь на помощь.

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Тут всё просто. Допустим, есть хамелеон. Хамелеон в каждый момент времени может быть только одного цвета. Весь перечень цветов, в которые может окраситься хамелеон, мы заранее определили. Где-то в коде присваиваем ему цвет. А когда нам необходимо задать реакцию хамелеона на определённый цвет, пользуемся обычным switch ... case.Если реакция не перекликается с другими цветами, то в конце ставим break;, ежели перекликается - ничего не ставим и проваливаемся в следующий case. Ой... это уже учебник по программированию....

Изменено пользователем parovoZZ
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

45 минут назад, pndbr сказал:

так как язык Си ,язык высокого уровня абстракции то весьма сложно применить чьи-то наработки

естественно. ну приведу пару примеров "тыц", "тыц" , как они вам помогут конкретно в вашем вопросе, никак.

я вам давал ссылки на лекции , там объясняется что такое графы/таблицы и как они работают.

у вас есть система , которая имеет конечное количество состояний , составляете таблицу всех состояний , потом вписываете какому состоянию соответствует какая комбинация нажатых/нажимаемых кнопок/датчиков или процессов.

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

а выкладывать рабочий код скажем конечного автомата таймера с кнопками, энкодерами, совмещенного с контролером температуры и объяснять  что делает и за что отвечает каждый кусок кода - увольте, не для того оный писался и отлаживался полтора месяца.

ЗЫ хотите помощи составляйте таблицу состояний , поможем с написанием кода. а так это обсуждение сферического коня в вакууме

ЗЫЫ @parovoZZ  :i-m_so_happy:

 

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для заряда литий-железофосфатных (LiFePO4) аккумуляторов

Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

3 часа назад, IMXO сказал:

 

ЗЫ хотите помощи составляйте таблицу состояний , поможем с написанием кода. а так это обсуждение сферического коня в вакууме

ЗЫЫ @parovoZZ  :i-m_so_happy:

 

еще раз спасибо

попытался сделать таблицы состояний..это оказалось сложнее чем я думал.

Не рассмотрел варианты ошибок на следящем устройстве.

Устройство представляет собой дпт с следящим устройством(4 канала).

у устройства есть 3 рабочих состояния  2H 4H 4L

Устройство управляется 3 -мя кнопками, 2 - с фиксацией but4h but4l

и одной кнопкой без фиксации - сбрасывающей эти кнопки  .

Также контакт contro контролирующий любой переход с режима и на режим 4L.

but4h определение нажатия 4н

 but4l  определения нажатия  4l

flag4h флаг режима 4н

flag4l  флаг режима 4l

control любой  переход связанный с режимом 4l проходит через control

таблица 1(опрос режима и кнопок)

режим           but4h      |      but4l      |      flag4h       |      flag4l        |      control            |      действие

  2h                0             |        0            |         0              |        0                |         -                 |        опрос кнопок                              

 2h                 0              |         0           |         1             |         0               |          -                |        4H->2H

 2h                 0               |        0           |          0             |           1             |           1               |     4L->2H

2h                    0               |          0         |          0               |          1             |           0                |  вывод сообщения об ошибке - опрос кнопок

 

4h                 1               |        0            |         1              |        0                |         -                 |   опрос кнопок

4h               1              |        0            |         0              |        1                |         1                 |   4L->4H

4h               1            |        0            |         0                 |        1               |         0                  | вывод сообщения об ошибке - опрос кнопок

4h              1               |        0            |         0              |        0                |         -                  |     2H->4H

 

4l                0            |        1           |         0              |        0                |         0                |   вывод сообщения об ошибке - опрос кнопок

4l                0             |        1            |         0              |        0                |         1             | 2H->4L

4l                 0             |        1            |         1           |        0                |         0              |   вывод сообщения об ошибке -  опрос кнопок

4l               0               |        1            |         1              |        0                |       1             |   4H->4L

4l               0                |        1            |         0              |        1                |        -          |   вывод сообщения об ошибке - опрос кнопок

 

err              1             |        1            |                                                                             | опрос кнопок

 

Таблица 2 (состояний)

contr2 contr3 contr4 contr 5 - контакты следящего устройства режимов работы.

                  contr2            contr3             contr4           contr 5 

2h               0                          1                         0                       1

4h               1                            1                        0                        1

4l                  0                             0                         1                      1

 

таблица3 (переходов(без учета ошибок) )

RIGHT - крутим вправо

LEFT - крутим влево

start_contr2345  начальное положение

test_contr2345  предварительное  положение

 fin_contr2345  конечное положение

tictok() задержка перед остановкой вращения 

            RIGHT | LEFT | start_contr2345 | test_contr2345 | tictoc | fin_contr2 | flag4h | flag4l| 

2H-4H    1       |  0      |  0101                        |   1101                  | 500    |        1100      |         1     |     0      |

  2H-4L   1      |  0      |        0101                     |    0011              | 100     |           0011      |   0            |      1    |

4H-2H     0      | 1      |    1100                          |   1101               |100      |            0101       |0                |    0     |

4H-4L      1     |     0   |    1100                           |    0011             |100     |             0011       |0                |     1    |

4L-2H      0     |     1  |      0011                            |  1101             | 100       |           0101        |0               |       0  |

4l-4h         0       | 1   |    0011                                |  1110          | 500 *   |             1100          | 1               |      0      |

 

Задержка при переходах на 4H обусловлена конструктивными особенностями режима 4Н (будет корректироваться на месте)

 

график переходов состояний следящего устройства  при вращении RIGHT

 0101(2H) ->1101->1001->1101->1100(4H)->1100->0110->0111->0110->0111->0110->0011(4L)

Положения  0101(2H) и 0011(4L) являются крайними и двигатель дальше не крутит.

 

Таблицы получились не к черту,но хотябы свои наработки изложил..и самому стало яснее)

 

 

Цитата

Тут всё просто. Допустим, есть хамелеон. Хамелеон в каждый момент времени может быть только одного цвета. Весь перечень цветов, в которые может окраситься хамелеон, мы заранее определили. Где-то в коде присваиваем ему цвет. А когда нам необходимо задать реакцию хамелеона на определённый цвет, пользуемся обычным switch ... case.Если реакция не перекликается с другими цветами, то в конце ставим break;, ежели перекликается - ничего не ставим и проваливаемся в следующий case. Ой... это уже учебник по программированию....

Спасибо и Вам  @parovoZZ

Но тут я добавил еще зависимость положения лап от цвета,и в зависимости от положения лап он не всегда может окраситься в нужный цвет.А только при определенном положении лап он может стать зеленым,красным или синим. А еще если он нарушит последовательность движения лапами(сделает лишний шаг) он не превратится из зеленого в красного,из красного в синего и . т .д.

вот это и  основная сложность,как лаконично и ясно решить эту задачу, знаний у меня не много,но научится хочется)

Изменено пользователем pndbr
Ссылка на комментарий
Поделиться на другие сайты

честно говоря вы ничего не изложили...

в таблицах ерунда какая-то написана , как может осуществятся переход 4H->2H или  4L->2H , если устройство уже находится в режиме 2H ????

опроса кнопок вообще не должно быть в режимах это процесс происходящий параллельно режимам

и режимы работы это не то как у вас нажаты кнопки на управляющей панели, а то в каком состоянии находится исполнительное устройство , 

Ссылка на комментарий
Поделиться на другие сайты

 

8 часов назад, IMXO сказал:

честно говоря вы ничего не изложили...

Провел работу над ошибками

Пока снова много ерунды не написал,напишу часть..1.jpg.53d29e1f8fcbee35979fcab073841b99.jpg

так правильнее?

Ссылка на комментарий
Поделиться на другие сайты

@pndbr , послушайте моего совета: если у вас нет базовой подготовки в области программирорования, и вы с нуля хотите освоить микроконтроллеры и написать первую свою полезную программу, на начинайте с конечных автоматов. Это студентов хорошо учить с этих "азов", а для практикующего новичка это мрак и немцы под Полтавой.

Нарисуйте просто алгоритм программы и, при помощи эквивалентов графических примитивов из языка Си, просто опишите его на Си. Возможно, проштудируйте систему прерываний - может пригодиться. И для начала все будет работать и вас радовать. А потом займетесь "наворотами".

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, pndbr сказал:

так правильнее? 

правильней - нет, понятней - да.в конечном автомате номер режима определяется состоянием выходов.

смотрим, у вас в 1,2,3,7,8 и 11 одно и тоже состояние выходов. почему?

или вы что-то не так описываете или это один и тот же режим.

и расшифруйте сокращения. 

Ссылка на комментарий
Поделиться на другие сайты

  • 4 недели спустя...
29.07.2019 в 17:09, IMXO сказал:

 

Здравствуйте.

Записал все возможные комбинации в массив(кнопки и считывающий энкодер)

Скрытый текст

pos[] = PINC

unsigned double pos[60] =

{
    0b11010111,0b10010111,0b11010110,0b10010110,0b11010101,0b10010101,0b11010011,0b10010011,0b11010010,0b10010010,
    0b11010001,0b10010001,0b11011011,0b10011011,0b11011010,0b10011010,0b11011001,0b10011001,0b11010011,0b10010011,
    0b11010010,0b10010010,0b11010001,0b10010001,0b11010011,0b10010011,0b11010010,0b10010010,0b11010001,0b10010001,
    0b11110011,0b10110011,0b11110010,0b10110010,0b11110001,0b10110001,0b11100011,0b10100011,0b11100010,0b10100010,
    0b11100001,0b10100001,0b11100111,0b10100111,0b11100110,0b10100110,0b11100101,0b10100101,0b11000111,0b10000111,
    0b11000110,0b10000110,0b11000101,0b10000101,0b11001111,0b10001111,0b11001110,0b10001110,0b11001101,0b10001101
};

при состояниях будут  выполняться ф-ии

при положениях

1.2 -2h()
3.4.9.10.15.16.21.22.27.28-leftto4h()
6.12.18.24.30.36.42.48.54-leftto4l()
7.8.13.14.19.20.25.26.31.32.37.38.44.50.56-rightto2h()
39.40.46.52.58-rightto4h()
59.60 - 4l()
33.34 - 4h()

при остальных error()

подскажите пожалуйста как это можно красиво завернуть в код...с моими недознаниями получается ужас из кучи switch case или if else-ов

спасибо

 

29.07.2019 в 10:39, ARV сказал:

@pndbr , послушайте моего совета: если у вас нет базовой подготовки в области программирорования, и вы с нуля хотите освоить микроконтроллеры и написать первую свою полезную программу, на начинайте с конечных автоматов. Это студентов хорошо учить с этих "азов", а для практикующего новичка это мрак и немцы под Полтавой.

Нарисуйте просто алгоритм программы и, при помощи эквивалентов графических примитивов из языка Си, просто опишите его на Си. Возможно, проштудируйте систему прерываний - может пригодиться. И для начала все будет работать и вас радовать. А потом займетесь "наворотами".

спасибо и вам за ответ.

Но 4 сигнала с энкодера + 2 кнопки + контрольный сигнал 

и возможными 60 (даже больше,не все возможные ошибки пока учел)комбинациями разрастаются в страшную мешанину  в моих руках

Ссылка на комментарий
Поделиться на другие сайты

Только что, pndbr сказал:

Но 4 сигнала с энкодера + 2 кнопки + контрольный сигнал 

и возможными 60 (даже больше,не все возможные ошибки пока учел)комбинациями разрастаются в страшную мешанину  в моих руках

И вы считаете, что конечный автомат на 60 с хвостиком состояний у вас получится лучше?! Прикиньте хотя бы на глазок количество разрешенных ПЕРЕХОДОВ меду этими состояниями, чтобы оценить масштаб беды. А ведь еще могут быть запретные переходы, которые тоже надо обрабатывать и которых может оказаться гораздо больше...

Я продолжаю настаивать на своём мнении ради вашего же блага.

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...
23.08.2019 в 16:12, ARV сказал:

Я продолжаю настаивать на своём мнении ради вашего же блага.

Спасибо за совет, прислушался я к Вам и накидал простыню кода.

Скрытый текст

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/tick.h>
#define F_CPU 8000000UL
#define  CTRL 7   //контроль ручник
#define RIGHT (1<<PB0)//крутим вправо
#define LEFT  (1<<PB1)//крутив влево
#define SW4H  (1<<PB2)//индикатор 4н
#define SW4L  (1<<PB3)//индикатор 4л
#define ERROR (1<<PB4)//индикатор ошибки
volatile unsigned char but2H = 0 ;//флаг 2н
volatile unsigned char but4H = 0 ;//флаг 4н
volatile unsigned char but4L = 0 ;//флаг 4л
uint16_t t0_ctr;
uint16_t t_ms;  //задержка
uint32_t t_sec32;
uint8_t pin_state;
uint8_t enc_state = 0b00000000; //состояние энкодера
uint8_t btn_state = 0b00000000; //состояние кнопок
uint8_t enc = 0;//переменная энкодера
uint16_t tbut = 0;//время опроса кнопок
uint16_t tmot = 0;//время кручения мотора
uint8_t errorswl = 0;//ошибка вращения влево
uint8_t errorswr = 0;//ошибка вращения вправо

uint16_t tbutctr = 0;//антидребезг кнопок
uint16_t tenc = 0;//опрос энкодера

static volatile uint8_t ovf_ctr;

ISR(TIMER0_OVF_vect)
{
	ovf_ctr++;
}
void t0_update()  //ф-ии задержки
{
	uint8_t ctr_high, ctr_low;
	static uint16_t last_ms, last_sec;
	
	do {
		ctr_high = ovf_ctr;
		ctr_low = TCNT0;
	} while((TIFR & (1<<TOV0)) || (ovf_ctr != ctr_high));
	t0_ctr = ctr_low | (ctr_high << 8);
	
	while(t0_ctr - last_ms >= T0_MS(1))
	{
		t_ms++;
		last_ms += T0_MS(1);

		if(t_ms - last_sec >= 1000)
		{
			t_sec32++;
			last_sec += 1000;
		}
	}
}
void t0_init()//инициализация таймера для задержки
{
	TCCR0 = T0_PRESC;      /* запустить счёт */
	TIMSK |= 1<<TOIE0;      /* разрешить прерывание по переполнению */
}
void t2h()
{
	PORTB|=(SW4H|SW4L|RIGHT|ERROR);
	errorswr=0;
}
void t4h()
{
	PORTB&=~SW4H ;
	PORTB|=(LEFT|SW4L|ERROR);
	errorswr=0;
	errorswl=0;
}
void t4l()
{
	PORTB&=~SW4L;
	PORTB|=(LEFT|SW4H|ERROR);
	errorswl=0;
}
void toright2h()//двигаем вправо с 4н до 2н
{
	if(errorswr<=3)
	{
		do
		{
			PORTB&=~RIGHT;
			tmot=t_ms;
		}
		while ((((int16_t)(t_ms - tmot) >= 2000)) || (enc==1));//положение энкодера 1 или крутим дольше 2с
		PORTB|=RIGHT;
		if (enc==1)
		{
			t2h();
		}
		else
		{
			PORTB&=~ERROR;
			errorswr++;
		}
	}
	else PORTB&=~ERROR;
	
}
void toright2hl()//двигаем с 4л до 2н
{
	if (0==(PIND&(1<<CTRL))&&(errorswr<=3))//контроль ручника
	{
		do
		{
			PORTB&=~RIGHT;
			tmot=t_ms;
		}
		while ((((int16_t)(t_ms - tmot) >= 2000))&&(enc==1));
		PORTB|=LEFT;
		if (enc==1)
		{
			t2h();
		}
		else
		{
			PORTB&=~ERROR;
			errorswr++;
		}

	}

	else
	{
		PORTB&=~ERROR;
	}
}
void  toleft4l()//крутим влево до 4л
{
	if (0==(PIND&(1<<CTRL))&&(errorswl<=3))//контроль ручника
	{
		do
		{
			PORTB&=~LEFT;
			tmot=t_ms;
		}
		while ((((int16_t)(t_ms - tmot) >= 2000))||(enc==8));//
		PORTB|=LEFT;
		if (enc==8)
		{
			t4l();
		}
		else
		{
			PORTB&=~ERROR;
			errorswl++;
		}

	}
}
void toleft4h()
{
	if(errorswl<=3)
	{
		do
		{
			PORTB&=~LEFT;
			tbut=t_ms;
		}
		while ((((int16_t)(t_ms - tmot) >= 2000))||(enc==4));
		PORTB|=LEFT;
		if (enc==4)
		{
			t4h();
		}
		else
		{
			PORTB&=~ERROR;
			errorswl++;
		}
	}
	else
	{
		PORTB&=~ERROR;
	}
	
}
void toright4h()
{
	if (0==(PIND&(1<<CTRL))&&(errorswr<=3))
	{
		do
		{
			PORTB&=~RIGHT;
			tbut=t_ms;
		}
		while ((((int16_t)(t_ms - tmot) >= 2000))||(enc==4));
		PORTB|=RIGHT;
		if (enc==4)
		{
			t4h();
		}
		else
		{
			PORTB&=~ERROR;
			errorswr++;
		}
	}
	else
	{
		PORTB&=~ERROR;
	}
}
void enc_state_f()//опрос энкодера каждые 50мс
{
	tenc = t_ms;
	while(((int16_t)(t_ms - tenc) >= 0 ))
	{
		tenc+=T0_MS(50);
		enc=0;
		
		pin_state=PIND ;

		enc_state = pin_state & 0b00111100 ;//маска 2345 битов энкодера
		
		if(enc_state==0x14)  enc=1 ; //2h  0х14 0b00010100
		if(enc_state==0x10)  enc=2 ; //     0х10 0b00010000
		if(enc_state==0x18)  enc=3 ;//     0х18 0b00011000
		if(enc_state==0x30)  enc=4 ;//4h   0х30 0b00110000
		if(enc_state==0x20)  enc=5 ;//     0х20 0b00100000
		if(enc_state==0x24)  enc=6 ;//     0х24 0b00100100
		if(enc_state==0x04)  enc=7 ;//     0х04 0b00000100
		if(enc_state==0x0C)  enc=8 ;//4l   0х0С 0b00001100
		if(enc==0)  PORTB &=~ ERROR;
		
	}
	
}
void btn_state_f() //опрос кнопок каждую секунду
{
	tbutctr = t_ms;
	while(((int16_t)(t_ms - tbutctr) >= 0 ))
	{
		tbutctr+=T0_SEC(1);

		btn_state = PIND & 0b00000011 ;


		if ((btn_state & 0b00000011) == 0b00000010 ) //4h
		{
			tbut = t_ms;
			while(((int16_t)(t_ms - tbut) >= 0 ))//антидребезг
			{
				tbut+=T0_MS(150);
				if ((((btn_state & 0b00000011 ) == 0b00000010 )))
				{
					but4H = 1;
					but4L = 0;
					but2H = 0;
				}
				else
				{
					but4H = 0;
				}
			}
		}
		if ((btn_state & 0b00000011 )== 0b00000001 )//4l
		{
			tbut = t_ms;
			while(((int16_t)(t_ms - tbut) >= 0 ))
			{
				tbut+=T0_MS(150);
				if(((btn_state & 0b00000011 ) == 0b00000001 ))
				{
					but4L = 1;
					but4H = 0;
					but2H = 0;
				}
				else
				{
					but4L = 0;
				}
			}
		}
		if ((btn_state & 0b00000011)==0b00000011) //2h
		{
			tbut = t_ms;
			while(((int16_t)(t_ms - tbut) >= 0 ))
			{
				tbut+=T0_MS(150);
				if(((btn_state & 0b00000011)==0b00000011))
				{
					but2H = 1;
					but4L = 0;
					but4H = 0;
				}
				
				else
				
				{
					but2H = 0;
				}
			}
		}
	}
}
void swto4hnew()//
{
	switch (enc)
	{
		case 1: toleft4h()	; break;
		case 2: toleft4h()	; break;
		case 3: toleft4h()	; break;
		case 4: t4h() ; break;
		case 5: toright4h()	; break;
		case 6: toright4h()	; break;
		case 7: toright4h()	; break;
		case 8: toright4h()	; break;
		default: PORTB &=~ ERROR;
	}
}
void swto4lnew()
{
	switch (enc)
	{
		case 1: toleft4l()	; break;
		case 2: toleft4l()	; break;
		case 3: toleft4l()	; break;
		case 4: toleft4l()  ; break;
		case 5: toleft4l()	; break;
		case 6: toleft4l()	; break;
		case 7: toleft4l()	; break;
		case 8: t4l()        ; break;
		default: PORTB &=~ ERROR;
	}
}
void swto2hnew()
{
	switch (enc)
	{
		case 1: t2h()	; break;
		case 2: toright2h()	; break;
		case 3: toright2h()	; break;
		case 4: toright2h()   ; break;
		case 5: toright2hl()	; break;
		case 6: toright2hl()	; break;
		case 7: toright2hl()	; break;
		case 8: toright2hl()	; break;
		default: PORTB &=~ ERROR;
	}
}
void change()//главная ф-ия
{
	if (but2H==1) swto2hnew();
	if (but4H==1) swto4hnew();
	if (but4L==1) swto4lnew();
}

int main()
{
	DDRD = 0b00000000;
	DDRB = 0b11111111;
	PORTB = 0b11111111;
	PORTD = 0b11111111;
	t0_init();
	sei();
	while (1)
	{
		t0_update();
		enc_state_f();
		btn_state_f();
		change();
	}
}

 

в симуляторе студии работает,сегодня попробую потестить в железе

 

Ссылка на комментарий
Поделиться на другие сайты

По простыне кода ничего сказать не могу... Если оно работает, это уже успех.

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

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

while(1){
	display(); // выводим индикацию
	event = get_event(); // запрашиваем событие, которое могло произойти
	// обработка события
	switch(event){
    	case EV_BUTTON: // нажата кнопка
    		break;
    	case EV_ENCODER: // повернулся енкодер
    		break;
    	case EV_DATCHIK: // на что-то среагировал какой-то датчик
    		break;
    	default:
    		// ничего не происходило
    		break;
    }
}

Само собой, вместо break должна быть какая-то полезная работа. И, кстати, на эту концепцию отлично накладывается концепция конечного автомата, только автомата не по состояниям внешних линий, а автомата по состояниям программы управления. Например, если в обработчике EV_BUTTON получен код кнопки "Стоп", можно активировать состояние "Стоп", в котором тот же обработчик кнопок будет реагировать на другие кнопки по-другому, дисплей будет отображать иначе, и сигналы датчика будут игнорироваться. В этом случае вполне допустимо завести переменную внутреннего состояния state и передавать её во все функции, зависящие от состояния, например, так:

static STATE state = ST_DEFAULT;
while(1){
	display(state); // выводим индикацию
	event = get_event(state); // запрашиваем событие, которое могло произойти
	// обработка события
	switch(event){
    	case EV_BUTTON: // нажата кнопка
        	switch(get_button(event)){
            		case KEY_STOP: state = ST_STOP; break;
            		case KEY_RUN: state = ST_RUN; break;
        	}
    		break;
    	case EV_ENCODER: // повернулся енкодер
    		break;
    	case EV_DATCHIK: // на что-то среагировал какой-то датчик
    		break;
    	default:
    		// ничего не происходило
    		break;
    }
}

У вас же пока что от концептуального подхода в проектировании нет ничего.

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

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, ARV сказал:

. То есть разделение на функции у вас носит скорее косметический характер, нежели, собственно, алгоритмический (если позволите так выразиться). Я, конечно, могу и ошибаться... но вот так мне показалось

Вам не показалось, многое я убрал в отдельные ф-ии для того чтобы удобнее было воспринимать код(недокод). И это почти первый мой код,и концептуальному подходу тут,пока неоткуда взяться.

За этим я и обратился на форум,чтобы подпинывали в нужном направлении)

Устройство имеет 3 кнопки выбора режима,2 с фиксацией(4н 4l) и одна сбрасывающая любую из них в режим (2h).

Имеется привод вращающий исполнительный механизм от упора до упора влево и вправо. На этом механизме установлен энкодер на котором во время вращения есть 8 состояний. 3 из них соответствуют положениям кнопок 1- это режим 2н(первое крайнее) когда кнопки не нажаты или сброшены(состояние энк 1),и 4н и 4л(второе крайнее соответствующее енк 8). Из положения 2н мы можем перейти 4н и 4л(при условии срабатывания контакта кнтр) из 4н в 2н и 4л(при кнтр),из 4л мы можем перейти в 2н и 4н только при  срабатывании контакта "кнтр". При срабатывании режимов 4н и 4л загораются соответствующие индикаторы .

 

В выше написанной простыни я сначала опрашиваю текущее состояние энкодера каждые 50 мс по спец функции,дабы  уйти от delay и записываю состояние чз маску и даю им значения от 1 до 8,потом опрашиваю кнопки 4н и 4л каждую секунду с антидребезгом в 150 мс,после исходя из текущего состояния  энкодера и кнопок вращаю двигатель влево или вправо с 3 мя этапами контроля:

1- это контроль вращения не дольше 2-секунд(чтобы не сжечь в крайнем положении двигатель)

2- это контроль состояния режима энкодера соответствующего кнопке.

3- контроль контакта  "кнтр"(дабы переключать только в безопасных режимах)

Так же добавил аккумулятор ошибки,при ошибке переходов больше или равное 3 двигатель вращать перестаём,дабы не сжечь.

 

В итоге в бесконечном цикле я опрашиваю состояние энкодера с частотой 50 мс и стояние кнопок каждую секунду и исходя из этих данных кручу двигатель в нужную сторону и зажигаю  соответствующий режиму светодиод.

 

Вот такая задача,с статьей я начал ознакамливаться, очень интересно, позже внесу поправки в свою простыню.

Спасибо

 

Ссылка на комментарий
Поделиться на другие сайты

18 часов назад, pndbr сказал:

На этом механизме установлен энкодер на котором во время вращения есть 8 состояний.

Проблемы программирования начинаются с того что у вас очень туманное представление о том что ваша машина должна делать и о критериях контроля этих действий.

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

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

Добавлю к только что сказанному @ruhi : "состояние" может быть разным при одном и том же, все зависит от степени детализации и направления взгляда на проблему. Если смотреть на систему, как на черный ящик с N входами и M выходами, состоянием надо называть каждую уникальную комбинацию [N,M]. Если же смотреть внутрь этого ящика, то вполне могут появиться состояния "ожидание включения", "вычисление скорости", "перерегулирование", "аварийное состояние" и т.п.

Согласитесь, что второе намного понятнее и "охватнее" умом, нежели первое...

Если забанить всех, кто набрался смелости думать независимо, здорово будет на форуме - как на кладбище: тишина, птички поют...

Ссылка на комментарий
Поделиться на другие сайты

да там из такой словесной каши вообще ничего не понять.

что это за режимы и чем они характеризуются (чем отличаются)?

почему режимы и кнопки имеют одинаковые названия?

что или кто нажимает эти кнопки, и где стоят эти кнопки?

то же самое про контакт  "кнтр" - где он стоит и что его нажимает?

нужна кинематическая схема устройства или подробное однозначное словесное описание устройства.

а так ни из одного поста автора ровным счетом ни хера не понятно...

и еще.

 если двигатель (механизм) дошел до упора, то отключать двигатель нужно моментально. а то двух секунд вполне может хватить, чтобы двигатель сгорел.

Мудрость приходит вместе с импотенцией...

Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.

Ссылка на комментарий
Поделиться на другие сайты

17 часов назад, Starichok сказал:

нужна кинематическая схема устройства или подробное однозначное словесное описание устройства.

Вот! Это по существу! Но, к сожалению, обычно люди предпочитают рассуждать о каких то абстрактных "конечных автоматах", "состояниях", "направлениях взгляда на проблему", ...

о чем угодно, только не об условиях реальной задачи :( !

Можно сделать все! Но чем больше можно, тем больше нельзя!

Ссылка на комментарий
Поделиться на другие сайты

  • 4 недели спустя...

Всем спасибо за ответы,с моими знаниями этот проект на данный момент для меня не выполним.

В итоге сделал немного упрощённый вариант на 3 х микросхемах советской логики и горстки транзистров.

Буду учиться на задачах попроще.

Ещё раз спасибо

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы публикуете как гость. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...