Вопрос касательно быстрой остановки счетчика прерываний
- Войдите на сайт для отправки комментариев
Здравствуйте.
Здесь уже не раз обсуждались счетчики, однако я не совсем понял один момент:
возьмем простой пример
volatile int a = 0; // переменная int b = 500; // нужное число импульсов pinMode(3,INPUT); // нужный пин void setup() { pinMode(13,OUTPUT);
digitalWrite(13,1);
attachInterrupt(1, imp_detect, RISING); } void loop() { if (a >= b) { digitalWrite(13,0); a = 0; } } void imp_detect() { a++; }
тут вроде бы все просто и диод погаснет отсчитав нужное кол-во импульсов, ОДНАКО если код значительно больше и в тушке loop куча всего - учитывая это разве погаснет диод в нужное время ?
быть может проверку кол-ва и выключение диода можно как то переместить в функцию прерывания ?
Меня это интересует так как возникла необходимость написать программу для работы мотора, которая бы включала его при определенном событии и отключала бы при достижении заданного кол-ва пройденных оборотов, которые подсчитываются при помощи прерывания.
Код у меня получается довольно большой, а учитывая большую скорость оборотов мотора я боюсь прогадать
извините код коряво вставился
Для начала нужно понять, что "одновременно" и "в тот же момент" и "нужное время" - это исключительно человеческие фантазии. Оперируйте временем, в течении которого должно совершиться действие. Вполне может статься, что частота поступления импульсов меньше, чем частота прохождения loop().
И, да, дернуть за ногу вполне себе можно и в прерывании. Конечно это займет определенное время и часть импульсов будет утеряна. Чтобы уменьшить потерю - дергать за пин стоит напрямую через регистры.
И, да, дернуть за ногу вполне себе можно и в прерывании.
подскажите как это называется правильно (название команд) - я пробовал в теле прерывания использовать if и while но не получилось
Прерывание потому и называется прерыванием, потому что за время порядка микросекунды прерывает выполнение программы. Тут главное долго в нём не сидеть и выходить до того, как оно сработает снова. Все команды в прерывании работают штатно. От длины основной программы не зависит, но только если в основной программе на долго не запрещаются прерывания. Приведите пример программы которая не получилась и что конкретно не получилось?
И, да, дернуть за ногу вполне себе можно и в прерывании.
подскажите как это называется правильно (название команд) - я пробовал в теле прерывания использовать if и while но не получилось
В смысле не получилось? Должно получиться! Попробуйте b сделать константой, или именованной константой. А в теле обработчика поставьте условие if(a>b)PORTD=0b1000000;//включили7пин порта D.
...
Я не знаю что произошло, однако сегодня действительно получилось - буквально пару дней назад я пробовал по всякому подставлять IF в функцию прерывания (также пробовал и различные другие методы которые приходили в голову) но программа просто "зависала" после одного прохода, а сегодня бац и заработало.
не долго я радовался - дома на макетке все было норм но приехал на работу и подключил к бандуре и получил пшик.
проблема та же - мотор не останавливается в нужный момент.
пожалуйста посмотрите мой код - быть может я допустил нелепую ошибку:
что собственно происходит не так как задумывалось - мотор зачастую останавливается в разное время.
ставлю я к примеру значение при котором должно произойти отключение равным 10 - но наглядно видно что кусок бумаги (а мотор крути валы что тянут бумагу) то проезжает 5 мм, то 15, то еще сколько то - и это при довольно таки низких оборотак мотора
если же повысить скорость мотора то бумага может уехать вообще на несколько см, хотя в теории скорость оборотов не должна влиять на то сколько пройдет этих оборотов до отключения мотора
вот как выглядет самодельный энкодер (датчик Sharp - дребезга нет)
В перрывании Вы используете menu, но не объявили её volatile.
Никто не знает, чему у Вас равна datak в момент работы с прерыванием, если недавно отработала строка 137 (datak = 0;), то условие в прерывании не выполнится никогда.
Вообще, код слшком велик и "расхристан" для поиска таких тонких ляпов. Такой огромный код Вы не отладите. Сделайте так:
1. Из кода выбросьте всё. При это всё означает ВСЁ.
2. Оставьте константные (просто присваиниваем) переменные datak и kol.
3. В setup включите Ваш двигатель и откройте прерывание.
Больше в коде не должно быть ничего, от слова совсем. Хотя, нет, можете вставить в loop печать в сериал значения kol, чтобы видеть, как она меняется при оборотах.
Добейтесь, чтобы Ваш двигатель останавливался и только потом вставляйте то, что получилось, в большой код.
до действительно про меню забыл, а про datak - там значение есть всегда отличное от 0, разве что кто то спец внесет изменение
datak - там значение есть всегда отличное от 0,
Если выполнится строка 137, то оно станет 0
В любом случаем, сделайте как я сказал. Если на простейшем коде не будет работать, ищем аппаратные проблемы (например, прерывание может вадисть в больших количествах при работе двигателя). А если будет работать надёжно, то смотрим на остальной код.
Только печатайте в loop свою kol, чтобы видеть как часто прерывания валятся.