How do I get my loop to run more slowly?

Hello,

I am trying to create a program in which the Arduino plays a sound, and the user responds by pushing either button 1, button 2, or the pressure sensor.
If sound1 plays, they should push button 1 to light the RGB led yellow.
If sound2 plays, they should push PRESSURE sensor to light RGB cyan
If sound3 plays, they should push button 2 to light RGB magenta.

I have an array of numbers 1-3 for the loop to cycle through, which corresponds to sound1, sound2, and sound3. The problem is, my loop runs too fast, so there’s no response time. It runs through the whole array in a second. I tried adding delays, but when I do that, the LED doesn’t light up at the proper time.

How do I get the loop to wait for the user to respond before going on to the next iteration?

For the sake of brevity, I’ve posted only the setup and loop portion, please let me know if I should post the entire code.

void setup()
{
  
 pinMode(speakerPin, OUTPUT);
 pinMode(buttonYellow, INPUT);
 pinMode(buttonMagenta, INPUT);

 for(int i = 0;i<3; i++)
   pinMode(ledDigitalOne[i], OUTPUT);    //sets RGB as output
 
 Serial.begin(9600);
 
  
}

void loop()
{
  Serial.print("If you hear one tone, press the BUTTON once");
  Serial.println("If you hear two tones, press the PRESSURE SENSOR");
  Serial.println("If you hear 3 tones, press the BUTTON2");
  
  for(int i =0;i<10;i++)
  {
 
     randNum = randNumChoices[i];
    playSound(randNum);
    Serial.println(randNum);   //just so I can see how fast it is cycling through the numbers
  
  
  
  
    yellowRead = digitalRead(buttonYellow);
  
    yellowLED(yellowRead);   //sends to yellowLED function to light yellow

    pressure = analogRead(pressurePin);
  
    cyanLED(pressure);     //sends to cyanLED function to light cyan
  
    magentaRead = digitalRead(buttonMagenta);
  
    magentaLED(magentaRead);   //sends to mangentaLED function to light magenta
  
  }
  
 
  
}

The problem is, my loop runs too fast, so there's no response time.

No, that is not the problem. The problem is that you need to understand that loop does that, and live with it.

That means that you need to expect that the user response is NOT going to happen in the same iteration of loop() as the trigger for that response.

please let me know if I should post the entire code.

I suppose that, for brevity, you'd like us to post just part of the answer. If that's the case, feel free to not post all of the code.

tghafo:
For the sake of brevity, I’ve posted only the setup and loop portion, please let me know if I should post the entire code.

For brevity I’ll just say “yes”

Here is the full code:

/*Serial monitor displays “1 tone: push button. 2 tones: push sensor. 3 tones: push button2”
Piezo plays either 1 tone, 2 tones, or 3 tones
You either push button, push sensor, or push button 3 times
If you push button: LED lights up yellow
If you push sensor: LED lights cyan
If you push button 2: LED lights magenta*/



//initialize pins 
int speakerPin = 9;
int buttonYellow = 4;
int pressurePin = 2;
int buttonMagenta = 3;


//declare variables and constants
char correct;
int randNumChoices[] = {2,1,3,1,1,2,3,1,2,3,3};
int randNum;
int yellowRead = HIGH;
int magentaRead = HIGH;
const boolean ON=LOW;
const boolean OFF=HIGH;
int pressure = 0;


//RGB LED
int ledDigitalOne[] = {6,10,11};
//6 = red, 10 = green, 11= blue

  

//Predefined Colors
boolean YELLOW[] = {ON,ON,OFF};
boolean CYAN[] = {OFF,ON,ON};
boolean MAGENTA[] = {ON,OFF,ON};

//Array to store the predefined colors
const boolean* COLORS[] = {YELLOW,CYAN,MAGENTA};




//functions
void playSound(int randNum)
{
    if (randNum <10)
  {
    sound1();
   
  }
  else if (randNum>= 10 && randNum<20)
  {
    sound2();
    
  }
  else
  {
    sound3();
   }
  
}
void sound1()  //d,b
{
  tone(9,493,5000);
}

void sound2()  //
{
  tone(9, 261,500);
  delay(500);
  tone(9, 392,2500);
}
void sound3()
{
  tone(9, 523, 500);
  delay(1000);
  tone(9, 523, 500);
  delay(1000);
  tone(9, 523, 500);
} 

