Using button with nano for project

I am trying to incorporate a button, buzzer, and 3 LEDs with a nano for a project. I have prototyped the circuit on a breadboard and am sure that the connections are correct. I want the buzzer to play a tune and the LEDs to turn on when the button is pressed is pressed for 3 seconds. The buzzer and LEDs work, just not when I want them to. For some reason, I press the button once for half a second and let go, and then the tune and LEDs trigger on a continuous loop even when the button is not pressed. Any advice?

`//Pins
int piezo=4; // Passive buzzer, Digital Pin 4
int led1=2; // First LED, Digital Pin 2
int led2=12; // Second LED, Digital Pin 12
int led3=9; // Third LED, Digital Pin 13
int button=6; // Momentary button, Digital Pin 6

//Button
unsigned long buttonTime; // Time that button has been pressed
int buttonState = 0; // Initial button state

//Counter
int counter=0; // counter starts at 0

void setup() {
pinMode(piezo, OUTPUT); // Sets Digital Pin 4 as an output
pinMode(led1, OUTPUT); // Sets Digital Pin 2 as an output
pinMode(led2, OUTPUT); // Sets Digital Pin 12 as an output
pinMode(led3, OUTPUT); // Sets Digital Pin 9 as an output
pinMode(button, INPUT); // Sets Digital Pin 6 as an input
}

void loop() {
buttonState = digitalRead(button); // buttonState is equivelant to whatever is read from the button, HIGH or LOW

if (buttonState == HIGH) {
counter++; // If the button is pressed, the counter begins counting upwards
}

if (counter >= 3000) {
digitalWrite(led1, HIGH); // Turns LED 1 on
digitalWrite(led2, HIGH); // Turns LED 2 on
digitalWrite(led3, HIGH); // Turns LED 3 on
tone(piezo,410,200); //Beginning of tune played by passive buzzer
delay(200);
tone(piezo,300,200);
delay(200);
tone(piezo,410,200);
delay(200);
tone(piezo,550,150);
delay(150);
tone(piezo,410,200);
delay(200);
tone(piezo,300,200);
delay(200);
tone(piezo,410,200);
delay(200);
tone(piezo,300,150);
delay(150);
tone(piezo, 100);
delay(200);
tone(piezo, 250);
delay(1000);
noTone(piezo); // End of tune played by passive buzzer
digitalWrite(led1, LOW); // Turns LED 1 off
digitalWrite(led2, LOW); // Turns LED 2 off
digitalWrite(led3, LOW); // Turns LED 3 off
}

else if (buttonState == LOW) {
counter=0; // Counter remains at 0 if the button is not pressed

}

}`

If you don't use INPUT_PULLUP the INPUT pin has to have an external pull-up or pull-down resistor. If it doesn't, it will float randomly between HIGH and LOW.

I have a 10k ohm pull-up resistor in between the pin and button lead

I cannot make sense of your description of how the resistor is connected. A diagram would help

It should be connected between the pin and 5V if you want to use it a a pullup resistor or between the pin and GND if you want to use it as a pulldown resistor

Sorry for being new to this, but how should I create the diagram?

Draw it with pencil and paper, take a picture of it, upload the picture to a post here

For the button.
one side goes to ground.
the other side goes to the Arduino input.
if you want a resistor, it goes from Arduino input to 5V, however it's simpler to just user INPUT_PULLUP instead of INPUT when you initialize that pin.
Last thing - invert your logic, because wiring as I've suggested means the input will be low when the button is pressed and high when it's not pressed.
If you insist on using high=pressed logic, then you'll need to wire the button between 5V and the input, and put the resistor between the input and ground, as a pulldown. But that's not the best way to do it, by far.

Thank you for the advice, I will try to update the code and circuit.

I removed the resistor, have one side going to ground and other going to the digital pin. I replaced INPUT with INPUT_PULLUP and switched the logic. However, I still have the same results. As soon as I press the button, the buzzer and LEDs trigger on repeat. Any other ideas?

It seems as though it is ignoring the minimum counter value.

Still waiting for your code to appear in code tags. It's the </> button at the top of the user dialog.

//Pins
int piezo=4;  // Passive buzzer, Digital Pin 4
int led1=2;  // First LED, Digital Pin 2
int led2=12;  // Second LED, Digital Pin 12
int led3=9;  // Third LED, Digital Pin 13
int button=6;  // Momentary button, Digital Pin 6

//Button
unsigned long buttonTime;  // Time that button has been pressed
int buttonState = 0;  // Initial button state

//Counter
int counter=0;  // counter starts at 0

void setup() {
  pinMode(piezo, OUTPUT);  // Sets Digital Pin 4 as an output
  pinMode(led1, OUTPUT);  // Sets Digital Pin 2 as an output
  pinMode(led2, OUTPUT);  // Sets Digital Pin 12 as an output
  pinMode(led3, OUTPUT);  // Sets Digital Pin 9 as an output
  pinMode(button, INPUT_PULLUP);  // Sets Digital Pin 6 as an input
}

void loop() {
  buttonState = digitalRead(button); // buttonState is equivelant to whatever is read from the button, HIGH or LOW
  
  if (buttonState == LOW) {
    counter++;  // If the button is pressed, the counter begins counting upwards
  }

  
  if (counter >= 3000) {
    digitalWrite(led1, HIGH);  // Turns LED 1 on
    digitalWrite(led2, HIGH);  // Turns LED 2 on
    digitalWrite(led3, HIGH);  // Turns LED 3 on
    tone(piezo,410,200);  //Beginning of tune played by passive buzzer
    delay(200);
    tone(piezo,300,200);
    delay(200);
    tone(piezo,410,200);
    delay(200);
    tone(piezo,550,150);
    delay(150);
    tone(piezo,410,200);
    delay(200);
    tone(piezo,300,200);
    delay(200);
    tone(piezo,410,200);
    delay(200);
    tone(piezo,300,150);
    delay(150);
    tone(piezo, 100);
    delay(200);
    tone(piezo, 250);
    delay(1000);
    noTone(piezo);  // End of tune played by passive buzzer
    digitalWrite(led1, LOW);  // Turns LED 1 off
    digitalWrite(led2, LOW);  // Turns LED 2 off
    digitalWrite(led3, LOW);  // Turns LED 3 off
  }
    
else if (buttonState == HIGH) {
counter=0;  // Counter remains at 0 if the button is not pressed

}

}

When the loop() is looping, how long do you think it takes? Multiply that number by 3000, and tell me what the answer is.

3000ms? Guessing it takes 1 millis

Much much less. your code, without the action:

void loop() {
  buttonState = digitalRead(button); // buttonState is equivelant to whatever is read from the button, HIGH or LOW

  if (buttonState == LOW) {
    counter++;  // If the button is pressed, the counter begins counting upwards
  }
  else if (buttonState == HIGH) {
    counter = 0; // Counter remains at 0 if the button is not pressed
  }
}

I don't know the answer, but if it's more than 20 uS, I'm giving up on Arduino. Other than some under-the-hood chicanery, that would resolve to
read input register,
mask bit
if result is zero increment counter
else clear counter
loop

So, the counter counts how many times a program has looped? I thought it kept track of time in ms. I tried using the millis() but could not figure out a way to make it work, becuase millis() counts from when the program starts, not when the button is pressed.

I think you should re-read the tutorials about millis() and non-blocking delays. What you need to do is store the time (x-millis()) when the button is first pressed, and monitor millis for a value 3000 greater than that start value, and stop monitoring that if the button is released.
But you need to work it through yourself, so that's enough hint. Back to the books!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.