Там же есть режим, когда прерывание возникает по любому фронту. А в прерывании определяете состояние пина, запоминаете время и ставите флаг для обработки в основном цикле. Попробуйте логику типа такой: Код (C++): bool btnPressed = false; bool btnReleased = false; long pressTime, releaseTime; interrupt() { if(digitalRead(...) == true) { btnPressed = true; btnReleased = false; pressTime = millis(); } else { btnReleased = true; releaseTime = millis(); } } void loop() { if(btnPressed && btnReleased) { long time = releaseTime - pressTime; btnPressed = false; btnReleased = false; ... } }
Теоретически можно. Адрес, с которого должно продолжится выполнение программы после выхода из обработчика прерывания, хранится в стеке. Если этот адрес подменить на адрес функции loop(), то после выхода из обработчика прерывания, выполнение продолжится с начала функции loop(). Но изменяя содержимого стека, Вы должны чётко понимать, что делаете.
очень бы не советовал так делать, тем более начинающим. Дейстра бы такой совет не одобрил бы. Лучше хорошенько подумать над структурой алгоритма без подмены значений программного счетчика.
рационально подумать над структурой алгоритма, а долгие вычисления разбивать на фрагменты, ну вроде как распараллеливать по времени, чтобы время прокрутки цикла loop() не было большим. Хотя я не могу представить себе, что такое можно делать десять миллисекунд? FFt разве что. И возвращение в начало должно быть структурировано - что там в регистрах, когда вы насильно подменяете программный счетчи?
Подниму тему. Интересует все же использование delay() в функции аппаратного прерывания. Что ж... чтоб вы товарищи телепаты не гадали что и зачем мне это - расскажу про свой проект: Суть в том что я хочу включать комп не кнопкой большим пальцем ноги, а тумблером на три положения on-off-on ( чтобы включить или выключить, мне нужно тумблер из одного крайнего положения перещелкнуть в другое, для имитации длительного нажатия - поставить и удерживать тумблер в среднем положении), для этого планировал к штырям материнки запаралелиться с помощью npn транзистора или оптопары. И вот сама проблема в том что мне необходимо подать импульс 0.1 с, а как сделать это без delay() я незнаю. Ниже недописанный кусок моего кода: Код (C++): #define SER 11 #define LATCH 10 #define CLK 9 #define POW_LED 13 #define FLASH_LED 12 #define TO_MOTHER_BOARD 8 unsigned int vals[12] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047}; void setup() { pinMode(TO_MOTHER_BOARD, OUTPUT); // на мать импульс pinMode(FLASH_LED, OUTPUT);// синхронизирован с исмпульсом на мать pinMode(POW_LED, OUTPUT); // есть питание pinMode(SER, OUTPUT); pinMode(LATCH, OUTPUT); pinMode(CLK, OUTPUT); attachInterrupt(0, tumbler, FALLING);//либо FALLING либо LOW для экстр выключения } void tumbler() { // СПАСАТЬ ЗДЕСЬ Т_Т digitalWrite(TO_MOTHER_BOARD, HIGH); digitalWrite(FLASH_LED, HIGH); delay(100); digitalWrite(TO_MOTHER_BOARD, LOW); digitalWrite(FLASH_LED, LOW); } void loop() { //в лупе у нас гистограмный индикатор на 12 диодов через 2 74hc595 int pot = analogRead(0); pot = constrain(pot, 5, 1000); pot = map(pot, 5, 1000, 0, 11); digitalWrite(LATCH, LOW);//низкий - начало отправки shiftOut(SER, CLK, MSBFIRST, highByte(vals[pot])); shiftOut(SER, CLK, MSBFIRST, lowByte(vals[pot])); digitalWrite(LATCH, HIGH); delay(100); } По схеме: второй пин моей мини про прижат к земле через 10к резистор, в положении тумблера ON на порт идет HIGH c 5 вольт, питание буду брать с разьема молекса блока питания
Ты используй прерывания со второго таймера, а внутри них delay(), так как эта функция прерывания с 1 таймера работает)
использовать delay() внутри прерывания нельзя, если это не 1-2 мкс конечно. arduino ide- file- примеры- ...blink без delya и будет вам щастье.
Тогда можно сделать два разных прерывания на RISING и на FALLING, в RISING запоминать millis(), а в FALLING тоже брать millis() и заносить в переменную разность нового и старого millis(). А после обработки этой разности в основной программе обнулять эту переменную.