Программа перестает работать
- Войдите на сайт для отправки комментариев
Сб, 23/02/2019 - 18:44
/*Код должен включать и выключать светодиод по двойному щелчку. Используется цифровой вывод микрофонного модуля. Проблема в том, что ВНЕЗАПНО, программа прекращает нормальную работу. Это начинает происходить спустя случайный промежуток времени, всегда разный. Перезагрузка помогает. ЧЯДНТ?*/ #define analogPin A0 #define digitalPin 2 #define led 4 void setup() { pinMode(analogPin, INPUT); pinMode(digitalPin, INPUT); pinMode(led, OUTPUT); Serial.begin(9600); attachInterrupt(0, Up , RISING); } volatile bool flag=0; volatile unsigned long timer=0; void Up(){ timer = millis() - timer; if(timer<4000&&timer>20){if (flag==0){ digitalWrite(led, HIGH); flag=1; }else{ digitalWrite(led, LOW); flag=0; } timer = 0; } } void loop() { }
Зарядите Serial на 115200 и после строки 22 временно поставьте Serial.println(timer);
Это, конечно, вызовет тошноту у программистов микроконтроллеров, но поможет понять, почему не выполняется условие.
Не понял.
Типы одинаковые.
Почему-то таймер не обнуляется.
Как заставить это работать?
Ну так оно работает, ровно так, как написано. В прерывании вы должны только проверить длительность и количество щелчков, и ничего другого. В лупе меняйте состояние выхода.
Не обнуляется потому что не попадает в условие. А как заставить... Ну, придётся еще подумать, не исключено, что найти другой алгоритм.
Ничего не выходит.
Можете помочь с кодом?
Ничего не выходит.
Покажите, как пытаетесь исправить.
Я бы попробывал замерить длительность сигнала с датчика, и на основании этого уже определять хлопки. Делать это конечно лучше таймером, а это тема довольно сложная, если вы новичок, то попробуйте для начала в loop'е это всё сделать, а в прерывании менять состоянии переменной, для отсчета времени. Не знаю, что за датчик, может надо применить не миллис а микрос
Ничего не выходит.
Можете помочь с кодом?
могу, только словами скажите, что хотите сделать, не увидел в коде двойного щелчка совсем
а вот так?
Проблема в том, что я не могу победить дребезг- не нашёл конденсатор, и теперь процесс поиска ошибок превращается в ад.
Хочу, чтобы при поступлении лог.1 за 4 секунды дважды, прерываясь, зажигался диод.
победить дребезг на прерывании не возможно, надо настраивать ваш аккустический датчик, чтобы дребезга не было
Какой дребезг? У вас там механические контакты? Если вы имеете ввиду шум, то, ещё раз повторяю, меряйте длительность шума, потом тишину, опять шум, и если попал подходящий вам интервал, включайте/выключайте свой выход. Если датчик постоянно вам посылает помехи на порт, то без дополнительных элементов не добиться стабильной работы.
Я менял, не помогает.
Внутри функции обработки прерывания не работает delay(), значения возвращаемые millis() не изменяются. Возможна потеря данный передаваемых по последовательному соединению (Serial data) в момент выполнения функциии обработки прерывания. Переменные, изменяемые в функции, должным быть объявлены как volatile.
Ну да, я там все без задержек написал.
С переменными вчера разобрался.
Возможно такое, что, если отключить сериал, она заработает нормально?
нет, логика не соответствует требуемой, начните с моего скетча, где отрабатывается два щелчка
Отключил сериал, стабильность работы стала лучше, но программа снова не работает.
Как найти этот скетч?
ННП НФВКЩИС.
И, да, как исправить ошибку я уже написал в #17, а ещё есть замечание по объёму кода.
Вот эта конструкция
легко заменяется на существенно более короткую и прозрачную
несколько спорное утверждение
несколько спорное утверждение
ну так совсем ничего невозможного нет...
интересна Ваша мысль, как будете отличать дребезг от недребезга изменение сигнала вызвавшего прерывание
несколько спорное утверждение
Не "несколько", а на полноценный холивар в котором все будут правы :)
зы. ua6em, чуть позже отвечу. некогда щас
несколько спорное утверждение
Не "несколько", а на полноценный холивар в котором все будут правы :)
мои компетенции говорят о том, что срани в аппаратных прерываниях быть не должно, зачищать надо на аппаратном уровне...иное, попытка переложить ответственность за кривые руки разработчика на программиста )))
Антидребезг в прерывании - Может так
А если дребезга нет, то как будет второй раз вызван butDreb() и выставлен kn = 1?
Вернусь к этому как-нибудь потом.
Когда достану конденсатор.
Спасибо всем, кто пытался помочь, но мой говнокод на 2й день не читается.
Кто его писал?
А если дребезга нет, то как будет второй раз вызван butDreb() и выставлен kn = 1?
Если был клик то будет и единица
Ну а обработку проведем в лооп и сбросим в 0
в прерывании 24 строка не сработает, милис загрузить получится, но его значение до выхода из прерывания изменятся не будет.
недавно здесь описыал рабочий алгоритм одного из вариантов антидребезга с прерыванием
http://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/obrabotka-knopki-na-preryvaniipower-down-mode-gde-oshibka#comment-432995
ua6em, вроде недавно искал и использовал для энкодера код от Димакса, (ежели память е изменяет), я его тоже тестил с год назад, но то ли у меня больно глючный энк. попался, то еще хз что, но пропуски и ошибки с тем кодом были. В результате написал такой, и он меня вполне устроил. конденсаторы ко все пинам энка по 0,1 мкф, подтяжка может быть только внутренними резисторами ардуины на голом энке.
Вернусь к этому как-нибудь потом.
Когда достану конденсатор.
Спасибо всем, кто пытался помочь, но мой говнокод на 2й день не читается.
Кто его писал?
И что? код из поста #16 не работает?
Пороюсь найду датчик, сам проверю )))
...а то как в призказке...пиво без водки деньги на ветер )))
Вернусь к этому как-нибудь потом.
Когда достану конденсатор.
Спасибо всем, кто пытался помочь, но мой говнокод на 2й день не читается.
Кто его писал?
И что? код из поста #16 не работает?
Пороюсь найду датчик, сам проверю )))
...а то как в призказке...пиво без водки деньги на ветер )))
Он работает, но тоже с дебезгом, если подуть - мигает.
Однако, целью было не заставить его работать, а понять, почему условие моего кода не выполняется.
Вернусь к этому как-нибудь потом.
Когда достану конденсатор.
Спасибо всем, кто пытался помочь, но мой говнокод на 2й день не читается.
Кто его писал?
И что? код из поста #16 не работает?
Пороюсь найду датчик, сам проверю )))
...а то как в призказке...пиво без водки деньги на ветер )))
Подуть это у ДПС, настраивайте на хлопок руками )))
Он работает так, как написали, а задумывали, так как написано у меня ...
Зарядите Serial на 115200 и после строки 22 временно поставьте Serial.println(timer);
Это, конечно, вызовет тошноту у программистов микроконтроллеров, но поможет понять, почему не выполняется условие.
это и так понятно, если после первого включения до срабатывания прерывания прошло более 4 секунд код никогда не выполнится
в прерывании 24 строка не сработает, милис загрузить получится, но его значение до выхода из прерывания изменятся не будет.
согласен, невнимательно посмотрел, сорри =)
но тоже обработка со своими нюансами.
В таком случае это не столько защита от дребезга, сколько определение клика. Потому что просто push оно ловить не сможет.
не может + там множественный вызов прерывания в случае дребезга
7/8 предыдущео поста стер, чтобы не влезать во все эти хреновы тонкости, бо и так понятно, что где-то такой вариант годится, а где-то нет.
почему тему про се ЕвгенийП и обозвал -холиваром
Ну я так и написал в #27 что это клик, а если надо удержание и клик то надо добавить еще одну переменную. Например так
можно конечно и дребезг обработать, то-есть все прерывния после первого во временном промежутке до 20 миллисекунд считать за дребезг, а именно при первом прерывании запоминать миллис и выставлять флаг, за второй хлопок считать прерывание поступившее за пределом этого временного отрезка, но правильнее сделать датчик без дребезга... #16