1

I would like help to continuously loop over my output pins after each sleep cycle. I am trying to increment through each output pin during each successive interrupt. Introducing this myIteration function causes immediate incrementing to final output pin and eliminates sleeping.

EDIT To clarify a bit and clean up the code, I am having trouble getting the loop to increment over the output pins each time the interrupt is triggered. It stays on the initialized pin value after each interrupt.

The reason I separate the if (state=HIGH) into two consecutive statements is because when I do not the debug LED remains on.

#include <LowPower.h>

const byte interrupt_pin = 2;                             // declare interrupt pin for PIR trigger
int musicPins[] = {3, 4, 5, 6, 7, 8, 9, 10, 11};          // Initialize pins that play music in array, elements from 0 to 8
volatile byte state = LOW;                                // trigger threshold starts low
int pinCount = 9;
int previous = 0;

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);                           // use builtin LED for debug
  pinMode(interrupt_pin, INPUT);                          // set interrupt pin as input
    
    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as High to start with no music during sensor initialization
    digitalWrite(musicPins[thisPin], HIGH);
    }
    for (int thisPin = 0; thisPin < pinCount; thisPin++) {      // set all music pins as outputs
    pinMode(musicPins[thisPin], OUTPUT);
    }
    
  delay(5000);                                            // wait so sensor can initialize
}

void loop() {

  attachInterrupt(digitalPinToInterrupt(interrupt_pin),interrupt_routine,RISING); // must attach each loop
  LowPower.powerDown(SLEEP_FOREVER,ADC_OFF,BOD_OFF);      // MCU sleep until interrupt
  detachInterrupt(digitalPinToInterrupt(interrupt_pin));  // remove interrupt

  if (previous==10){                                      // when variable gets to 10 reset to zero
    previous=0;
  }
  
  if (state==HIGH){                                       // PIR senses motion, sends high signal
    digitalWrite(LED_BUILTIN,HIGH);                       // debug LED turns on
    myOnIteration();                                      // musicPin number x turns on
    delay(100);                                           // wait to stabilize
    digitalWrite(LED_BUILTIN,LOW);                        // debug LED turns off
  }
  if (state==HIGH){                                       // separate statements to guarantee next steps happen 
    myOffIteration();                                     // musicPin number x turns off
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);       // sleep for 8s after musicPin plays

  }

  previous++;                                             // increment before attaching next interrupt
 
}


////////Functions//////////
void interrupt_routine(){
  state = HIGH;
}

void myOnIteration() {                                    // cycle through output pins turning on once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], LOW);
      }
}

void myOffIteration() {                                   // cycle through output pins turning off once per interrupt
for (int count = previous; count < pinCount; count++) {
        digitalWrite(musicPins[count], HIGH);
      }
}
5
  • 1
    Your problem description is a bit unclear. What did you expect the code to do and what did it actually do instead? Also: myIteration() is never called. Also it wouldn't change the global thisPin variable, since it uses it's own local variable with that name. – chrisl Sep 14 '20 at 8:09
  • 1
    Why do you have two directly consecutive tests for if (state==HIGH)? Wouldn't one do? Plus what chrisl said. – Nick Gammon Sep 14 '20 at 9:04
  • I use two consecutive test for if (state==HIGH) because when I do not the debug LED remains on during sleep. Thanks for the pointer about global variable. I've edited the original post. My iteration functions are still not iterating, the code runs only the initialized value at pin 4. – chirp84 Sep 15 '20 at 2:52
  • Why are you counting from 4 to 9, when your musicPins array has only has 8 elements? And did you intent to skip the first 4 elements with that? With that pin 4 will never change. Count from 0 to 7 instead – chrisl Sep 15 '20 at 18:14
  • Thanks, the array was indeed incorrect. I've fixed it to be the number of elements in the array and not the pin numbers. I also needed to be incrementing inside the main loop before attaching the interrupt. The original post is edited with final working version. – chirp84 Sep 18 '20 at 6:05
1

Original code is updated with final version. A motion sensing interrupt iterates over multiple voice playback output pins and sleeps at low power for rest of time.

1
  • I don't understand this "answer". Stack Exchange is not a forum. Are you saying the problem is fixed? If so, in what way? If not, please edit your question to elaborate, don't use an answer to clarify the question. – Nick Gammon Sep 18 '20 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.