![]()  | 
	
| 
			
			 | 
		#31 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			А вот так будет выглядеть классический блинк в автоматном стиле: 
		
		
		
		
		
		
		
	Код: 
	// ============================== описание КА "blink" =================================== //
// Собственно содержимое Arhat.lib::TSC_Blink/TSC_Blink.ino
 
/*
 * Светодиод - как конечный автомат имеет состояния:
 *     LED_OFF (выключен, ожидание включения)
 *     LED_ON  (включен, ожидание выключения)
 *
 * Событием, изменяющим состояние является счечик времении.
 */
 
#define _ARHAT_ 1
#include "arhat.h"
 
#define pinLed            13 // ножка платы со встроенным светодиодом
#define WAIT_ON         1000 // длительность состояния "ожидание выключения" мсек.
#define WAIT_OFF        1000 // длительность состояния "ожидание включения" мсек.
 
// Таблица переходов нашего конечного автомата (нумерация с 0!):
TSC_Step        ledTable[2] = {
   { 1, to_on, WAIT_ON}         // "выключен": включить, перейти к состоянию "включен" с задержкой
  ,{ 0, to_off, WAIT_OFF}       // "включен": всё наоборот, выключаем, переходим к пред. состоянию.
};
 
// Методы, исполняемые при изменении состояния КА:
void to_on() { digitalWrite(pinLed, HIGH); }     // .. включаем светодиод
void to_off(){ digitalWrite(pinLed, LOW); }      // .. выключаем светодиод
 
TSC_Control     ledControl;     // тут будем хранить текущие данные этого КА
 
// используем это для начальной настройки конечного автомата (далее КА)
void setup()
{              
  pinMode(pinLed, OUTPUT);                        // ножку светодиода настраиваем как "это выход"
  tsc_init(&ledControl, ledTable, 0, WAIT_OFF);  // добавляем КА и задаем его начальное состояние
}
 
// просто вызываем выполнение текущего шага КА, если получится.
void loop()
{
  tsc_step( &ledControl );
}
 
		 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#32 | 
| 
			
			 Junior Member 
			
			
			
			Регистрация: 26.08.2015 
				
				
				
					Сообщений: 6
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			День добрый, 
		
		
		
		
		
		
		
	Понимаю что вопрос может быть глуп, но все же: Используя вашу библиотеку, необходимо обрабатывать прерывания. Но при #define _ARHAT_ 1 выдает ошибку на 'attachInterrupt' was not declared in this scope что наверное логично (вставляю ее в ваш пример analogRead). Если за комментирова то компилируется, но при это полагаю delay в прерывании работать не будет, и многие вкусности тоже. Mega 2560 R3 IDE 1.6.4 Куда копать, что я не внимательно прочел? Спасибо!  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#33 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Упс. Пасибки за замечание. Детально смогу посмотреть только через недельку.
		 
		
		
		
		
		
		
		
	 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#34 | 
| 
			
			 Junior Member 
			
			
			
			Регистрация: 26.08.2015 
				
				
				
					Сообщений: 6
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Буду ждать. Очень нужна ваша библиотека! 
		
		
		
		
		
		
		
		
			А в прерывании millis или delay работают? Или как в штатной системе? Последний раз редактировалось leon_3; 27.08.2015 в 12:18.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#35 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Не знаю как там в штатном Wiring ... по идее можно, но не нужно ибо "дорого и опасно" (может таймер или обработчик встать колом из-за запрета прерываний или в вашей проге или в таймере). В прерываниях, что в штатной системе, что у меня правильнее пользовать напрямую счетчик переполнений таймера. У меня там есть спец. функция для его консистентного чтения и пример использования ... проверка работы таймера. Только там с запретом прерываний надо корректно разобраться когда и что "можно делать". 
		
		
		
		
		
		
		
	Читаете счетчик и строите свои задержки на изменениях его значений. Только надо помнить что он считает по 1024 миллисекунды ... в обоих вариантах.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#36 | 
