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.
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
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.
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.
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.
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.
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
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.
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);
}
}
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:
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?
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...
waiting for start
start pressed
sound has already played (or not) so don't play it again
blinking has reached max (or not) so no more blinking
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:
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.