03.07.2015, 07:34 | #21 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Это не интересно, не нужно или не работает? Как-то никто так и не проверил библиотеку... так стоит ли продолжать далее?
Вчера весь вечер убил на чтение даташита про прерывания. Задача была сделать замер длительности импульса (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? ... в общем, требуется совет от бывалых: стоит ли реализовывать замер длительности импульсов в библиотеке через обработку прерываний? |
03.07.2015, 10:39 | #22 | |||
Administrator
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9823 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Цитата:
Цитата:
Цитата:
|
|||
03.07.2015, 11:45 | #23 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
I need help.
Не нашел КАК проверить в обработчике. Он же един на весь вектор PCINT0..2! Флаг прорывания устанавливается общий (там всего три бита), номер ножки, вызвавшей прерывание - не нашел КАК опознать... или есть способ? Хотя ... если строго для замера длительности импульса ... он жеж "стоять" должен... можно тупо считывать "прерывательные" ножки и смотреть "кто такой вумный"... но. Это ни разу не поможет повесить 2 HC-SR04 на 2 ноги прерывания и замерять параллельно ... хотел поставить 2шт. на сервомотор "спиной друг к другу" и сканировать обе полусферы одновременно... или "почти". Последний раз редактировалось Arhat109; 03.07.2015 в 11:49. |
03.07.2015, 12:19 | #24 | ||
Administrator
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9823 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Цитата:
Цитата:
|
||
03.07.2015, 14:07 | #25 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Да, похоже что так и придется реализовывать: устанавливать и смотреть в каком состоянии все ножки прерываний заданного уровня, которые подключены к замерам длительностей.
... но мне кажется, что это "как-то ненадежно"... |
03.07.2015, 16:00 | #26 |
Administrator
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9823 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
А что смущает? Это же обработчик, в нем можно выполнять любой код, не связанный с другими прерываниями
|
04.07.2015, 08:50 | #27 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Смущает это (выложу пока то что получается, не компилял ещё):
PHP код:
Следующим циклом я подсчитываю "номер" сработавшего бита. Это не есть "хорошее решение". Ибо "если вдруг", одновременно (в рамках одного вызова обработчика) происходит 2 и более "срабатываний" (например, прерывания были запрещены длительное время в скетче - понятно что "Г-кодинг"), то по-хорошему надо обработать ВСЕ сработавшие ножки... как? Ну и "второй момент", который сейчас "тормозит процесс": надо как-то указать обработку таймаута... или расширять обработчик таймера, и в нем добавлять цикл по всем таймаутам .. или полностью менять идеологию библиотеки, уходя от типового Wiring на "событийный конечный автомат". Последнее решение "в целом" мне кажется перспективней. И сильно. "Робот" - это всяко обыкновенный конечный автомат, работающий по возникающим событиям. ... в обшем, я "таймаут в разработке" и взял по причине того что "доперло": нафиг не надо улучшать Wiring. Требуется совершенно иной подход. |
04.07.2015, 14:57 | #28 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Так. Похоже это был какой-то глюк в моей среде 1.6.4 ... переставил себе заново эту версию и ... опаньки! Забыл переименовать wiring.c ... а оно возьми да и скомпиляйся без ошибок.
Похоже что библиотекарь таки работает "как и положено": подшивает то, что есть в файлах, если оно есть ИЛИ берет из библиотеки core.a если его нет.. Существенно меняет ситуацию: можно НЕ переименовывать ничего... и даже с main.cpp "поиздеваться вдоволь". поправил первый пост. |
06.07.2015, 10:36 | #29 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Допилил замер длительности импульса через прерывания PCINT2 ... возник вопрос с таймаутами, ибо датчик в реальности вполне себе может срабатывать "через раз":
Сделал расширение к обработчику таймера, которое смотрит наличие включенных таймаутов и если они есть и "наступило время" - косвенно вызывает заданную процедуру обработки таймаута. К сожалению, поскольку таймер включен по определению, теперь обработчик требует наличия структуры данных по таймаутам ... а там пока массив на 8 событий... "итого" - около 60 байт оперативы. Это - плохо? Переходить на стандартные "очереди" на указателях и malloc()? Насколько "опасно" вызывать процедуры таймаутов из обработчика прерывания по таймеру (активизируется примерно каждую миллисекунду, пашет с закрытыми прерываниями "по определению") ... не получится так, что пачка возникших таймаутов заломает всю обработку прерывания? Есть решения лучше? |
21.07.2015, 07:18 | #30 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Часть библиотеки для "автоматного программирования":
Код:
// ==================== то, что должно было быть определено в 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, скетч, ардуино |
Здесь присутствуют: 7 (пользователей: 0 , гостей: 7) | |
|
|