2

I am using Arduino's tone() function to produce some basic tunes. However, tone() does not have volume control.

I did post about this in the Arduino Stack Exchange web site as well. User Majenko said that

The tone() function generates a 50% duty cycle square wave using a timer and interrupts. 50% duty cycle is basically full volume. An alternative is to do it in hardware. You can use an op-amp as buffer (or speaker driver) and a couple of resistors (or a potentiometer) as an "attenuator" before it to change the voltate of the signal going to the op-amp. You need the op-amp as a buffer because the speaker will mess with the potentiometer otherwise.

I am not so experienced in electronics and i do not understand what he means. I want to try this. Can anyone help me out with the schematic of this configuration?

There is one digital pin going to the positive end of the speaker. The negative end of the speaker goes to Arduino's GND. Can someone explain how this topology should be?

user1584421
  • 1,259
  • 2
  • 17
  • 32

1 Answers1

2

I believe what the author is trying to say is this:

schematic

simulate this circuit – Schematic created using CircuitLab

The potentiometer is used as a voltage divider, to provide a signal at node X with amplitude variable between 0% and 100% of the full 5V/0V digital output from the Arduino.

If you were to connect a low-impedance speaker to X, it would seriously mess with the nice proportionality between potentiometer position and signal amplitude. He is suggesting using an op-amp voltage follower to drive the speaker, and isolate it from X.

You could achieve a similar result with a single transistor "emitter follower" instead:

schematic

simulate this circuit

If you don't need manually variable volume control, then a simpler solution would be:

schematic

simulate this circuit

The value you choose for R1 would depend on the impedance of the speaker, and the volume you desire. Without more information about the speaker, all I can suggest is that you experiment with different values until you get what you want.

If you are trying to control volume in software, that's a very different problem to solve, and none of these ideas are appropriate.

Simon Fitch
  • 27,759
  • 2
  • 16
  • 87
  • if the audio signal comes out at a DC level of Vcc/2, you definitely need DC block caps here. – danmcb Jun 30 '22 at 06:56
  • Thank you so much for this beautiful and detailed answer! I will try these methods when i buy the necessary components and i will report my findings. BTW, i am using this speaker: https://www.visaton.de/en/products/drivers/fullrange-systems/k-50-8-ohm. This is an 8 Ohm speaker, so how exactly the resistance should vary based on the speaker impedance? Thank you very much! – user1584421 Jul 04 '22 at 08:07
  • @danmcb Thank you very much! Where exactly should they be placed in the circuit? BTW, i have another problem, that there is heavy clicking involved. (Question is here: https://electronics.stackexchange.com/questions/625147/remove-clicking-from-speaker). Can this DC blocking capacitor help me with the mitigation of this problem as well? From comments i read, i got the impression that a capacitor can help me. Thank again! – user1584421 Jul 04 '22 at 08:09
  • @user1584421 You can't drive an 8Ω speaker directly from the Arduino, or an op-amp, that's far too low, and may cause damage to the IC. You must put at least 390Ω in series with the speaker, which will heavily attenuate the volume, or consider an LM386 circuit, for such a low impedance speaker. – Simon Fitch Jul 04 '22 at 15:01
  • @SimonFitch What exactly are `8&Omega` and `390&Omega`? `that's far too low`.. What is low exactly? Is there a speaker that works great with the arduino? I thought about it as well, that the speaker selection might be wrong. I didn't put any thought to this (not experienced with audio electronics), i just got whatever i found. – user1584421 Jul 04 '22 at 21:48
  • @user1584421 Sorry, I thought the comments used the same &xyz; escaping for certain characters, and didn't read them back to check. Ω is Ω. I meant 8Ω and 390Ω, my mistake. – Simon Fitch Jul 05 '22 at 02:03
  • @user1584421 You can't get much more than 20mA or maybe as low as 10mA out of a digital Arduino output, or a typical op-amp, check the datasheets. Whatever resistance you load it with, it shouldn't be less than about \$\frac{5V}{10mA}\$ total. I estimated 400Ω is a realistic lower bound. For example, if you have a 64Ω speaker, you should put something like 330Ω in series with it to total 394Ω, to avoid overloading the IC's output. – Simon Fitch Jul 05 '22 at 02:13
  • @SimonFitch Got it! Thank you! So for the 8Ω speaker example, the resistance should be close to 392Ω. What if i use an audio preamp before the speaker, instead of resistance? Like the LM386? – user1584421 Jul 05 '22 at 21:43
  • @SimonFitch In that case, i completely omit the resistance? – user1584421 Jul 05 '22 at 22:04
  • @user1584421 Yes, the LM386 is a good way to go. Remember it has a gain of at least 20, so you'll have to attenuate the signal with a voltage divider at its input. You should probably aim at dividing the 5V Arduino output by about 100, for something that isn't stupidly loud. There are a thousand sites showing you how to wire up an LM386 with an 8Ω speaker. – Simon Fitch Jul 07 '22 at 12:43
  • @SimonFitch Thank you! By the way, i tried the resistance approach. I selected one closer to 398Ω. The clicking was still highly audible, although the volume was highly diminished due to the resistance. In a different approach i tried 220μF, 330F and 470μF capacitors to the positive rail of the speaker, in order to block DC. There was no effect on the clicking. I don't know what to do at this point... Just the LM386. – user1584421 Jul 07 '22 at 20:31