void setColor(int* led, boolean* color)
{
  for(int i = 0; i<3;i++)
  {
    digitalWrite(led[i], color[i]);
  }
}

void yellowLED(int yellowRead)
{
    if (yellowRead == LOW) {     
    // turn LED on:    
    setColor(ledDigitalOne, YELLOW);  
  } 
  else 
  {
    // turn LED off:
    for (int i = 0;i<3;i++)
    {
      digitalWrite(ledDigitalOne[i], HIGH); 
    }
  }
}
 
 
void cyanLED(int pressure)
{
    if (pressure >=25)
  {
     setColor(ledDigitalOne, CYAN);  
  } 
  else 
  {
    // turn LED off:
    for (int i = 0;i<3;i++)
    {
      digitalWrite(ledDigitalOne[i], HIGH); 
    }
  }
}

void magentaLED(int magentaRead)
{
    if (magentaRead == LOW) {     
    // turn LED on:    
    setColor(ledDigitalOne, MAGENTA); 
  } 
  else 
  {
    // turn LED off:
    for (int i = 0;i<3;i++)
    {
      digitalWrite(ledDigitalOne[i], HIGH); 
    }
  }
}
    


void setup()
{
  
 pinMode(speakerPin, OUTPUT);
 pinMode(buttonYellow, INPUT);
 pinMode(buttonMagenta, INPUT);

 for(int i = 0;i<3; i++)
   pinMode(ledDigitalOne[i], OUTPUT);    //sets RGB as output
 
 Serial.begin(9600);
 
  
}

void loop()
{
  Serial.print("If you hear one tone, press the BUTTON once");
  Serial.println("If you hear two tones, press the PRESSURE SENSOR");
  Serial.println("If you hear 3 tones, press the BUTTON2");
  
  for(int i =0;i<10;i++)
  {
 
     randNum = randNumChoices[i];
   playSound(randNum);
    Serial.println(randNum);
  
  
  
  
    yellowRead = digitalRead(buttonYellow);
  
    yellowLED(yellowRead);

    pressure = analogRead(pressurePin);
  
    cyanLED(pressure);
  
    magentaRead = digitalRead(buttonMagenta);
  
    magentaLED(magentaRead); 
  
  }
  
 
  
}

How can I make it so that the user has a way to respond to the piezo sound?
Also, I had originally thought this might be a problem with my circuit, but if I try to switch between buttons and pressure sensor, for example I push the pressure sensor to make it cyan, then try to push the button1 to make the led yellow, the cyan works but the yellow is very dim. Is the code causing this problem?

In Real Life, if you sent an email to a friend asking a question, would you be astonished if you did not get a reply a second later?

If not, how would you organize your life, so that you could do other things, but handle the response when it came?

Whatever your technique is, apply it to this program.

A State Machine might help.

tghafo:
Here is the full code:

How can I make it so that the user has a way to respond to the piezo sound?
Also, I had originally thought this might be a problem with my circuit, but if I try to switch between buttons and pressure sensor, for example I push the pressure sensor to make it cyan, then try to push the button1 to make the led yellow, the cyan works but the yellow is very dim. Is the code causing this problem?

her is an example of how to wait for serial input, using Nick's advice of a simple state machine.

long R1, R2;
float result;
boolean printed;
int state;

void setup()  
{
  Serial.begin(9600);
}
void loop()  
{
  if (state == 0)
  {
    if (!printed) Serial.println(F("What is the value of R1 in ohms?"));
    printed = true;
    if (Serial.available())
    {
      R1 = Serial.parseInt();
      Serial.print(F("R1 = "));
      Serial.print(R1);
      Serial.println(F(" Ohms"));
      printed = false;
      state = 1;
    }
  }
  else if (state == 1)
  {
    if (!printed) Serial.println(F("What is the value of R2 in ohms?"));
    printed = true;
    if (Serial.available())
    {
      R2 = Serial.parseInt();
      Serial.print(F("R2 = "));
      Serial.print(R2);
      Serial.println(F(" Ohms"));
      printed = false;
      state = 2;
    }
  }
  else if (state == 2)
  {
    result =  (float) R1 * R2 / ( R1 + R2 );
    Serial.print(F("Resistor Value = "));
    Serial.print(round(result));
    Serial.println(" Ohms");
    state = 0;
  }
}