Arduino LM358 Op Amp PWM to Voltage Converter

Creating a DC Voltage using Your Arduino

LM358 PWM to ADC Featured GraphicThe PWM output of your Arduino will work fine in many cases.  Particularly with motors and LEDs.   However, what if you must have an actual DC voltage?   This tutorial will show you how to create that analog voltage using an LM358.

You will need that Op Amp or one similar, along with a resistor and a capacitor.

Now, I’ve attempted to give you a functional description of the circuit, not only to aid you in understanding,  but also so that you get a sense for how you may wish to tweak it.

That said,  do feel free to jump right to the tutorial.

Get an LM358

eBay     Amazon     Bang Good     IC Station

The LM358 Op Amp PWM to Voltage Converter

The circuit presented uses an LM358 Op Amp in a Non-Inverting Voltage Follower configuration.  If you’re unfamiliar with Op Amps,  you can read an easy to follow description HERE.

It also uses resistor and capacitor in series to form an RC time constant that charges to the desired voltage.

You could omit the op amp,  but it has some advantages.  For one, it has a nice high output impedance.  Second,  it offers a degree of protection for your Arduino.

LM358 PWM to Voltage

PWM to Voltage Converter Functional Description

The image and text below serve to give you a sense of how this circuit works.

ARDUINO LM358 PWM to ADC Functional Description1)  A PWM signal is applied to the input of the circuit.   Pulse width modulation has few characteristics that are important to us.

  • The first is the period of the signal.  That is two say, how frequently the PWM signal repeats itself
  • Next we’re interested in the amplitude,  or how high the signal goes in volts.
  • Finally, we want to know the percentage of time the signal is on.

2)  Next,  the capacitor C1 charges through R1 to the average value of the capacitor.  The time it takes to charge to this value is determined by the RC time constant.  The values for the capacitor and resistor are largely driven by the time period of the PWM.   Another consideration in resistor selection has to do with maximum current handling capability of the Arduino Output.  The capacitor should also have a voltage rating that is higher than the voltage it is expected to charge to.

  • One time constant in seconds = Value of Resistor in Ohms x Value of Capacitor in Farads.
  • It takes five time constants for the capacitor to charge very close to 100 percent.

3) Finally the Op Amp responds by raising or lowering its output until the value at pin 2 ( the inverting input) is equal to the value at pin 3 ( the non-inverting input).

Circuit Low Pass Filter in More Depth

C1 and R1 in our circuit are in a configuration that is know as a low pass filter.   That means it is designed to pass lower frequencies while blocking higher frequencies.  More it establishes a time constant that allows us to charge to the value of our Arduino PWM output.

The PWM to Analog Converter Charge Time Constant

I’ve selected 4700 ohms for R1 and a 10uF cap for C1.   I did it because it will work and (more importantly) because its what I have around.

Thus my time constant is 4700 * 0.000010 or  0.047 seconds.

When super imposed on a classical RC time constant curve (with a value of 5 volts),  it will look something like this:

PWM to Voltage RC Time Constant CurveThe PWM to Analog Converter Discharge Time Constant

To get a sense for how the low pass filter interacts with the PWM,  it also useful to look at the discharge time constant.  The curve is the inverse of the charge curve.

PWM to Voltage RC Discharge CurveThe PWM Signal Characteristics

There are two default frequencies in the Arduino Uno PWM.   One is 490 Hz and the other 980 Hz.   I’m using a digital  PWM pin with a 490 HZ output.   The time it takes for it to complete one cycle is determined by calculating the inverse of the frequency:

Time in Seconds = 1 / Frequency in Hertz

Therefore the period is 1/490 or approximately 2 mSec.

If we select a 50% duty cycle,  the timing will look something like this:


PWM Period Duty Cycle

Notice how the output of the PWM falls low after 1 mSec.  At this point in time, the capacitor begins discharging.

How the the Low Pass Filter is Charged

So we have a capacitor that takes 235 mSec to charge and PWM that is only on for about 1 mSec.    One the surface, you might conclude that it will never charge up.   However, if you examine the charge and discharge curves a little closer,  you will see that it does charge (albeit slowly) in a pattern that looks like a warped stairway.

Start with the first charge cycle

In that millisecond of time, let’s estimate what the capacitor will charge to.

Let’s cheat. Go to the online calculator found HERE.  Insert the resistance and capacitor values, enter 5 for the supply voltage and enter 1 mSec for the time.

You will see that after this first millisecond the the capacitor will have charged to 0.1053 volts.  (about 2.1 percent of).

Examine the first discharge cycle

Now when we start the discharge cycle,  we have 0.1053 volts across it;  not five volts.

Let’s go to another online calculator found HERE.   Enter the 0.1053 volts and the other values.  Be sure to enter the time.

You will see that in that the capacitor has only lost about two percent and is sitting at about 0.103 volts.

Second Charge Cycle

In the second charge cycle the voltage across the cap starts where the first discharge cycle left of or about 0.103 volts.

Go back to the online calculator for charging caps.  Set your supply voltage to 5.0 – 0.103 volts ( or 4.897 volts).  You will see a result of 0.103 volts.

This value is what is added to the 0.103 volts that we already have.  Thus at the end of this charge cycle we will have about 0.206 volts.

Second Discharge Cycle

Go back to your discharge calculator and you will see that you lost another 2 percent.. putting the value across the capacitor at about 0.201 volts.

Completing the Low Pass Filter Charge

This ‘step’ process continues until the capacitor charges to about 2.5 volts.  It will take about ten RC time constants to get there ( about half a second).

When it gets there, the small charge and discharge cycles will continue.  Using an oscilloscope, you will see them riding across the top of the DC value.  My set up yielded about 50 mV of ripple.  I’ll show you how to clean that up in another tutorial.

Arduino LM358 Op Amp PWM to Voltage Out Tutorial

LM358 Pin Outs

You’ll be using an LM358.  If you use an eight pin DIP,  the pins are as show below.

LM358 Pin Outs

Connect You LM358 Circuit to Your Arduino

You will want to use a common external supply that is greater than 5V.  A 9 volt supply would work.    If you try to power the Op Amp with 5 Volts will cap your output voltage to about 3.6 volts.


LM358 PWM to ADC

Copy Paste and Up Load the Arduino PWM to Voltage Out Converter Sketch

The sketch is really basic.   You’re going to cycle through various voltages in three second intervals.


// Henry's Bench LM358 Arduino PWM to Voltage Converter

int pwmOut = 3;  // The output to the transistor that drives the motor

void setup()
  pinMode(pwmOut, OUTPUT);  

void loop()                     
  analogWrite(pwmOut, 0); // about zero volts
  analogWrite(pwmOut, 51); // about 1 volt
  analogWrite(pwmOut, 102); // about 2 volts
  analogWrite(pwmOut, 128); // about 2.5 volts
  analogWrite(pwmOut, 153); // about 3.0 volts
  analogWrite(pwmOut, 204); // about 4.0 volts
  analogWrite(pwmOut, 255);  // about 5.0 volts

Test Your Output

Connect a meter to your pin one on your LM358.   If you observe it long enough,  you will see it march through the programmed values.