0

I have a for loop inside my void loop() that triggers a piezo.

What I want to happen is when I press a button, it breaks the loop of the piezo, but right now, it's as if it isn't detecting the button press inside my for loop.

Here's my code:

#include <Adafruit_NeoPixel.h>

#define PIN 6
#define TONE 8
const int buttonPin = 2;

long fadeTime = 5 * 1000L; // X minutes
int colorStops = 256;
int delaySpeed = fadeTime / colorStops;
int notes[] = {262,294,330,349};
int switchState = 0;         // variable for reading the pushbutton status

Adafruit_NeoPixel strip = Adafruit_NeoPixel(5, PIN, NEO_RGB);

void setup() {
  pinMode(buttonPin, INPUT); // initialize the pushbutton pin as an input

  strip.begin();
  strip.show();
}

void loop() {
  // read the state of the pushbutton value:
  switchState = digitalRead(buttonPin);

  // Fade in light
  for(int i = 1; i<colorStops; i++){
    for(int np = 0;np<strip.numPixels(); np++){
      strip.setPixelColor(np, strip.Color(i,i,0));
    }
    strip.show();
    delay(delaySpeed);
  }

  // Play tone after light fully bright
  for(int i = 1; i<100; i++){
    // Turn off tone on button press
    if (switchState == HIGH) {
      noTone(TONE);
      break;
    }
    tone(TONE, notes[random(0,3)]);
    delay(100);
  }
}

Does switchState = digitalRead(buttonPin); only get called at the start of the void loop and so it can't detect the button change until then? Something else?

Also, in case it's useful, here's my hardware set up...

enter image description here

3
  • That'll be because you're not reading the button inside the for loop?
    – Majenko
    Mar 18, 2016 at 20:28
  • @Majenko Does switchState not just call digitalRead(buttonPin)?
    – Shpigford
    Mar 18, 2016 at 20:30
  • 1
    No. switchState is assigned the results of performing digitalRead(buttonPin) at the time it is called - i.e., at the top of loop().
    – Majenko
    Mar 18, 2016 at 20:31

1 Answer 1

1

You aren't reading the state of the button within your loop.

You only read it the once at the top of your loop():

void loop() {
  // read the state of the pushbutton value:
  switchState = digitalRead(buttonPin);

You need to replicate that every time you want a new reading from the button - so in your loop you need to add that digitalRead line:

// Play tone after light fully bright
for(int i = 1; i<100; i++){
  // Turn off tone on button press
  switchState = digitalRead(buttonPin);
  if (switchState == HIGH) {
    noTone(TONE);
    break;
  }
  tone(TONE, notes[random(0,3)]);
  delay(100);
}

Or you can do away with the variable altogether and just test the return value of the digitalRead:

// Play tone after light fully bright
for(int i = 1; i<100; i++){
  // Turn off tone on button press
  if (digitalRead(buttonPin) == HIGH) {
    noTone(TONE);
    break;
  }
  tone(TONE, notes[random(0,3)]);
  delay(100);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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