Отлавливание счетчика.
- Войдите на сайт для отправки комментариев
Пт, 29/04/2016 - 20:30
Всем привет. Данная тема уже обсуждалось много уже где. Поэтому прошу прощкния за повторения. Но немогу разобраться в таймерах. Очень много источников перелопатил. Но всеже решил спросить у месных гуру. Прошу снисхождения к малоопытному (или совсем безопытному, смотря с кем сравнить). Вопрос такой: имеется внешнее прерывание. В его функции счетчик. Есть также диод, который нужно зажеч на N мс при достижении этого счетчика значения M.
volatile int i=0; void setup() { pinMode(13, OUTPUT); attachInterrupt(0, Schet, RISING); } void loop() { if(i=14) { digitalWrite(13, HIGH); delay(2)//или ожидание через милис digitalWrite(13, LOW); } } void Schet() { i++; if (i=68) {i=0;} }
Очень важно не пропустить когда i=N так как диодов 9 штук. И у каждого свое N :) Можно ли сделать это не используя цикл loop или же есть какие то другие пути? Может где то неправильно изъяснился прошу меня извинить уже каша в голове путаться стал:)
Что по Вашему делает строка 22?
По-моему она ВСЕГДА обнуляет перемнную i.
Исправьте опечатку и всё заработает.
Извиняюсь это тут опечатка код вручную писал не копипаст:) в 22 строке конешноже двойное равно:)
А в 11-й?
Также двойное. Суть в том что 9 диодов при повышении частоты прерываний начинают пропускаться. Как побороть этот ньюанс? Диумал использовать может непосредственно таймеры. Но вопрос как...
Также двойное. Суть в том что 9 диодов при повышении частоты прерываний начинают пропускаться. Как побороть этот ньюанс? Диумал использовать может непосредственно таймеры. Но вопрос как...
Включать необходимо рядом с обнулением i в прерывании, и там же ставить время включения, а в цикле выключать, если время+сколько надо достигнуто.
Скорее всего, дребезг контактов крутит Ваши счётчики сильно быстро, а на каждом из 9-ти светодиодов у Вас по delay() тупит. Кстати, Вы думаете сверкнувший 2мс светодиод будет заметен?
Это малый пример моей програмки, показывающий алгоритм который я использую. Импульсы идут от индуктивного датчика и реперного диска на валу. На реперном диске 32 метки. При вращении вала свыше 2000 начинаются пропуски. Загружать прерывание тоже нельзя изза его частоты.
2000 чего? Оборотов в минуту? Так это мелочи. При такой скорости вращения 2000/60*32=1066 прерываний в секунду.
Там у Вас показан не алгоритм, а, простите, неверный подход. :) Нельзя надеяться на асинрхронное (в одном месте меняем, в другом проверяем) отлавливание значения переменной в некоторой точке. Можно с дрейфом обнаружить завершение отсчёта, который останавливается. Там, где переменная изменяется, и надо проверять её значение. А далее либо выставлять флаг, либо генерировать событие, либо выполнять действие непосредственно.
именно оборотов в минуту:) согласен подход неверный - поэтому я здесь. Добрался наконец до компа вот полный код програмки.
немного поподробней можно про ваши варианты? малость не уловил)
именно оборотов в минуту:) согласен подход неверный - поэтому я здесь. Добрался наконец до компа вот полный код програмки.
немного поподробней можно про ваши варианты? малость не уловил)
Простите, изучать и корректировать Ваш код нет возможности. Вариант в том, чтобы тот, кто изменяет значение переменной и тут же проверял, выставляя флаг, наприммер. В другой части программы проверяется этот флаг, если поднят, сбрасывается и выполняется необходимое действие. Сброс флага может быть и после выполнения действия - зависит о желаемой фазы.
А не получится что проверка флага выйдет тож самое что и проверка переменной?
А не получится что проверка флага выйдет тож самое что и проверка переменной?
Флаг - это тригер: его одним сигналом устатавливают (в одном месте), другим сигналом сбрасывают (в другом месте). Для того флаги и придумали, потому они и флагами называются, иногда семафорами. Счётчик может тоже быть флагом, но лишь в том случае, если у его есть некотрый барьер, показывающий зашкалиивание и останавливающий изменение счётчика.
Видимо я думаю моленько о другом. Можно простенький пример с флагом?
В обработчике прерывания:
В теле программы:
В обработчике прерывания:
В теле программы:
Ну пропустить то он точно не пропустит согласен:) но он так же не успеет отработать в нужный момент.... какже быть то?
Включать необходимо рядом с обнулением i в прерывании, и там же ставить время включения, а в цикле выключать, если время+сколько надо достигнуто.
Скорее всего, дребезг контактов крутит Ваши счётчики сильно быстро, а на каждом из 9-ти светодиодов у Вас по delay() тупит. Кстати, Вы думаете сверкнувший 2мс светодиод будет заметен?
А ведь действительно же лучше будет. Неправильно вас сначало понял:) Попробую таким методом.
В обработчике прерывания:
В теле программы:
Ну пропустить то он точно не пропустит согласен:) но он так же не успеет отработать в нужный момент.... какже быть то?
Если это очень критично, тут же на месте в прерывании выполнять действия. Суть в том, что прерывания могут работать рекурсивно. Грубо говоря, если Вы зависли в прерывании и ходите в нём долго покуралесить, вполне допустимо разрешить прерывания внутри обработчика, но использовать флаг т.с. занятости чтобы до завершения некоторого действия прерываения работали, крутился счётчик и всё остальное внутри прерывания, но не вызывался обработчик рекурсивно.
В прерывании:
прерывания могут работать рекурсивно.
Ох, faeton, "не надо бы вслух, ох, не надо бы". Эта техника для профессионалов или хотя бы продвинутых любителей, но никак не для новичков. Парень сейчас нворотит чего-нибудь, что будет "вроде бы работать", а потом месяцами будет глюки ловить.