Go Down

Topic: Line before 'for loop' is running until 'for loop' ends (Read 285 times) previous topic - next topic

xtthew

I'm having trouble with some code running until my for loop is done. I have a buzzer that signals the start of the light change, and I'm using a For Loop to intialize the lights on a NeoPixel Ring.

The problem is that the buzzer keeps on ringing until the for loop has completed lighting all the LEDs on the NeoPixel ring.

I don't physically have a NeoPixel Ring, I'm using tinkercad.com/circuits to test this with.

What I've tried to rectify the problem is:

  • Create a for loop for the buzzer. (still gets stuck)
  • Move the for loop outside the if statement (still gets stuck)
  • Remove the delay (buzzer doesn't sound)


Without the for loop, lighting a single RGB LED works fine.. but adding this into their seems to have messed it up. I've tried to use strip.fill from the NeoPixel library but for some reason tinkercad doesn't recognize it so I'm stuck using this for loop to accomplish my goal.

I'm including the full code, a snippet where the problem is happening, and an image of the setup.


Here is the full code:

Code: [Select]

#include <Adafruit_NeoPixel.h>
#define PIN 5
#define NUMPIXELS 24
Adafruit_NeoPixel ring(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

int powerInd=13;
int button=7;
int buzzer=6;
int buzzTone1=880;
int buzzTone2=1046.5;
int buzzTone3=1318.52;
byte ringState=0;
boolean oldButtonState = LOW;
boolean buttonState1 = LOW;
boolean buttonState2 = LOW;
boolean buttonState3 = LOW;
int j;

void setup() {
  pinMode(powerInd,OUTPUT);
  digitalWrite(powerInd,HIGH); //Indicate Power is On
  pinMode(button,INPUT);
  pinMode(buzzer,OUTPUT);
//  tone(buzzer,2800);   --------REMOVED BUZZER FOR TESTING---------
//  delay(500);
//  noTone(buzzer);   
}

void loop() {

   buttonState1 = digitalRead(button);
   buttonState2 = digitalRead(button);
   buttonState3 = digitalRead(button);
 
    if (  (buttonState1==buttonState2) && (buttonState1==buttonState3) )
    {
 
        if ( buttonState1 != oldButtonState )
        {
 
           if ( buttonState1 == HIGH )
           {
                ringState++;
               
                 if (ringState > 3) { ringState = 0;}
                         
                   ring.clear();
                   ring.show();
               
                    if (ringState==1) {
                      tone(buzzer,buzzTone1,100);
                      delay(100);
                      for(int j=0;j<NUMPIXELS;j++) {
                        ring.setPixelColor(j, ring.Color(0, 255, 0));
                        ring.show();}
                    }
   
                    if (ringState==2) {
                      tone(buzzer,buzzTone2,200);
                      delay(200);
                      tone(buzzer,buzzTone1,100);
                      delay(100);                                     
                      for(int j=0;j<NUMPIXELS;j++) {
                        ring.setPixelColor(j, ring.Color(255, 255, 0));
                        ring.show();}
                     }   
             
                    if (ringState==3) {
                      tone(buzzer,buzzTone2,200);
                      delay(200);
                      tone(buzzer,buzzTone1,100);
                      delay(100);
                      tone(buzzer,buzzTone3,200);
                      delay(200);                     
                      for(int j=0; j<NUMPIXELS; j++) {
                        ring.setPixelColor(j, ring.Color(255, 0, 0));
                        ring.show();}
                    }
              delay(1000);
          }
         oldButtonState == buttonState1;
      }
  }
}


Here is where the problem is:
Code: [Select]

                    if (ringState==1) {
                      tone(buzzer,buzzTone1,100);
                      delay(100);
                      for(int j=0;j<NUMPIXELS;j++) {
                        ring.setPixelColor(j, ring.Color(0, 255, 0));
                        ring.show();}
                    }

Montmorency

#1
Apr 13, 2019, 11:27 pm Last Edit: Apr 13, 2019, 11:28 pm by Montmorency
Since your never seem to "parallelize" any actions with the buzzer a better idea might be to adopt `tone/noTone` approach, instead of specifying duration in `tone` and then repeating it in `delay`.

For example

Code: [Select]
tone(buzzer, buzzTone2);
delay(200);
noTone();


Did you try to use an explicit call to `noTone` before the LED cycle? Does it stop the buzzer?

xtthew

I just tried to add noTone(buzzer) and it doesn't stop the buzzing from running until the for loop ends.

Thanks for the suggestion on that though!

EDIT:
Sorry.. I didn't catch the part where you said to match the delay.

It's working fine now with:

Code: [Select]

                    if (ringState==1) {
                      tone(buzzer,buzzTone1);
                      delay(100);
                      noTone(buzzer);
                      delay(100);
                      for(int j=0;j<NUMPIXELS;j++) {
                        ring.setPixelColor(j, ring.Color(0, 255, 0));
                        ring.show();}
                    }


Thanks!

ONE MORE EDIT: I just realized you didn't specifically say to do this, but it works.. I'd still like to understand why it does this though.

david_2018

Something that might be causing problems, by letting the code run constantly while the button is HIGH instead of just once:

Code: [Select]

 oldButtonState == buttonState1;



Go Up