Для функции Loop для итерации выходов после прерывания
Мне нужна помощь в непрерывном циклическом переключении моих выходных контактов после каждого цикла сна. Я пытаюсь увеличить каждый выходной контакт во время каждого последующего прерывания. Введение этой функции myIteration вызывает немедленное увеличение до конечного выходного вывода и устраняет спящий режим.
ОБНОВЛЕНИЕ Чтобы немного прояснить и очистить код, у меня возникают проблемы с увеличением цикла по выходным контактам каждый раз, когда запускается прерывание. Он остается на инициализированном значении вывода после каждого прерывания.
Причина, по которой я разделяю if (state=HIGH) на два последовательных оператора, заключается в том, что когда я этого не делаю, индикатор отладки остается включенным.
#include <LowPower.h>
const byte interrupt_pin = 2; // объявляем вывод прерывания для триггера PIR
int musicPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11}; // Инициализировать пины, которые воспроизводят музыку в массиве, элементы от 0 до 8
volatile byte state = LOW; // порог срабатывания начинается с низкого уровня
int pinCount = 9;
int previous = 0;
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // используем встроенный светодиод для отладки
pinMode(interrupt_pin, INPUT); // установить вывод прерывания в качестве входа
for (int thisPin = 0; thisPin < pinCount; thisPin++) { // установим для всех музыкальных контактов значение High, чтобы во время инициализации сенсора не было музыки
digitalWrite(musicPins[thisPin], HIGH);
}
for (int thisPin = 0; thisPin < pinCount; thisPin++) { // устанавливаем все музыкальные выводы в качестве выходов
pinMode(musicPins[thisPin], OUTPUT);
}
delay(5000); // ждем, пока датчик сможет инициализироваться
}
void loop() {
attachInterrupt(digitalPinToInterrupt(interrupt_pin),interrupt_routine,RISING); // необходимо присоединить каждый цикл
LowPower.powerDown(SLEEP_FOREVER,ADC_OFF,BOD_OFF); // MCU бездействует до прерывания
detachInterrupt(digitalPinToInterrupt(interrupt_pin)); // удалить прерывание
if (previous==10){ // когда переменная становится равной 10, обнуляется
previous=0;
}
if (state==HIGH){ // ПИК обнаруживает движение, посылает сигнал высокого уровня
digitalWrite(LED_BUILTIN,HIGH); // загорается светодиод отладки
myOnIteration(); // включается номер музыкального контакта x
delay(100); // ждем стабилизации
digitalWrite(LED_BUILTIN,LOW); // светодиод отладки гаснет
}
if (state==HIGH){ // отдельные операторы, чтобы гарантировать выполнение следующих шагов
myOffIteration(); // musicPin номер x выключается
LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); // сон на 8 секунд после воспроизведения musicPin
}
previous++; // увеличение перед присоединением следующего прерывания
}
////////Функции//////////
void interrupt_routine(){
state = HIGH;
}
void myOnIteration() { // цикл по выходным контактам, включающимся один раз за каждое прерывание
for (int count = previous; count < pinCount; count++) {
digitalWrite(musicPins[count], LOW);
}
}
void myOffIteration() { // циклически отключаем выходные контакты один раз за каждое прерывание
for (int count = previous; count < pinCount; count++) {
digitalWrite(musicPins[count], HIGH);
}
}
@chirp84, 👍1
Обсуждение1 ответ
Исходный код обновлен окончательной версией. Прерывание от обнаружения движения повторяется по нескольким выходным контактам воспроизведения голоса и переходит в спящий режим с низким энергопотреблением на оставшееся время.
Я не понимаю этого "ответа". Stack Exchange — это не форум. Вы хотите сказать, что проблема решена? Если да, то каким образом? Если нет, отредактируйте свой вопрос, чтобы уточнить, не используйте ответ, чтобы уточнить вопрос., @Nick Gammon
- Передача переменных для PID в прерывании
- Получить сокет в цикле arduino (прервать цикл while с помощью сокета)
- Выполнение вычислений только по запросу через последовательный
- Использование millis() и micros() внутри процедуры прерывания
- Подсчет импульсов с прерыванием
- Устранение дребезга кнопки с помощью прерывания
- Программа arduino выдаёт ошибку expected //primary-expression before ')' token error: //expected ';' before '}' token E
- Почему необходимо использовать ключевое слово volatile для глобальных переменных при обработке прерываний в ардуино?
Ваше описание проблемы немного непонятно. Что вы ожидали от кода и что он сделал вместо этого? Также:
myIteration()
никогда не вызывается. Также он не изменит глобальную переменную thisPin, так как использует собственную локальную переменную с таким именем., @chrislПочему у вас есть два непосредственно последовательных теста для
if (state==HIGH)
? Разве нельзя? Плюс то, что сказал Крисл., @Nick GammonЯ использую два последовательных теста для
if (state==HIGH)
, потому что, когда я этого не делаю, светодиод отладки остается включенным во время сна. Спасибо за подсказку о глобальной переменной. Я отредактировал исходный пост. Мои функции итерации все еще не повторяются, код запускает только инициализированное значение на выводе 4., @chirp84Почему вы считаете от 4 до 9, когда ваш массив «musicPins» содержит только 8 элементов? И вы намеревались пропустить первые 4 элемента при этом? С этим контактом 4 никогда не изменится. Вместо этого считайте от 0 до 7, @chrisl
Спасибо, массив действительно был неверным. Я исправил это как количество элементов в массиве, а не номера выводов. Мне также нужно было увеличивать значение внутри основного цикла, прежде чем прикреплять прерывание. Исходный пост отредактирован с окончательной рабочей версией., @chirp84