Прерывание, LowPower - не могу понять в чем проблема
- Войдите на сайт для отправки комментариев
По таймеру хочу уходить в сон
https://github.com/rocketscream/Low-Power
Moderator : пожалуйста, вставьте код правильно (возможно, новым сообщением в тему),
Вроде все правильно. WakeUp отменяет прерывание и включает диоды. Потом они тухнут. И все работает.
Но к 2 пину прерывания WakeUpPin привязана сенсорная кнопка, которая будит. И по идее она должна не только запускать, но и засыпать устройство раньше таймера если надо.
Moderator : пожалуйста, вставьте код правильно (возможно, новым сообщением в тему),
Кнопка просто ускоряет таймер для ReadyToPowerSafe и там еще 2 секунды запаса. Но когда время истекает устройство зависает. Все индикаторы включаются, словно прерывание сработало, но больше не реагирует вообще. Хотя кнопка WakeUpPin выключена в момент attachInterrupt и LowPower.powerDown.
Почему работает по разному с ускорения кнопки и с полного таймера? Ведь это же один и тот же код. Откуда прерывание берется если кнопка не нажата? И почему может все зависать?
Почему не выходит из powerDown? Или выходит, ведь индикаторы загораются?
Кода никто не видел, а потому, Бог его знает, что Вы там навертели.
только КОД НУЖЕН ВАШ (для особо непонятливых - ВАШ - ЭТО ВЗЯТЫЙ ИЗ ВАШЕГО ИДЕ, А НЕ ЧУЖОГО САЙТА, даже, если Вы там ну, совсем ничего не меняли).
Хорошо, вот простая версия кода.
Спустя 5 секунд устройство засыпает (не мигает LED_BUILTIN), просыпается кнопкой (мигает LED_BUILTIN), мгновенно загорается в ISR WakeUp и гаснет на выходе дополнительный диод в ReadyToPowerSafe.
Но при включенном устройстве щелчок на кнопке загоняет устройство в постоянно горящий доп. диод. Значит программа не выходит из ReadyToPowerSafe.
Я так понимаю - после кнопки attachInterrupt сразу ловит прерывание чтоли... Но в чем разница КОД ЖЕ ОДИНАКОВЫЙ? А кнопка отжата, т.е и условия такие же.
Я добавил мигалку после назначения IRQ
И получается словно прерывание тут же срабатывает, потом мигает LED_BUILTIN и потом удачно засыпает. Так откуда оно берется то? нет же никаких RISING!
Я даже осциллографом посмотрел! Нажатие кнопки вижу, а больше ничего там нет - ни шума ни помех!
По поводу "дребезга", наводок, антен и прочего. У этих модулей дребезга быть не должно. Но я все равно проверил! Нет ложных срабатываний.
Давайте не будем плодить сущности и оснавимся на коде из #2
Вы постоянно забываете, что пишете для людей, которые не в курсе Ваших мыслей и прочих наработок. Вы написали как оно себя ведёт, правда не очень понятно (например, что такое "дополнительный диод" - называйте номера пинов, если уж схемы нет - откуда кому знать какой диод у Вас основной, а какой - дополнительный).
Но Вы не написали, что Вы хотели сделать.
Описание должно быть таким
1. Что хотел получить
2. Что получил
3. Чем конкретно №1 отличается от №2.
Да писал я все это еще в первом посте. Короче, я разобрался. Дело в отложенных pending прерываниях, которые запоминаются где-то в регистрах МК и срабатывают сразу при назначении.
Кто-нибудь знает правильный способ сброса такого прерывания?
Пока я просто ограничился таким.
attachInterrupt(digitalPinToInterrupt(WakeUpPin), WakeUpDummy, RISING );
detachInterrupt(digitalPinToInterrupt(WakeUpPin));
attachInterrupt(digitalPinToInterrupt(WakeUpPin), WakeUp, RISING );
void WakeUpDummy() {}
Сначала срабатывает пустая функция WakeUpDummy, она просто снимает флаг пропущенного прерывания с пина самим фактом своего запуска. А потом уже назначаю нормальную.
Это?
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf
12.2.3 EIFR – External Interrupt Flag Register
Я не знаю, это ж песочница для новичков. А что с ним делать? В инете ничего не найти, везде только аттач и детач обсуждают либо помехи 220. Только одну статью про pending и удалось найти. Хорошо хоть там сказали, что прервания так в "буфере" висят.
Как то это тупо - назначаешь прерывание и оно ловится тем, что было пару секунд назад... Разве аттач не должен делать сброс старого для актуальность?
Я не знаю, это ж песочница для новичков.
А работа с прерываниями, увы - не для новичков и не для песочницы :(
Разве аттач не должен делать сброс старого для актуальность?
В его описании это прописано? Если нет, то непонятно, кому и за что он мог так задолжать :-)
EIFR |= (1 << INTF0);
Вот команда для сброса. Подробное описание почему именно так:
https://forum.arduino.cc/index.php?topic=59217.msg426522#msg426522
или по русски:
Что-то в программе должно знать, что эти флаги должны быть установлены до того, как вы подключите обработчик прерывания. Например, для прерывания по фронту или спаду на выводе D2 можно установить соответствующий флаг и, как только, вы вызовете функцию attachInterrupt прерывание возникает немедленно, даже если событие произошло час назад. Чтобы избежать этого, вы можете вручную сбросить флаг.
http://robotosha.ru/arduino/arduino-interrupts.html
так понял, что дело в том, что
void
WakeUp() не обрабатывает дребезг кнопки.
Вообще не о том. Я уже писал - 1 у них нет дребезга. И даже если бы он был: 2 в момент срабатывания кнопка вообще не трогается.
я вот про это
Но при включенном устройстве щелчок на кнопке загоняет устройство в постоянно горящий доп. диод. Значит программа не выходит из ReadyToPowerSafe.
доп диод этот? digitalWrite(A1, HIGH);
Про EIFR на нашем форуме уже были дискуссии на тему как правильно сбросить.