Strange behavior from a passive buzzer

I have this test code, which in a stand alone program (first code block) generates the first sound (seconds 1 - 3) made in the audio clip at the link below. When I put the for loop into a function in a larger program, it creates the less pleasant second sound (seconds 7 -12) in the sound clip.

Has anyone else experienced that? What could cause the difference? I noticed from the Arduino documentation link below that the tone function is non blocking? Could it be an issue of competing resources since it is non blocking? I'm not using tone anywhere else in the larger program.

  • This function is non-blocking, which means that even if you provide the duration parameter the sketch execution will continue immediately even if the tone hasn’t finished playing.

#include "pitches.h"
 

int duration = 2500;  // 500 miliseconds
int chimePin = 52;//the pin of the active buzzer
 
void setup() 
{
    Serial.begin(9600);
    while (!Serial)
    {
      ; // Wait for serial to connect
    }

    delay(2000);

    for (int thisNote = 0; thisNote < 3; thisNote++) 
    {
        tone(chimePin, 7777, duration);
        
        delay(100);
    }
}
 
void loop() 
{ 

  // restart after two seconds 
  delay(2000);
}

Here is the function that is generating distorted sound

int chimePin = 52;
void announcementChime()
{
    Serial.println("Entering annoucementChime");
    int duration = 2500;

    //tone(chimePin, NOTE_Chime, 500);
    for (int thisNote = 0; thisNote < 3; thisNote++) 
    {
        tone(chimePin, 7777, duration);

        delay(100);
    }
  
    delay(duration + 1000);
    Serial.println("Exiting annoucementChime");
}

Make this

delay(duration +100);

So the notes don’t overlap

Hello, thanks for the reply. I will keep that in place in case I want to use different notes, however that produces the same result as far as the sound differences.

It sounds correct with the stand alone sketch, but has the unpleasant version when inside of a larger program just as the audio recording shows. I think my root causes is whatever is causing the difference, however I'm not sure what that is.

hello @turbosupramk3

when I compiled it and uploaded it to my arduino, it makes the same sound as you mentioned. I fixed by using a step down converter (5v -> 3.6v) from the gpio to the passive buzzer.
maybe you can try?
regards
Darsh

Shouldn't delay inside the for be at least as long as the tone?
Why 7777 Hz? isn't that anoyingly high?
Does your other code use timers? (Stepper motor libraries do!)

Hello, I dropped it to 3.4v with a resistor ladder and I am seeing the same results, it sounds fine when using the stand alone code set, but distorted when using inside of a larger project.

@build_1971 It is annoyingly high, it's meant for my dog to hear, I might even try to go higher once I can get this working, however I don't believe this buzzer can generate noises outside of the human hearing range.

Could you post the full sketch?
Or a minimum compilable sketch that has the same problem?
Often the problem is outside the code that problem owners share...
Is there any interrupts used in your larger sketch?
I asked about the 7777 Hz because it is named chime. And I do not know the exact definition of a chime, but 7777 Hz is probably outside that definition.
And I would not be surprised if your piezo can go far beyond what you can hear...

I actually only want to generate a single chime noise for a single duration. It would take me a few hours to trim down to a compilable smaller code set, which may be the route I have to go.

I put a DMM on the pin and it read some voltage in between pulses, however even when I have a line of code like this without a loop tone(chimePin, 7777, duration); it will still generate an alternating noise. I'm not sure why it doesn't do that in the stand alone example, however I think I've misunderstood the tone command as I reread through the notes and I see the below, which fits the pulsation I'm hearing. I'm going to see if there is a way to generate a continual frequency at 100% duty cycle or an adjustable duty cycle.

Generates a square wave of the specified frequency (and 50% duty cycle)

50% duty cyclle is 50% of time high and 50% of time low.
You won't hear a 100% tone as the pin willl be high continously.

Right, but that's what I am after, a continuous 3 second duration higher pitched sound to alert my dog, at the frequency I choose.

Strangely enough, the stand alone code set allows for this.

So what is the 'for' for then?

That was for testing. The original example I found played scales and as I modified it I was trying different things and left the for statement in. It could realistically be the following.

Are there any piezo buzzers that I could buy that can play a single tone for the duration of my choosing, that work well with the Arduino or with the Arduino and a 2n2222?

int chimePin = 52;
int duration = 3000;
tone(chimePin, 7777, duration);

What kind of buzzer do you have? Is it an active buzzer (one that buzzes with 5V only) or a piezzo speaker (where you need to send some wave form to make a sound)?
The first one will not work for you.
The other type should work.
I cannot recommend you a specific piezzo speaker, as your current one should work (if it is the second type).
You did not show us the rest of the code, so we cannot check for other libraries that use the same timer.

Hi,

This is the passive buzzer description from the kit.

I will work on getting something trimmed down and usable, that still generates the sounds in the recording, so that you can see that code base. I appreciate you sticking with me on this.

That buzzer should be ok!

Could you share a picture of your setup?

Sorry it's spaghetti. While starting to shrink my code down to a minimum working example for you this morning, I discovered a smoking gun. When I comment out GPSSerial.begin(9600); in my setup function, the buzzer plays correctly.

I haven't trimmed hardly any of the functions out yet, would you like me to continue removing them and ensuring it complies or is that information sufficient? It's defined as SoftwareSerial GPSSerial(11, 13); so I'm going to speculate that the SoftwareSerial has interrupts or timers that are interfering? The wire going to the piezo goes off screen, but it's the one that connects to pin connection spot 52 on my Arduino Mega, right next to the yellow wire that is in 53 on the bottom left.

I am not an expert on softwareSerial, but I know that the normal Serial also uses interrupts. So, big chance...
Is there GPS on the other side of the softwareSerial?
Could you stop that from communicating during your buzz?

What is the black wire in hole 40 doing?
The resistor is in 39...

Those both were for an LED that I removed temporarily.

I don't know how I can stop the SoftwareSerial while I'm trying to play the tone or if that is even possible. One idea I had was to use an open hardware serial port since my Mega has 4 of them and I'm only using one currently, however leaving the rest the same, the below code doesn't generate any gps data? Is the syntax correct?

#define GPSSerial Serial2

How do you expect anyone to know the answer from this tiny bit of code?
And why do you expect this line of code to generate a tone?