![]()  | 
	
| 
			
			 | 
		#21 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Это не интересно, не нужно или не работает? Как-то никто так и не проверил библиотеку... так стоит ли продолжать далее?  
		
		
		
		
		
		
		
	![]() Вчера весь вечер убил на чтение даташита про прерывания. Задача была сделать замер длительности импульса (Wiring:: pulseIn()) через прерывания. Внезапно выяснил, что использовать PCINT не получится, поскольку нет управления режимом прерываний: только по изменению уровня. А требуется переустанавливать с прерывания по фронту на прерывание по спаду, иначе легко можно намерить длительность не того уровня. Кроме этого, вторая "засада": в прерывании типа PCINT невозможно (или я так и не понял КАК) узнать от какой конкретно ножки этого уровня оно прилетело. По сути, к примеру PCINT16..23 выведены на ножки Analog8..15 и их удобно использовать как прерывания (16 анлаговых ножек мне точно не надо) ... но одновременно разрешать можно только одну из них, иначе нет способа узнать "какая конкретно сейчас сработала"... а датчиков HC-SR04 у меня 2. Для них и делаю. И третье: прерываний INT0..7 на Ардуино Мега разведено ... только 5. Из них 2 совмещаются в контроллере с шиной I2C, которая мне нужна "как воздух" (датчик гироскопа, гирокомпаса и дисплей 1602), ещё 2 - это USART1, который планировался как средство связи с приемо-передающими модулями, тот же Bluetooth, и пятое - это PWM ножка, которые все у меня планировались под аппаратный ШИМ на серво моторы (12шт)... и, "как быть"? Отказаться от USART1, заменив его на 2 или 3? ... в общем, требуется совет от бывалых: стоит ли реализовывать замер длительности импульсов в библиотеке через обработку прерываний?  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#22 | |||
| 
			
			 Administrator 
			
			
			
				
			
			Регистрация: 12.04.2010 
				Адрес: Москва 
				
				
					Сообщений: 9,618
				 
				
				
				Вес репутации: 9824 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()  | 
	
	
	
		
		
			
			 Цитата: 
	
 Цитата: 
	
 Цитата: 
	
  | 
|||
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#23 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			I need help.  
		
		
		
		
		
		
		
		
			![]() Не нашел КАК проверить в обработчике. Он же един на весь вектор PCINT0..2! Флаг прорывания устанавливается общий (там всего три бита), номер ножки, вызвавшей прерывание - не нашел КАК опознать... или есть способ? Хотя ... если строго для замера длительности импульса ... он жеж "стоять" должен... можно тупо считывать "прерывательные" ножки и смотреть "кто такой вумный"... но. Это ни разу не поможет повесить 2 HC-SR04 на 2 ноги прерывания и замерять параллельно ... хотел поставить 2шт. на сервомотор "спиной друг к другу" и сканировать обе полусферы одновременно... или "почти". Последний раз редактировалось Arhat109; 03.07.2015 в 11:49.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#24 | ||
| 
			
			 Administrator 
			
			
			
				
			
			Регистрация: 12.04.2010 
				Адрес: Москва 
				
				
					Сообщений: 9,618
				 
				
				
				Вес репутации: 9824 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()  | 
	
	
	
		
		
			
			 Цитата: 
	
 Цитата: 
	
  | 
||
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#25 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Да, похоже что так и придется реализовывать: устанавливать и смотреть в каком состоянии все ножки прерываний заданного уровня, которые подключены к замерам длительностей. 
		
		
		
		
		
		
		
	... но мне кажется, что это "как-то ненадежно"...  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#26 | 
