Tone() library distorition on NRF

Hi, I have a sketch that plays a simple tune using the tone() library. It took me a little while to discover that if you try to play a tone for a duration and then a delay() for a duration, the delays will be overrided. Because the tone library is non-blocking, the tone will start sounding, then immediately the delay() will start (which is blocking), but if the tone isn't finished before the pause is finished, there will be no pause i.e. they are happening simultaneously. If you want to have the pauses between notes be honored, you have to make the delay() period be the sum of the note duration and the intended pause. So the simple tune sounds mostly right now... but there's still a problem. The first few notes of the melody are distorted but after a while get straightened out. I think there is still some conflict between the delay() which is supposed to be blocking, and a timer somewhere that's running the tone() library. If you have an NRF based Arduino and a buzzer/speaker lying around, try out this sketch and let me know if you have distortion on the first few notes. If so, any idea how to resolve it?

const int Buzzer = D6;

unsigned int Tones[16]
  = {415, 329, 369, 246, 246, 369, 415, 329, 415, 369, 329, 246, 246, 369, 415, 311};
unsigned int Durations[16]
  = {700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 800, 900, 1000, 2000};
unsigned int Pauses[16]
  = {20, 20, 20, 1400, 20, 20, 20, 1400, 20, 20, 20, 1500, 40, 50, 60, 2100};
int lastStep = 16;

void setup() {
  pinMode( Buzzer, OUTPUT );
  Serial.begin(115200);
}

void loop() { PlaySong(); }

void PlaySong() {
  for ( int i ; i < lastStep; i++ ){
    tone(Buzzer,Tones[i],Durations[i]);
    delay(Durations[i]+Pauses[i]);
    noTone(Buzzer);
    }
  delay(2100);
}

Set the initial value of i to 0. Edit your code like this:

const int Buzzer = D6;

unsigned int Tones[16]
  = {415, 329, 369, 246, 246, 369, 415, 329, 415, 369, 329, 246, 246, 369, 415, 311};
unsigned int Durations[16]
  = {700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, 800, 900, 1000, 2000};
unsigned int Pauses[16]
  = {20, 20, 20, 1400, 20, 20, 20, 1400, 20, 20, 20, 1500, 40, 50, 60, 2100};
int lastStep = 16;

void setup() {
  pinMode(Buzzer, OUTPUT);
  Serial.begin(115200);
}

void loop() {
  PlaySong();
}

void PlaySong() {
  for (int i = 0; i < lastStep; i++) {
    tone(Buzzer, Tones[i], Durations[i]);
    delay(Durations[i] + Pauses[i]);
    noTone(Buzzer);
  }
  delay(2100);
}

Thanks, yes that's more proper.

I think my continuing problem is a defective buzzer. I'm not having the same issues with a small speaker.

Allright, In case some intrepid future buzzer user is having this sort of problem, I think the answer is that this is neither a passive piezo buzzer, which was the description, and not an active/amplified buzzer, but instead a magnetic buzzer. As I read this article, it's not unlikely that this buzzer can "enter resonance with external disturbances and deliver a current induced by the coil, which would be reinjected into the circuit". I've certainly experienced what sounds like feedback and my Xiao has locked up from it. So, going to try to more definitively identify what I have here and make sure the circuit is appropriate for it. Article: https://techexplorations.com/arduino/how-to-use-a-buzzer-the-correct-way/

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.