Click here to Skip to main content
15,891,856 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hey there to all,

I am new in the Arduino programming-environment and I thought I want to create me an "alarm clock" to work a little bit with the buttons. The "alarm clock" works with a Piezospeaker and two buttons, nothing more. The idea behind this is to press both buttons separately and when both buttons are pressed (AND) they stop my alarm clock. Now the problem is that my speaker isn't just on (HIGH) it have a rhythm:

C++
digitalWrite(speaker, HIGH);
delay(500);
digitalWrite(speaker, LOW);
delay(500);


But I discovered that with that delay I have some troubles. It doesn't work anytime. Without a delay it works properly but as higher the delay it more tend to doesn't work.

My code:

C++
int speaker = 2;
int taster_1 = 7;
int taster_2 = 8;
int taster_status_1 = 0;
int taster_status_2 = 0;
bool taster1_off= 0;
bool taster2_off = 0;

bool speaker_status = true;

void setup() {
  pinMode(speaker, OUTPUT);
  pinMode(taster_1, INPUT);
  pinMode(taster_2, INPUT);
  digitalWrite(speaker, HIGH);
}

void loop() {

  taster_status_1 = digitalRead(taster_1);
  taster_status_2 = digitalRead(taster_2); 

  if ( taster_status_1 == HIGH) { 
     taster1_off = 1;
  } else if ( taster_status_2 == HIGH) {
      taster2_off = 1;
  }

  if (taster1_off == 1 and taster2_off == 1){ //when both buttons were pressed the alarm should stop
    speaker_status = false;
  }

  if (speaker_status == true) { // rhythm of the alarm, as long speaker_status is true it goes on and on
    digitalWrite(speaker, HIGH);
    delay(500);
    digitalWrite(speaker, LOW);
    delay(500);
  }

}


What I have tried:

I tried with
attachInterrupt()
and Timers but I think it doesn't work the way I want to. I really looking forward for a hint.

I would really appreciate a little hint and a really huge thank you in anticipation!
Posted
Updated 7-Apr-16 2:09am

Part of the problem is that the delay function[^] stops your program runnign for the ammount of time you specify - 500ms or half a second. And you call it twice in quick succession, so it only checks the buttons quickly once a second. So you can't just "push the buttons" - you have to hold them down.

And when you do, you code doesn't do what you think, because:
C++
if ( taster_status_1 == HIGH) { 
     taster1_off = 1;
  } else if ( taster_status_2 == HIGH) {
      taster2_off = 1;
  }
means that is teh first button is pressed, it never checks the other, and so
this test will always fail:
C++
if (taster1_off == 1 and taster2_off == 1){ //when both buttons were pressed the alarm should stop

Take out the else and it should work:
C++
if ( taster_status_1 == HIGH) { 
     taster1_off = 1;
  } 
if ( taster_status_2 == HIGH) {
      taster2_off = 1;
  }
 
Share this answer
 
Comments
TimLaJoh 8-Apr-16 12:33pm    
Thank you for your help. I really appreciate it, thanks!

I tested it and it worked for me when I don't use the delay(). As soon I use a delay() between the

digitalWrite(speaker, HIGH);
delay(500);
digitalWrite(speaker, LOW);
delay(500);

it don't work. I cannot turn the alarm off. I think because of the delay() the buttons can't interrupt the delay function.
OriginalGriff 8-Apr-16 12:37pm    
Makes sense.
Look at Jochen's solution: the PWM output sounds like a good idea to me!
Your piezo buzzer is a so called "external drive type". That means it must be driven with an alternating signal. The buzzer frequency is type depending (typical values are in the range of 1 to 9 kHz). While it will work with some frequencies, it will have maximum intensity at the specified frequency. So you should look up the frequency for your buzzer.

If the frequecy is for example 4.8 kHz, the period time is 0.21 milli seconds (1 / 4800) and the on / off times must be half that time (0.105 ms). This is much less than your delays of 500 ms. If you use a delay of 2 ms, the signal will be 250 Hz which should still be hearable.

A better solution would be using a timer or PWM output (I don't know the Arduino but it seems that there is a PWM output: Arduino - PWM[^]).

Finally some warnings:

Never apply DC voltage to piezo buzzers for long time periods. So ensure that the output is always cleared when terminating your program.

Piezo buzzers can cause high voltages upon thermical and mechanical shocks and induce reverse voltages (especially when driven with rectangular signals) that may destroy the Arduino port. To avoid this use two Zener diodes in series (cathode to cathode) connected in parallel to the buzzer or drive the buzzer with a transistor (than put also a 1 kOhm resistor in parallel to the buzzer to protect the transistor from the reverse voltage).
 
Share this answer
 
Comments
OriginalGriff 8-Apr-16 12:40pm    
Get my five for the diodes! :laugh:
I've had those in place for direct driven 5V micro-solenoids, where the back EMF as they shut could spike at +400VDC!
And the new hardware designer removed them as "they weren't doing anything"... :sigh:
Jochen Arndt 8-Apr-16 12:48pm    
Thank you.
I thought it was worth mentioning it before he blows his Arduino to oblivion.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900