Notifications
Clear all

Piezo Buzzer for loop not working

24 Posts
6 Users
0 Likes
8,486 Views
(@rms84)
Member
Joined: 4 years ago
Posts: 7
Topic starter  

Hello I'm Rosie. I would would really appreciate some help with this arduino sketch. As part of a larger project I want a piezo buzzer to beep for a certain amount of time and then stop, so I am using a for loop. I can't figure out why it's still continuous though, as I was expecting it to stop looping when i becomes greater than 5. I've pasted my code below, if somebody could take a look at it and explain where I'm going wrong I would be really grateful. Thanks in advance. PS. I've not included the setup code below as it's got lots of code in there that is irrelevant to the buzzer bit of the project.

 

void loop() {

int i;
int pin = 8;
int frequency = 2000;
int duration = 500;

for ( i = 0 ; i < 5 ; i++){
tone(pin, frequency, duration);
delay(1000);

}
}

This topic was modified 4 years ago by rms84

   
Quote
(@dronebot-workshop)
Workshop Guru Admin
Joined: 5 years ago
Posts: 1051
 

Hi Rosie, and welcome to the forum!

I think your for statement is fine, however, you seem to have your code in the Loop section. Anything in the Loop will repeat continuously. That's probably why it keeps beeping.

"Never trust a computer you can’t throw out a window." — Steve Wozniak


   
ReplyQuote
(@rms84)
Member
Joined: 4 years ago
Posts: 7
Topic starter  

@dronebot-workshop

Hello and thank you for your reply and welcoming me to the forum. I actually want it to repeat so that's why I put it in the loop section, however I want it to stop beeping after several minutes. That's why I have the "for ( i = 0 ; i < 5 ; i++)" in the code. As I thought that when i became greater than 5 it would stop beeping. I don't actually want it to beep 5 times, I just set it to 5 for testing purposes, after I know the code executes as planned I intend to increase the number to 120.  Other than having 120 lines of code in the setup section, is there a way it can repeat and then stop in the loop section?


   
ReplyQuote
(@overbyte)
Only close to Holy
Joined: 4 years ago
Posts: 1
 

Instead of a FOR, which sets a state, you want an IF statement which checks a condition.

If (buzzer_equates_to_?) then { stop buzzer }

Something like:

IF(i==5) {tone(pin, 0, 0) };

Hope this helps..

 

This post was modified 4 years ago 2 times by Overbyte

   
ReplyQuote
(@rms84)
Member
Joined: 4 years ago
Posts: 7
Topic starter  

@overbyte

Thank you for your reply. I will change it to IF and let you know how I get on. ? 


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@rms84

bool soundBuzzer = true;

int pin = 8;
int frequency = 2000;
int duration = 500;

void setup() {
  //
}

void loop() {
  
    // this conditional is only called when soundBuzzer = true 
    if(soundBuzzer){
      tone(pin, frequency, duration);
      soundBuzzer = !soundBuzzer; //changes soundBuzzer to false
      } 
        
    // soundBuzzer = true; // put this further down the code when you want the buzzer to sound again.
}

The above code will only activate the buzzer once.


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@rms84

There are two problems with your code... Bill highlighted one of them, which is you have declared your variables within the scope of the main loop, meaning that they will get re-created every time the loop comes back around.  To fix that, you need to move them out of the main loop, and declare them in the global scope of the program instead.  Secondly, even if you were to move them out to the global scope, within your for loop, you are re-setting the 'i' variable back to zero each time it comes back around, so it will go on forever anyway.

Hopefully the following will help you to understand why this matters:

  int i = 0;
  int pin = 8;
  int frequency = 50;
  int duration = 1000;

void loop() {
  
  // Note that i is not being reset to zero...
  for (i; i < 5 ; i++) {
    tone(pin, frequency, duration);
    delay(1000);
   }
   
 }

   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@pugwash

Hope this helps you a bit, as it gets rid of that ugly delay() function.

I hope you're not claiming your code without the delay function is cleaner 😉


   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@frogandtoad

I hope you're not claiming your code without the delay function is cleaner 

Yes. I am doing exactly that and with sound reason!

The delay() function is very destructive because it shuts down the microcontroller completely when called. In the case of your code example, the buzzer buzzes for one second and then the microcontroller stops doing anything for one second. Which mean no interrupts will be recognised and the time consumed by the delay() could be used for doing other things! I suggest you read up on it.

Furthermore, the "i" variable should not be global, this is just bad practice, the correct way of coding the conditional is as follows.

for(int i = 0; i < 5; i++){}

This means that "i" only exists in inside the curly braces for the time it is required and can be used without confusion again later within the main loop().


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

   
ReplyQuote
(@pugwash)
Sorcerers' Apprentice
Joined: 5 years ago
Posts: 923
 

@frogandtoad

Indeed, the delay() function can shut down the micro-controller, but is that really a problem for this simple application, where efficiency is not a requirement?

  1. "Can" should read "does"!
  2. simple application?? @rms84 posted that the buzzer is NOT the entire application but there is actually a lot more code in the loop(). Therefore the use of the delay() function is counterproductive.

All I am saying is that this code is far cleaner and easier to understand (not only for beginners):

Do you disagree with that?

Not entirely! But advanced programmers should only use delay() in exceptional circumstances.

I use the term ugly to describe the effect that using this function has on the practical operation in the real world, not about the simple code to use it.

I agree that using delay() in simple operations is a starting point for beginners or if someone, even Bill uses it, for quick and dirty demos.

But you must admit that using:

delay(300000);

to stop the microcontroller for a whole five minutes is about as much use as a chocolate watch!

When I started programming Arduinos, I used the delay() function until I read about the pitfalls and have used millis() ever since, the exception being when I am testing a simple concept, later I will change delay() to millis() function for the real-world application.

I hope this explains my philosophy of the delay() vs millis() debate!!


   
ReplyQuote
frogandtoad
(@frogandtoad)
Member
Joined: 5 years ago
Posts: 1458
 

@pugwash

simple application?? @rms84 posted that the buzzer is NOT the entire application but there is actually a lot more code in the loop(). Therefore the use of the delay() function is counterproductive.

I didn't see any extra code... all I see is that the OP appears to be not experienced enough to figure out the small snippet of code they presented for assistance.

Not entirely! But advanced programmers should only use delay() in exceptional circumstances.

All the experienced and professional programmers I know and worked with (including teachers), all strive for and advocate clarity over performance as being one of the most important aspects of any program, with tweaking for memory, speed or special requirements etc... coming in as second, and only if there is a need for it (i.e:- not fast enough during testing, etc...).

But you must admit that using:

delay(300000);

to stop the microcontroller for a whole five minutes is about as much use as a chocolate watch!

No, not necessarily. If I go on holidays and just want my lights to turn on every 5 minutes until I get back in 3 months then perhaps that's good enough.  Why would I need to invent my own timing scheme for such a simple task, when it's already available?

I hope this explains my philosophy of the delay() vs millis() debate!!

Sure, I understand your philosophy, and hope you understand mine just the same 🙂


   
ReplyQuote
(@rms84)
Member
Joined: 4 years ago
Posts: 7
Topic starter  

I am actually a complete beginner in programming micro-controllers so I really appreciate all the info provided by everyone. I shall do some research into each of the suggestions so thank you all for giving me some pointers.


   
ReplyQuote
(@rms84)
Member
Joined: 4 years ago
Posts: 7
Topic starter  

Oh and just to clarify there is extra code but I didn't post it in my original message as it all runs fine so didn't want to over complicate the forum with the stuff I didn't need help with ? 


   
ReplyQuote
Page 1 / 2