Jump to content
pndbr

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

Recommended Posts

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

Edited by parovoZZ

Share this post


Link to post
Share on other sites
45 минут назад, pndbr сказал:

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

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

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

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

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

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

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

ЗЫЫ @parovoZZ  :i-m_so_happy:

 

Share this post


Link to post
Share on other sites

Импульсный источник питания - расчет за 10 минут в eDesignSuite

Как ориентироваться в огромном количестве существующих вариантов, чтобы выбрать наиболее подходящий для конкретного случая. «Ручной» перебор всех вариантов может оказаться весьма трудоемким процессом, а полученный результат – далеко не оптимальным. Специализированное программное обеспечение, позволяет уменьшить количество рутинных операций при проектировании.

Подробнее

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

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

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

Edited by pndbr

Share this post


Link to post
Share on other sites
                     

Как упростить выбор ИП для промышленного применения?

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

Подробнее

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

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

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

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

Share this post


Link to post
Share on other sites
                     

Преимущества новых высоковольтных SOI-драйверов Infineon

При производстве драйверов силовых транзисторов компания Infineon использует различные технологии: JI, SOI, CT. Драйверы, выполненные с применением технологии SOI, имеют целый ряд преимуществ по сравнению с классическими JI-драйверами. В статье рассматриваются эти преимущества на примере новых семейств драйверов 650 В 2ED210x и 2ED218x.

Подробнее

 

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

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

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

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

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

Share this post


Link to post
Share on other sites

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

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


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

Share this post


Link to post
Share on other sites
5 часов назад, pndbr сказал:

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

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

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

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

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

Share this post


Link to post
Share on other sites
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 (даже больше,не все возможные ошибки пока учел)комбинациями разрастаются в страшную мешанину  в моих руках

Share this post


Link to post
Share on other sites
Только что, pndbr сказал:

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

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

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

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


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

Share this post


Link to post
Share on other sites
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();
	}
}

 

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

 

Share this post


Link to post
Share on other sites

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

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

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

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

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

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


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

Share this post


Link to post
Share on other sites
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 мс и стояние кнопок каждую секунду и исходя из этих данных кручу двигатель в нужную сторону и зажигаю  соответствующий режиму светодиод.

 

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

Спасибо

 

Share this post


Link to post
Share on other sites
18 часов назад, pndbr сказал:

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

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

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


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

Share this post


Link to post
Share on other sites

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

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


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

Share this post


Link to post
Share on other sites

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

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

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

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

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

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

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

и еще.

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


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

Share this post


Link to post
Share on other sites
17 часов назад, Starichok сказал:

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

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

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


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

Share this post


Link to post
Share on other sites

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

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • если ищите оригинальный транзюк  то остерегайте  Shop1157182 Store ! взял там пяток типа бу w25nm60 прислали не фуфло но перепил ,в центре корпуса нет окошки с маркировкой (сама маркировка есть) ! по моему если нет окошки то  80%  что перемаркер )) у полученных транзисторов емкость затвора 3500пф (по дт 2400пф) сопротивление 0,33 ом по дт должно быть 0.16ом ! по моему ирфп450 или 350 
    • Все верно - светодиод, батарейка на 3В (например CR2032 или подобная) и геркон. Но 7 см это вряд ли, даже с датчиком Холла.
    • Милли или Мега? Мега.  Какое отношение..... У RX первоначальное сопротивление не изменилось, у TX сопротивление не померишь хоть с кз хоть без него, конечно же мерял на корпус .  Вчера через эпоксидку, паяльником добрался до луженого проводника графитового экрана, подпаялся времянкой к нему и к штекеру , ну и все заработало, на 4 барьере в доме тишина, вернулись  "чуйка" и баланс.   После подключении времянки, между экраном и обмотками на измерении 20 мегаОм полный ноль, видать кабель экрана держался на какой то волосинке и была вся эта байда. Сегодня думаю закончить эту косметику.     
    • Такой древний маловероятно, что дожил до наших дней, а если и так, то пора бы ему уже отправиться "в страну вечного эфира".
    • Я могу предположить, что аполитичность народа привела его в полное равнодушие к происходящему и, как следствие, породила страх в массах, а страх порождает трусость..
    • https://forum.cxem.net/index.php?/blogs/entry/306-управление-светодиодами/ - в середине записи схема ("Г") и под ней видео ее работы. VT2VT3 заменяются на КТ827 (P-N-P) и убирается резистор R5. Можно и на КТ829, но тогда к подсветке нужно будет тянуть два провода - от питания и от коллектора транзистора. А так минусом будет корпус машины. Ток через подсветку задается резистором R6 (потому он и со звездочкой).
    • Дешевле заказть в китае. Есть места, где минимальный заказ от 5шт.... но сначало спроси разрешения у oleg1ma на тиражирование.
×
×
  • Create New...