| 
			
			 Administrator 
			
			
			
				
			
			Регистрация: 12.04.2010 
				Адрес: Москва 
				
				
					Сообщений: 9,618
				 
				
				
				Вес репутации: 9824 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]()  | 
	
	
	
		
		
			
			 
			
			А что смущает? Это же обработчик, в нем можно выполнять любой код, не связанный с другими прерываниями
		 
		
		
		
		
		
		
			
		
		
		
		
	 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#27 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Смущает это (выложу пока то что получается, не компилял ещё): 
		
		
		
		
		
		
		
	PHP код: 
	
			
	Следующим циклом я подсчитываю "номер" сработавшего бита. Это не есть "хорошее решение". Ибо "если вдруг", одновременно (в рамках одного вызова обработчика) происходит 2 и более "срабатываний" (например, прерывания были запрещены длительное время в скетче - понятно что "Г-кодинг"), то по-хорошему надо обработать ВСЕ сработавшие ножки... как? Ну и "второй момент", который сейчас "тормозит процесс": надо как-то указать обработку таймаута... или расширять обработчик таймера, и в нем добавлять цикл по всем таймаутам .. или полностью менять идеологию библиотеки, уходя от типового Wiring на "событийный конечный автомат". Последнее решение "в целом" мне кажется перспективней. И сильно. "Робот" - это всяко обыкновенный конечный автомат, работающий по возникающим событиям. ... в обшем, я "таймаут в разработке" и взял по причине того что "доперло": нафиг не надо улучшать Wiring. Требуется совершенно иной подход.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#28 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Так. Похоже это был какой-то глюк в моей среде 1.6.4 ... переставил себе заново эту версию и ... опаньки! Забыл переименовать wiring.c ... а оно возьми да и скомпиляйся без ошибок. 
		
		
		
		
		
		
		
	Похоже что библиотекарь таки работает "как и положено": подшивает то, что есть в файлах, если оно есть ИЛИ берет из библиотеки core.a если его нет.. Существенно меняет ситуацию: можно НЕ переименовывать ничего... и даже с main.cpp "поиздеваться вдоволь". ![]() поправил первый пост.  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#29 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Допилил замер длительности импульса через прерывания PCINT2 ... возник вопрос с таймаутами, ибо датчик в реальности вполне себе может срабатывать "через раз": 
		
		
		
		
		
		
		
	Сделал расширение к обработчику таймера, которое смотрит наличие включенных таймаутов и если они есть и "наступило время" - косвенно вызывает заданную процедуру обработки таймаута. К сожалению, поскольку таймер включен по определению, теперь обработчик требует наличия структуры данных по таймаутам ... а там пока массив на 8 событий... "итого" - около 60 байт оперативы. Это - плохо? Переходить на стандартные "очереди" на указателях и malloc()? Насколько "опасно" вызывать процедуры таймаутов из обработчика прерывания по таймеру (активизируется примерно каждую миллисекунду, пашет с закрытыми прерываниями "по определению") ... не получится так, что пачка возникших таймаутов заломает всю обработку прерывания? Есть решения лучше?  | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
| 
			
			 | 
		#30 | 
| 
			
			 Senior Member 
			
			
			
			Регистрация: 14.06.2015 
				Адрес: СССР 
				
				
					Сообщений: 122
				 
				
				
				Вес репутации: 0 ![]()  | 
	
	
	
		
		
			
			 
			
			Часть библиотеки для "автоматного программирования": 
		
		
		
		
		
		
		
	Код: 
	// ==================== то, что должно было быть определено в Wiring ====================== //
/**
 * Time State Control Simple Library. Prefix for this: TSC_ (tsc_)
 *
 * Библиотека создания простых конечных автоматов с задержками исполнения по времении
 * в миллисекундах через функцию millis().
 *
 * @author Arhat109 at 2015-07-18
 * @see Arhat.lib::examples/TSC_Blink/TSC_Blink.ino
 */
typedef unsigned long TSC_Time;      // переопределение "на будущее": не всегда нужен long
typedef void (*TSC_Command)(void);   // вводим определение типа "команда КА" тут просто процедура без параметров
 
// вводим определение типа ячейки хранения состояний автомата:
typedef struct {
  uint8_t       state;          // номер следующего состояния в таблице переходов
  TSC_Command   command;        // команда (метод) для исполнения действий состояния
  TSC_Time      timeout;        // временной интервал следующего состояния (мсек)
} TSC_Step;
 
// вводим определение типа для хранения текущего состояния конечного автомата (КА)
typedef struct {
  uint8_t       state;          // текущий номер исполняемого состояния КА
  TSC_Time      timeout;        // текущий интервал, которого надо дождаться
  TSC_Step *    table;          // таблица переходов этого КА
} TSC_Control;
 
void tsc_init( TSC_Control *_tsc, TSC_Step * _table, uint8_t _state, TSC_Time _wait );
void tsc_next( TSC_Control *_tsc, uint8_t _state, TSC_Time _wait );
void tsc_step( TSC_Control *_tsc );
Код: 
	// ======== TimeStateControl.c -- реализация библиотеки: ======== //
include "TimeStateControl.h"
// метод сохранения текущих данных для конечного автомата:
void tsc_init( TSC_Control *_tsc, TSC_Step * _table, uint8_t _state, TSC_Time _wait )
{
    _tsc->table = _table;                 // сохраняем теблицу переходов для этого КА
    tsc_next(_tsc, _state, _wait);        // устанавливаем его текущее состояние в начальное
}
 
// метод перехода к следующему шагу конечного автомата:
void tsc_next( TSC_Control *_tsc, uint8_t _state, TSC_Time _wait )
{
    _tsc->state = _state;                      // устанавливаем следующее состояние
    _tsc->timeout = millis() + _wait;          // и его время ожидания
}
 
// метод "шаг цикла КА":
// параметр - указатель на состояние заданного КА.
void tsc_step( TSC_Control *_tsc )
{
  if( millis() >= _tsc->timeout )         // если событие, переключающее КА - наступило:
  {
    TSC_Step * current;                   // определяем место хранения структуры состояния КА
 
    current = _tsc->table + _tsc->state;  // и находим "текущее состояние КА"
 
    current->command();                            // исполняем команду
    tsc_next(_tsc, current->state, current->timeout); // и устанавливаем следующий шаг КА
  }
}
 | 
| 
		 | 
	
	
	
		
		
		
		
			 
		
		
		
		
		
		
		
			
		
		
		
	 | 
![]()  | 
	
	
		
| Метки | 
| arduino mega 2560, скетч, ардуино | 
| Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
		
  | 
	
		
  |