Button LED and sound problem

Hi guys, I hope, I'm in the right corner of this forum. If not, please feel free to move this thread to the appropriate section.

I absolutely new to the arduino, no experience whatsoever.
My project is a new bell for my home.
What I want to achieve is that after pressing a button a sound is played and a LED light turns on and off three times.

Firt of all I connected everything as shown:

Then I tried to alter this code I found:

int ledPin = 13; // LED is connected to digital pin 13
int switchPin = 5; // switch connected to digital pin 2
int switchValue; // a variable to keep track of when switch is pressed
int counter = 0;
//int counterValue;

void setup()
{
pinMode(ledPin, OUTPUT); // sets the ledPin to be an output
pinMode(switchPin, INPUT); // sets the switchPin to be an input
digitalWrite(switchPin, HIGH); // sets the default (unpressed) state of switchPin to HIGH
}

void loop() // run over and over again
{

switchValue = digitalRead(switchPin); // check to see if the switch is pressed
if ((switchValue == LOW) && (counter <= 3)) { // if the switch is pressed then,
digitalWrite(ledPin, HIGH); // turn the LED on
delay(2000); // wait for a second
digitalWrite(ledPin, LOW); // turn the LED off
delay(2000); // wait for a second
counter++;
}
if (switchValue == HIGH)
{
counter = 0;
delay(100);
}

}