| 
			
			 Junior Member 
			
			
			
			Регистрация: 26.08.2015 
				
				
				
					Сообщений: 6
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Понял, спасибо. В моем случае если прерывание есть, то это аварийная ситуация с отключением техники. Но там клапана и насосы слишком инертны, по этому в прерывании нужно считать время. Родная штука не умела ни в каком виде считать время! 
		
		
		
		
		
		
		
	Спасибо, жду исправления вообще с прерыванием!  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#37 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Считать время в прерывании - в любом случае плохая идея. Посмотрите статью в Википедии "Автоматное программирование" и последние посты в этой теме как пример его реализации для Ардуино. 
		
		
		
		
		
		
		
		
			В прерывании достаточно изменять состояние конечного автомата. В вашем случае, есть состояния системы управления и "процессы" управления - последовательные переходы между состояниями с задержками по времени. Отключение насосов или чего там ещё - это точно такой же процесс, просто стартующий из обработчика прерывания. Программирование в автоматном стиле - это то, на что я планирую замещать свою библиотеку по приезду.  
		Последний раз редактировалось Arhat109; 29.08.2015 в 05:58. Причина: опечатки  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#38 | 
| 
			
			 Junior Member 
			
			
			
			Регистрация: 26.08.2015 
				
				
				
					Сообщений: 6
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Ну судя по всему я двигаюсь подобным курсом. 
		
		
		
		
		
		
		
	Я в программировании вообще новичок новичков (грубо говоря это 2ая программа больше 30 строк). Я не могу понять как реализовать переход по прерыванию - т.е. есть прерывание которое должно вызвать длинную функцию. Единственное что мне пришло в голову - по прерыванию менять только переменную-флаг, а во всей программе приходится делать множество проверок этого флага, а при его обнаружении уже прыгать туда куда необходимо... Знаю что не очень вариант, но иных не наше!  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#39 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Верно двигаетесь. 
		
		
		
		
		
		
		
	В прерывании надо только устанавливать факт изменения ситуации - то бишь "изменять некие флаги" или считывать значения или выплевывать их куда-нить (но быстро и коротко, без задержек). Всё остальное (проверка флагов, обработка принятого значения, подготовка "плевка" конечно же должна делать основная часть программы. А вот чтобы не было "много разных проверок" используется то самое "автоматное программирование". Прочтите таки статью в википедии. Я настолько же доходчиво повторить не возьмусь. Там всё очень примитивно разжевано, с той разницей, что "переключающим флагом" является символ, читаемый из входного потока, а не "таймер". Как это может выглядеть в случае "переключающее событие - таймер", я попытался показать тут выше на примере типового Blink.ino. По сути, ваша задача - написать массив переходов (выше - всего 2 состояния), а остальная часть - типовая и пишется "один раз".  
		 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#40 | |
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 Цитата: 
	
 ![]() Угу, логично. attachInterrupt() определена в Wiring, должна работать, если нет строки #define _ARHAT_ 1. Но, в этом режиме и "вкусностей" тоже нет, ибо режим совместимости. ![]() Для подключения прерываний там есть макрос ISRTimer(), но он создает имя только для обработчика прерываний от таймеров: TIMER_1_OVF_vect(), к примеру: обработчик прерывания по переполнению таймер №1. В комментарии к макросу есть все допустимые константы. Для иных обработчиков можно использовать типовые имена процедур, определенные в interrupt.h библиотеки самого компилятора. Они подключаются "автоматически" на стадии линковки (компиляции) итога и без Wiring. Delay() в прерываниях, работать не может, если прерывание остается запрещенным внутри. то есть, если у вас нет команды sei() кажется ... не помню точно как называется, определена там же в interrupt.h. Если прерывания внутри обработчика разрешены, то работать будет, но в случае когда следующее прерывание успевает возникнуть ДО момента завершения предыдущего - можете нарваться на неприятности по переполнению стека вызовов или повторное использование глобальных переменных. В общем так делать НЕ стоит, как и писал ранее. Ну вот "как-то так".  | 
|
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
![]()  | 
	
	
		
| Метки | 
| arduino mega 2560, скетч, ардуино | 
| Здесь присутствуют: 4 (пользователей: 0 , гостей: 4) | |
| Опции темы | Поиск в этой теме | 
| Опции просмотра | |
		
  | 
	
		
  |