I am looking for a way to create a true analog output with the arduino uno. I am constantly reading an analog input on a0 pin, all i want to do is send the same signal as output. I know arduino convert the signal into pwm so have can i convert it back to true analog signal.I have a dac too but not getting proper output.

secondly, i want to send same signal by converting it into bits through Ethernet so how do i send and receive the signal.

here is my code for dac.

#include "Wire.h"
#include "MCP4725.h"
MCP4725 MCP(0x60);
uint32_t microphonePin=A0;
uint32_t threshold=800;
const int ledPin=13; 

void setup() {
    pinMode (ledPin, OUTPUT);
    Serial.print("MCP4725 test program: ");
    if (MCP.begin() == false)
       Serial.println("Could not find sensor");


void loop() {
   uint32_t sensorValue=analogRead(microphonePin);
   if (MCP.getValue()>threshold)
      digitalWrite (ledPin, HIGH);
   else{ digitalWrite(ledPin, LOW); }


here is my circuit for audio amplifier

here is my circuit for audio amplifier

and for the speaker it is connected on DAC out.

FYI:I am able to read the data on my serial monitor form mic and i am also able to so do some operation by just using mic and GUi. I just want to here what i am saying on speaker.

  • you cannot output the same signal as intput, because you are not reading all of the input signal ... you are reading only intermittent samples of the input signal
    – jsotola
    Commented Mar 4, 2021 at 5:18
  • using those value i want to create if not the same signal then approximately same signal Commented Mar 4, 2021 at 5:40
  • 2
    Can you describe how the signal you get is different from the expected signal? What frequencies do you need to process?
    – PMF
    Commented Mar 4, 2021 at 5:51
  • i have connected mic with amplifier circuit on my analog pin a0 now i want that send that signal to the speaker which is connected with dac. DAC is connected With A4 and A5 pin. Commented Mar 4, 2021 at 7:24
  • 1
    Why are you connecting the speaker with the mic through the Arduino? Why not connecting the mic amplifier circuit directly to the speaker amplifier? The Uno is not really made for audio processing. You can do some, but the result is not very good. And you give it an unnecessary workload with also outputting the digitized signal as analog.
    – chrisl
    Commented Mar 4, 2021 at 8:31

3 Answers 3


I see that MCP4725 uses Wire library with the default clock of 100,000 kb/sec.

At a rough estimation each call to MCP.writeDAC or MCP.getValue will be at least 32 bits long and you use three of them in each loop.

This one:

   if (MCP.getValue()>threshold)

is redundant, you should store the value in a temporary variable and use-it in both "print" and "if".

With 10us for each bit that means 1060 us for each loop. The analog read also takes 100us to complete. Over all 1160us minimum. Is the MCP.getValue() really needed?

That means that your maximum sample frequency is 860hz and the maximum bandwidth of 430hz. I doubt that this is an acceptable bandwidth for a microphone.

Even so, the output signal will not look similar at all, you need a higher bandwidth or to limit, if possible, the bandwidth of the input signal.

In some limits you can modify the MCP4725 library to use fast wire clock four times faster if it suits your requirements. If you also drop the two MCP.getValue() calls that will be again almost three times faster, up to 5khz.

Also you might search for faster ADC on Arduino.

Update after OP microphone amplifier schematic.

The ADC works only with positive voltages. Short the output capacitor of the amplifier!

  • Hey, thanks for reply i have removed those two line only difference is their is less high pitch noise but i am not getting desired output. Commented Mar 5, 2021 at 4:19
  • @eTollSystems Oh!!! Now I see the other big flaw in your design!!! The ADC is not working with negative voltages!!! See the updated answer.
    – Dorian
    Commented Mar 5, 2021 at 6:46

If you want something simpler than the transistor version you can use the following as well, for the other options skip to the --here-- mark

Oldstyle analog out. this works like a vacuum tube and while I use a LDR you can also use heat or a actual vacuum tube.

You Will Need:

  1. A low resistance LDR or multiple in parallel.
  2. A cardboard box or other box to isolate it from outside interfearance.
  3. A Led or light bulb.

How this works: while a led flashes, a LDR needs a certain time to just to values(often up to around a few ms), so this will stabilize your adc signal.

You send the desired amplitude as a pwm signal to the light source(you probably want to invert your pwm signal) which aims at the LDR. you send your sound frequency through the LDR which now works as a variable resistor.

!!Use low resistance LDR's and a bright light source to get a as low as possible resistance. with (weak)lasers, you can get a normal LDR down to around 1 to 0 ohm. but you will most likely use a led since that has more precise intensity control. Ancient style analog out like vacuum tubes

Another simple method is the inversed of analog read in an Arduino. you basically use multiple output ports with different resistances to get a different output when done right in this case you can get around 257 different volume levels with 8 pins for the amplitude and 1 for the frequency.


--added this here as a simple explaination/guide-- first start with getting your microphone working, see if analogread get's some high values. if it stays at 0, 1 or another low value, then you didn't include a transistor with your microphone to boost the signal.

-For your output start with a project without a microphone to see if it is working right. you will need to use 2 pins to power your output(excluding ground, assuming single-channel audio). -the first one you will need for your frequency signal output. the other one is for the amplitude/volume/gain. -We will use any type of amplifier(transistor) to merge the signals, in this case, I assume a transistor since they are cheap, simple low power, have an easy dynamic range and you most likely have them already.

-this following part can be done in 2 ways I would suggest to try way 1 first since it is most simple, logic, and fast which is great on a slow which is great in a small microprocesssor. where method 2 might seem the exact different way around but is much more precise.

Method 1: connect the frequency output pin to the emmitor pin of the transistor where the + normally goes in. Connect the amplitude output pin to the base pin of transistor(the trigger) add a very small capacitor(or a bigger one for tests) between the base and ground this is to convert the adc in analog voltage instead of pulses. the collector of the transistor which you would normally connect to ground is your output. you might want to add a small resistor after it especially if you are using it for a audio cable. you can also directly connect a very small speaker to hear the sound for a cable(be careful withconnection arduino IO to things like a pc) you connect the output as oudio signal and the ground as ground. but check what voltage the other devices audio port supports since arduino's IO pins generate 5v

method 2. connect the frequency out pin to the base of the transistor, connect the ADC of the amplitude pin to the emitter pin of the transistor, connect a capacitor of larger capacity than described in method 1 between the emitter pin of the transistor and the ground of the Arduino. the collector is again your output, you might to as a resistor to it. connect a wire from an analog port to the emitter pin of the transistor to read out the voltage in the capacitor for precise voltage regulation.

tinker with the values of the capacitor size. (you now have an energy pool in front of the transistor if you know the ampere on which you are outputting you can use this to regulate the pool, otherwise you can read it using the analog feedback loop). important to know is that if you want precise volume you use a larger capacitor, if you want fast volume differences you use a small one and intentionally use more pins to charge it. for an Arduino Uno due to low analog read speeds, I would recommend a larger capacitor or this.

extra stuff when putting your complete system together you might run into speed issues. you should therefor connect the microphone to both a digital and a analog pin. the digital pin constantly monitors the frequency and the analog pin measures the amplitude sometimes(add a small capacitor get that average amplitude). I would also recommend turning down the analog read precision to prevent checking for all 1024 possible voltages.

for method one you can also add a extra resistor from base to ground and from the amplitude pin to base so you can more precisely calculate the voltages.

--end of simple version--

You can try to use 2 pins for the output signal. one of them sends the frequency digital(3 pins if you also want negative polarity audio). this output signal should go to something like a transistor or a digitally controlled potentiometer or amplifier. I will assume you use a transistor since those are most common and quite fast. the first digital output pin should go to the emitter pin of the transistor the second pin is used for the volume and will go to the base of the transistor. you might want to add a very small capacitor between the base and ground to reduce frequency interference(to prevent the ADC frequency from showing up in your signal). the Collector pin would be your analog output suitable for audio.

So in basic steps:

  1. split the signal into a digital frequency and volume. (the digital frequency can be made by seeing a signal above a certain value as high and the other as low, this works best when you use both the positive and the negative side of the soundwave otherwise you will need to chose a very low number)(the analog frequency is literally your analog value for the positive only audio, and value-512 (*-1 for negative numbers to get only positive numbers) for the full audio if you include the negative audio)
  2. Send the frequency signal to the emitter pin of your diode.
  3. Send the amplitude signal to the base pin of your diode.
  4. Connect a small capacitance between the ground and the amplitude signal.

however What Dorian said are things you might want to keep track of as well since they often indeed tend to kill of such projects because you very easily run into speed limits(analog read in a arduino ar basically 1024 digital reads(literally)).

So some tips for your cirquit:

  1. If your microphone doesn't have a transistor connected to boost the signal add it since otherwise the analog port of the arduino uno is not sensitive enough to measure the signal. you can and should fist test this using a project where you constantly analogread and print it. you can add a small capacitor between the analog port and the ground to just measure the voltage.
  2. use diodes to rectify your microphone signal, your arduino can only read positive voltage, the microphone also sends negative voltage. redirect the negative voltage to the arduino ground (you can invert the negative voltage using a transistor or some other methods to read the negative voltages as well, but I would recommend just sending the negative signals to ground since this would give the near full range as well)
  3. use 2 microphones one for frequency and one for amplitude. or connect the output of your microphone to both a analog and a digital port. you might in the last case want to use resistors to lower the current going to them this makes sure both get a accurate voltage.
  4. avoid as manny analog reads as possible, storing it is better than calling it twice
  5. use c/c++ bitmanipulations for IO, not only is it more easy to program larger systems when using them, they are also a lot faster( arduino uno has the PORTB, PORTD, PIND, PINB, DDRD, DDRB, and the a and c version(however you most often only use the D and B) predefined. bitmanipulations require very little knowledge compared to other programming methods as long as you know the port addresses, which again for the arduino uno are predefined search: arduino uno bit manipulations or arduino uno PORTB.
  6. you can sample the sound frequency using a digital port at a higher frequency than the amplitude. since sound often doesn't jump to fast in amplitude in a way that you would clearly notice. this means you could read the sound with a IO pin and write it on another IO pin, additionally you could once every interval measure the amplitude to use which makes your code a lot faster.

there are way more ways but these are easy to do. for sending it trough internet however you need to be careful that the module you use processes those things itself so that you do not just connect a internet port since that would slow your system down even more.

For those wanting a ms paint sketch:

version one: Version one resistors are optional, feedback look can be added

version two: Version 2 can be made without resistors or feedbackloop

note that I just used random images from the internet you can use any capacitor and transistor that works for this, I did not check if this transistor is right for this, but it had a nice layout description in the image. the capacitor doesn't need to be ceramic, but this way you see clear legs and I don't need to focus on polarity. in general, all cheap 5v compatible transistors should work and all capacitors if they are not way too big or too small for your load.

I used descriptions rather than logos, so anyone should be able to read it as long as they have software to tell the differences in colour if they are colourblind.

How it works The transistor sends the voltage from the emittor to the collector(or the other way around based on the transistor you use). so in method 2 which also works for mosfets. we send a adc signal to the capacitor to charge it to a voltage, you should however also add a resistor to ground or a cable to a analog port, because otherwise the voltage can just build up to 5v. this capacitor which we charge becomes a analog power source. we connect it to the emmitor(or pin which you normally connect on the + side). so if we where to open up the transistor(close the cirquit) by putting a positive voltage on the base or trigger pin then you would get a output of the voltage that you put into it. so if you play the frequency digital on the base completely opening and closing the transistor then you get a voltage output similar to the voltage in the capacitor. method one works more difficult but a transistor opens up relative to the current going from base to exit, so we use the pwm and a small capacitor to get a analog voltage on it only partly opening it, then we send the digital audio signal into the pin that you normally connect to 5v and you get that frequency payed with the transistor acting as a variable resistor So method one uses a transistor as a variable resistor And method two uses the transistor or fet as a switch which uses the voltage build up in the capacitor, doesn't actually need to use pwm if you use a feedback loop. Basic True analog without the transistor to create the frequency(for method 2 only)

  • i will work on it to see if it give desire output. Commented Mar 5, 2021 at 4:33
  • mic is working fine. I am not able to understand what other frequency you are sending to the transistor. one will be mic output through arduino which will be pwm data. Commented Mar 5, 2021 at 6:42
  • @eTollSystems the pwm data is used for the amplitude/volume only. since pwm sends a digital frequency that would show up as sound as well and only does it X times a secon, we can't use pwm for the audio signal. Commented Mar 5, 2021 at 8:45
  • @eTollSystems the signal pin is used to mirror the frequency/sound the mic hears. so you send out the sound digital. and use the pwm for the volume. Commented Mar 5, 2021 at 8:48
  • @eTollSystems so if your mic would give these signals: 0,382,890,3,999,4,439,0 then you could for example say everything above 200 is high and all other is low. if you use a digital pin to read the mic it will be a lot more easy that way you can just ask if it is high or low( you can connect the mic to both a analog and a digital port(just add a resistor towards the digital port)) Commented Mar 5, 2021 at 8:51

for your case(audio) there also is https://github.com/connornishijima/arduino-volume1 or the volume library to install it you can use the git to get the files, or if you use the arduino ide, you can open the arduino ide and in the software go to helptools(4thoptionoftopmenubar)->Manage Libraries-> {type volume in the search bar}-> install the library called volume. you can also chose volume 2 or volume 3, see the git for the differences.

this however still uses micro pwm, so it is not true analog, but for audio it works. also note that on low volume the audio will be affected. I recommend only using the volumes between 100 and 255.

this method requires no additional hardware, and works well for audio, to send the audio to other devices however I would just send the audio values and not the audio output.

NOT TRUE ANALOG, but it solves your problem, the methods I described in my other answer will work well for most other analog cases, or even adding a small capacitor at that ma output might work in many cases. however since audio needs the voltage to change really fast this method works well, also since the volume is read by your mind instead of a digital device it has a normalization filter built in and a low sampling speed as well as sensitivity to only low frequency(how human brains and ears work) which will make the volume sound natural.

If you have a separate arduino for the volume or a well optimized code you can also avoid interrupts to get a higher frequency, this method is harder and requires you to know what your code does but allows for better quality volume(speciffically at low volume levels)

alternatively you can use a shiftregister and connect resisters to the outputs, for example 12800, 6400,3200,1600,800,400,200,100. like a bit but reversed, since the audio gets louder with a lower resistance. you can use other values, just don't make them to low, since arduino outputs 5v and 3.3v, both are much higher than your average headphone connection, also turning on multiple parallel resistors at once gives a lower resistance. for example if we turn on the 100 ohm and the 200 ohm resistor we get a output of around 66,66666666 ohm since the output is 1/((1/Resistor1)+(1/Resistor2)+(1/ResistorETC) like this a singe 8 bit shift register can deliver 256 different volume levels as true analog. if you have ports free on your ardruino you can also use those instead of a shift register, however be sure to use bitmanipulations and not digitalwrite, since the later one is slow. 1 pin = 2 volume levels 2 pin = 4 volume levels 3 pin = 8 volume levels 4 pin = 16 volume levels 5 pin = 32 volume levels 6 pin = 64 volume levels 7 pin = 128 volume levels 8 pin = 256 volume levels etc. this method can give true analog voltage if you know the resistance at the output, a speaker however differs in resistance based on many factors, but doing this will still give you good volume control like actual analog voltage, even though it is actually more analog amperage. to get voltage content the terminal connected to all the outputs of the resistors to another resistor to generate a voltage divider, this works for things like vga displays, however for things like audio, lights, etc. you should jus directly take the output of the resistors

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.