It kind of works: the light blinks 4 times (somehow I can't get it to blink 3 times), but the sound doesn't play. However, if I change the circuit so that the orange connection goes from d30 on the breadboard to d29, the sound will play, but the LED wont blink.

My error should be something quite obvious for the initiated, but for me it's a total mystery.

I'd be very thankful if you could help me out.
TardisHQ

Hi, @tardishq
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".

Can you post link to data/specs of the sound module please?
Can you please post a link to where you got the basic code?

Can you please post a copy of your circuit a picture of a hand drawn circuit in jpg, png will be fine.

A picture gram does not show any pin or component labels?

Thanks.. Tom.. :smiley: :+1: :coffee: :australia:

Your post was MOVED to its current location as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

Your blink counter starts at 0. You test to make sure it is less than or equal to 3 so you get 0,1,2,3 = 4 blinks. It is much more common to just use the less than so you would get 0,1,2. Sometimes, it is a difficult concept for new folks to get all this "counting from zero" stuff.

As for the rest of the code, have a look at the State Change Detection example in the IDE (File->examples->02.Digital->State Change Detection) and learn how to detect when your button got pressed, not if your button is currently pressed. I would think it would be better if someone only briefly pressed the button that you still get the blinks and sound without having to hold the button down the entire time.

As for why no sound - I can't tell. That is not a proper schematic (hand drawn would be better) and I don't know what that board is with your speaker. Typically, the speaker would be connected to its own pin such that when you detect a button press, you then activate the speaker, etc.

Thanks for your answer. I hope I can answer all your questions.
The sound module I use is this one: MP3 Sound Chip Module. Create your own Talking Cards & Gifts. MP3 chip – Talking Products Ltd

The Code I found on this forum. To be exact from here: How to turn on/off an LED 3 times, then stop - Using Arduino / Programming Questions - Arduino Forum

Reagrding the circuit, I'm not sure how to do that, thatswhy I used photoshop. I recreated all connections. Here is my handdrawn circuit. I hope it helps.

For clearification: If i connect digital PIN 5 from C0 to C1 I can hear the sound, if it connects to C0 it will blink.

Thanks
TardisHQ

Thank you for your help. Your first paragraph explains my issue very well. Thanks for clearing it up. For the rest there is much to think about, but it got my wheels turning. Again: thank you.

If you look in my post abvo, you will find a handdrawn schematic of my circuit and some more information on my hardware. Maybe these help.

Best regards
TardisHQ

Are you using the build-in LED? If not, and you have an external one connected, it really should have a 220 ohm resistor in series to limit the current.

As for the circuit, I didn't see any schematic but the "button" connection is probably just short to ground (pressed) or open. You can write a simple sketch that just continuously reads the pin and prints HIGH or LOW and see what happens when you press/release the button. Then you will know what state the pin will be in when it is pressed and when it is not.

Also, check out the State Change Detection example like I mentioned before... You will want to use that

Hi,
Do you have a DMM?
We need to see exaclty what the button is operating on the module.

Can you disconnect the UNO D5 from the switch.
Then measure the voltage on each of two wires with respect to gnd, before and after you press the button.

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

So far your tipps are helping wonderfully. The State Change Detection example made the LED go blink while the sound is playing simultanously. But: it starts blinking even before the button is pressed and wont stop. I have to figure out why and how to make it start/stop.
I bought some resistors as you advised and will try to fit them into the circuit. Please tell me: Why do I need one, though?
Thanks in advance. Best regards
TardisHQ

Actually I do own a DMM, but I'm at a loss on how to use it.
Good news is: it starts to work as intended. The LED blinks and the sound is played.

If you look at a datasheet for an LED, it has a forward voltage rating. This is usually around 2V or so... That is the voltage drop across the LED. It also has a max current rating which is usually something like 20-30 mA. When you connect it to a 5V arduino board, you have to limit the current to keep it at Imax or below, so....
5V - 2V = 3V
and 3V/30mA = 100 ohms.

A typical value to use is 220 ohms which keeps the current down around 20mA.

The reason this works without a resistor is that the arduino board can only deliver around 30mA per pin but it is a very bad design to rely on components to limit out their capabilities. You run the risk of damaging the pin/chip.

You will have to introduce another variable into your sketch, something like

bool isBlinking = false;

and then, when the button is pressed, you change the value of this variable

isBlinking = !isBlinking;

and then, in your blinking routine, you only do the blinking if it is true

if ( isBlinking == true ) {
  // do your blinking stuff
}

I see. Well, the resistor seems to do his job, the LED is slightly less bright.
It just wont stop blinking. I'm able to calibrate the blink rate, though. Only, it just sort of starts on his own as soon the Arduino has power and wont stop.

This is my code now, is there something I'm missing?


// this constant won't change:
const int  buttonPin =  2;    // the pin that the pushbutton is attached to
const int ledPin = 12;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  // compare the buttonState to its previous state
  if (buttonState != lastButtonState) {
    // if the state has changed, increment the counter
    if (buttonState == HIGH) {
      // if the current state is HIGH then the button went from off to on:
      buttonPushCounter++;
      Serial.println("On");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {
      // if the current state is LOW then the button went from on to off:
      Serial.println("Off");
    }
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  // save the current state as the last state, for next time through the loop
  lastButtonState = buttonState;


  // turns on the LED every four button pushes by checking the modulo of the
  // button push counter. the modulo function gives you the remainder of the
  // division of two numbers:
  if (buttonPushCounter % 1 == 0) {
    digitalWrite(ledPin, HIGH);
    delay(1500);
    digitalWrite(ledPin, LOW);
       delay(150);
    
    
  } else {
      digitalWrite(ledPin, LOW);
  }

}

You LED will always blink since this

  if (buttonPushCounter % 1 == 0) {

is ALWAYS true. The modulo operator '%' returns a value from 0 to X-1 and since your 'X' is 1, the only value it can return is 0 which will always equal 0.

Your comments are not accurate since they say blink every 4th button push.

Also, do you have a pull-down resistor connected to your button? You are declaring it as "INPUT" which requires a pull-down resistor. A better way it to declare it as "INPUT_PULLUP" and use the internal pull-up resistor. Then, connect the button between the pin and ground. This will reverse the sense of the button (HIGH == not pressed, LOW == pressed) so you will have to adjust your code.

It is a pity that the State Change Example does not do it this way...

Sorry to bother you again, but I don't understand what I have to write to get it to stop blinking. And I'm to daft to understand what it means that values are returned in relationship to letters and numbers.... and maths(?).

So, after sime tinkering I made some progress. First of all I changed the circuit to this:

Then I changed the code to this:



const int  buttonPin =  2;   
const int ledPin = 12;       
bool isBlinking = true;


int buttonPushCounter = 0;   
int buttonState = 0;         
int lastButtonState = 0;     

void setup() {

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  
  Serial.begin(9600);
}


void loop() {

  buttonState = digitalRead(buttonPin);


  if (buttonState != lastButtonState) {

    if (buttonState == LOW) {
      isBlinking = !isBlinking;
      buttonPushCounter++;
      Serial.println("On");
      Serial.print("number of button pushes: ");
      Serial.println(buttonPushCounter);
    } else {

      Serial.println("Off");
    }

    delay(50);
  }

  lastButtonState = buttonState;


  if (buttonPushCounter % 1 == 0) {
    
    if ( isBlinking == true ) {
      digitalWrite(ledPin, HIGH);
      delay(1500);
      digitalWrite(ledPin, LOW);
      delay(1500);
  // do your blinking stuff
  
}
    
    
    
  } else {
      digitalWrite(ledPin, HIGH);
  }

}

What happens now is that pressing the button does work. It will start and stop the sound and the blinking.

But: If the utton is pressed sound and light start to loop till the button is pressed again. My idea was that the sound is played once and the light blinks three times. How do I stop the loop without pressing the button again? Where is my error?

Thanks
TardisHQ

You should never stop loop().

You need to introduce a couple of new variables, maybe something like

bool soundHasPlayed = false;
int buttonBlinkCount = 0;

and then, when you press the button to start, you check to see if the sound has played and you also check to see how many times the button has blinked. If they have reached your goal, you stop, if not, continue. When you press the button to stop, isBlinking gets set to false. You have to keep track of what state you are in...

  1. waiting for start
  2. start pressed
  3. sound has already played (or not) so don't play it again
  4. blinking has reached max (or not) so no more blinking
  5. stop has been pressed

Hi,

Give the button its own input pin.
Give the LED its own output pin.

@blh64 has said, in your code look for the button being pressed not pressed.

Tom... :smiley: :+1: :coffee: :australia:

Hi guys,

I had to admit defeat ... for now. I realized that I still have much to learn about these kind of projects and in the way of thinking logically. I'm more a Kirk than a Spock in this regard. But I had a friend over who had more experience and he helped me a lot. We even built in a second LED that I didn't dare to implement in the first place.
What we did was this: First of all we changed the circuit to this:

Then he changed the code to this:

  

const int  buttonPin =  2;
const int soundPin = 4;   
const int ledPin = 12;    
const int ledPin2 = 11;    
bool BlinkAN = false;
bool soundHasPlayed = false;


int buttonPushCounter = 0;   
int buttonState = 0;         
int lastButtonState = 1;     

void setup() {

  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(soundPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  Serial.begin(9600);
}


void loop() {                                   //Überprüfe: Hat sich der Zustand des Knopf (AN/AUS) verändert? Wenn ja: gib die Info LED und Sound weiter und setze den Button auf AN, Zähle plus 1 auf die Knopfzähler
                                                 // Wenn nein: warte 50 Millisekunden
  buttonState = digitalRead(buttonPin);
  
  if (buttonState != lastButtonState) 
  {
    if (buttonState == LOW) 
    {
      BlinkAN = !BlinkAN;
      soundHasPlayed = !soundHasPlayed;
      buttonPushCounter++;
    } 
    else 
    {
    }
    delay(50);
  }

  lastButtonState = buttonState;              // Schreibe den letzten Status des Knopfes als aktuellen Status des Knopfes


  if (buttonPushCounter % 1 == 0) {
    
    if ( BlinkAN == true ) {
      digitalWrite(ledPin2, HIGH);
      digitalWrite(soundPin, HIGH);
      delay(600);
      digitalWrite(ledPin, HIGH);
      delay(1800);
      digitalWrite(ledPin, LOW);
      digitalWrite(soundPin, LOW);
      delay(1200);
      
      digitalWrite(soundPin, HIGH);
      delay(600);
      digitalWrite(ledPin, HIGH);
      delay(1800);
      digitalWrite(ledPin, LOW);
      digitalWrite(soundPin, LOW);
      delay(1200);
      
      digitalWrite(soundPin, HIGH);
      delay(600);
      digitalWrite(ledPin, HIGH);
      delay(1800);
      digitalWrite(ledPin, LOW);
      digitalWrite(soundPin, LOW);
      digitalWrite(ledPin2, LOW);
      delay(1200);

      BlinkAN = !BlinkAN;
      soundHasPlayed = !soundHasPlayed;
    // do your blinking stuff
  
    } else {
      
      digitalWrite(ledPin, LOW);
      digitalWrite(soundPin, LOW);
    }
    
  //else 2 käme hier hin   
    
  } else {
      digitalWrite(ledPin, LOW);
      digitalWrite(soundPin, LOW);
  }

}

And it worked exactly as I imagined. Theres nothing much to do apart from thanking you guys for your patience and willingeness to help a complete noob. Stay safe.

LLAP
TardisHQ

Do you understand the circuit and how the code works to do what you want ?

try

  if (true != false) {

and see if it still works.