Для функции Loop для итерации выходов после прерывания

interrupt 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);
      }
}

, 👍1

Обсуждение

Ваше описание проблемы немного непонятно. Что вы ожидали от кода и что он сделал вместо этого? Также: myIteration() никогда не вызывается. Также он не изменит глобальную переменную thisPin, так как использует собственную локальную переменную с таким именем., @chrisl

Почему у вас есть два непосредственно последовательных теста для if (state==HIGH)? Разве нельзя? Плюс то, что сказал Крисл., @Nick Gammon

Я использую два последовательных теста для if (state==HIGH), потому что, когда я этого не делаю, светодиод отладки остается включенным во время сна. Спасибо за подсказку о глобальной переменной. Я отредактировал исходный пост. Мои функции итерации все еще не повторяются, код запускает только инициализированное значение на выводе 4., @chirp84

Почему вы считаете от 4 до 9, когда ваш массив «musicPins» содержит только 8 элементов? И вы намеревались пропустить первые 4 элемента при этом? С этим контактом 4 никогда не изменится. Вместо этого считайте от 0 до 7, @chrisl

Спасибо, массив действительно был неверным. Я исправил это как количество элементов в массиве, а не номера выводов. Мне также нужно было увеличивать значение внутри основного цикла, прежде чем прикреплять прерывание. Исходный пост отредактирован с окончательной рабочей версией., @chirp84


1 ответ


1

Исходный код обновлен окончательной версией. Прерывание от обнаружения движения повторяется по нескольким выходным контактам воспроизведения голоса и переходит в спящий режим с низким энергопотреблением на оставшееся время.

,

Я не понимаю этого "ответа". Stack Exchange — это не форум. Вы хотите сказать, что проблема решена? Если да, то каким образом? Если нет, отредактируйте свой вопрос, чтобы уточнить, не используйте ответ, чтобы уточнить вопрос., @Nick Gammon