2

I have a simple circuit that makes use of the tone() function to produce some sounds. I also have a button, hooked with an interrupt function, that whenever is pressed, a variable changes.

Sometimes, when the button is pressed, a high pitched sound is produced. What is weird is that this does not happen every time.

You can take a look at this simulation: https://wokwi.com/projects/291958456169005577

If you press the buttons continuously, you will hear the sound.

Why is this sound triggered? Is there a way to mitigate this? Perhaps making changes to the tone() function? Or perhaps placing a low-pass filter - as this seems like a high frequency sound?

8
  • I do not hear anything out of ordinary in the simulation ... does the same thing happen with hardware?
    – jsotola
    Apr 20, 2023 at 15:28
  • 1
    what kind of actuator are you using and is it the actuator itself that produces the unwanted sound (and not a coil or something like that)? The tone() function generates a square wave and according to Fourier theory a square wave naturaly contains a lot of higher harmonics. If you have an unsuitable actuator which resonates at those harmonics, it could explain such a behaviour...
    – Sim Son
    Apr 20, 2023 at 16:15
  • @jsotola If you press the buttons (say do it 20 times), you will for sure listen to some glitchy sounds when pressed, at some point. Yes, the same thing happens with hardware (which means the emulator is amazing, i guess). Apr 20, 2023 at 21:23
  • @SimSon I am just using a pushbutton... Apr 20, 2023 at 21:24
  • 1
    put delay(1); after the tone ... checking why that works
    – jsotola
    Apr 21, 2023 at 1:24

2 Answers 2

4

Here is the result of my investigation.

The problem is caused by two factors.

First one is the contact bounce of the switch.

Second one is inadequate pullup strength at the switch, but this may be a simulator issue.

The attached picture shows the data that was captured by the Wokwi logic analyzer module.

The top trace pair shows the tone when the switch bounce is turned off in the simulator.

The rest of the traces are labeled.

enter image description here

2
  • Thank you so much for this investigation! I did manage to solve it by using the solution you provided in a comment. Specifically, i used delay(1); after tone(). Apr 23, 2023 at 19:30
  • proper switch debouncing is the real solution ... ignore switch transitions for 5 ms after the initial transition
    – jsotola
    Apr 23, 2023 at 23:23
1

My explanation for this issue is that the last pulse generated by the tone() function is interrupted while the output is on a high level. This results in the last pulse being shorter than it should be to correspond to the desired sound frequency.

enter image description here

While the pulse length doesn't matter for a continuous output (where the pulse frequency determines the sound frequency), a single short pulse can be interpreted as a pulse of a higher frequency. According to Fourier theory at least its fundamental frequency will be higher than the one of the longer pulses.

Observations that might substantiate my theory:

  • the issue happens randomly in ~50% of the cases (for a 50% duty cycle signal).
  • the frequency of the erronous tone varies and is always higher than the desired frequency, depending on how short the trailing pulse is.

These seem to be the case for the simulation.

Possible fixes:

a) provide the tone() function with the optional duration argument and hope the library itself addresses this problem (which it actually might not as the issue is even in the simulation)

b) make sure to only use multiples of the square wave period for duration, so the wave always stops on a low level

According to my theory, a low-pass filter will not work as a fix because the fault frequency can be close to the desired frequency and is the "primary signal", not just some low amplitude harmonic which would be easier to filter from a (much stronger) fundamental.

1
  • 1
    Thank you so much for taking the time to investigate and create drawings! I solved this issue using jsotola's suggesting and placing delay(1); after the call to tone(). Apr 23, 2023 at 19:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.