Arduino’s AnalogWrite – Converting PWM to a Voltage

D-A_converter

D-A_converter

When I first started working with the Arduino platform (it was also my first experience with microcontrollers), I was a little surprised that analogWrite didn’t actually output a voltage, but a PWM (pulse-width modulated) signal. After all, the ATmega had a A-D (analog to digital) converter along with Arduino’s analogRead. The complementary analogWrite function was there, but no D-A (digital to analog) converter on the AVR chip itself. Fortunately, there is an easy way to convert a PWM signal to an analog voltage. To do so you only need to implement a simple single-pole low pass filter. Does it sound complicated? It isn’t. There are some great online tools to help. Once you learn how to make one, you can quickly and easily output analog voltages from not only the Arduino, but PICs as well as any other microcontroller that has PWM output.

PWM Primer

Pulse width modulation (or PWM as it is most commonly known), is a way of encoding a voltage onto a fixed frequency carrier wave. Commonly used for radio controlled devices, it is similar to FM (frequency modulation) or AM (amplitude modulation) in what it accomplishes. Each type of modulation scheme has its own advantages and disadvantages. AM modulation was the first type of modulation used for radio transmissions. It is the most simple modulation scheme to implement, requiring only a single transistor or vacuum tube amplifier as was done in the early days of radio. However, it suffers from excessive noise and therefore, FM modulation was invented. In this modulation technique, the voltage signal is no longer related to the strength of the signal. That is why FM radio has superior noise and fidelity qualities over AM radio, though it is not as simple to implement in circuitry.

With the need for digital communication, a new modulation technique was invented – PWM. This technique shares the same noise immunity as  FM, to which it is very similar. The biggest difference is the simplicity and digital nature of the modulation. Instead of varying the modulation frequency with voltage, an output is merely switched on and off at a fixed frequency. The percentage of the on-time is in proportion to the signal voltage. To see better what this means, let’s examine what a PWM signal looks like for various levels. In the following image, the duty cycle is the output value from the PWM pin of an Arduino divided by 255:

PWM example graphs for Arduino

PWM outputs (curtesy arduino.cc)

For the Arduino, you write a value from 0 to 255 on a PWM pin, and the Arduino library will cause the pin to output a PWM signal whose on time is in proportion to the value written.

When it comes time for us to actually write an output voltage, the 0-255 value lacks meaning. What we want is many cases is a voltage. For our purposes, we will assume the Arduino is running at Vcc = 5 volts. In that case, a value of 255 will also be 5 volts. We can then easily convert the desired voltage to the digital value needed using simple division. We first divide the voltage we want by the 5 volts maximum. That gives us the percentage of our PWM signal. We then multiply this percentage by 255 to give us our pin value. Here is the formula:

Pin Value (0-255) = 255 * (AnalogVolts / 5);

Modulating a Signal

In addition to just setting the output voltage, you may need to actually modulate a signal. To modulate a signal, we simply call analogWrite with the value corresponding to our signal voltage. One way to do this would be to read the voltage at an analog pin, and then write it back out. For example:
int pwmPin = 9; // output pin supporting PWM
int inPin = 3; // voltage connected to analog pin 3, e.g. a potentiometer
int val = 0; // variable to store the read value
float volt = 0; // variable to hold the voltage read
void setup()
{
pinMode(pwmPin, OUTPUT); // sets the pin as output
}
void loop()
{
val = analogRead(inPin); // read the input pin
volt =(5.0 * val) / 1023;
val = 255 * (volt / 5);
analogWrite(pwmPin, val);
}

Now in this example, we obviously won’t be need to convert our output voltage back to a voltage, but will instead transmit our modulated signal as it is. If you have an oscilloscope, you can attach it to the output, and a potentiometer to the input and watch your PWM signal change with the input value. There are many applications for PWM modulation, the most commonly being control of servos – either directly by wire or by radio-control. The Arduino has a nice library that handles creating the correct PWM signal for servos. For more information, see the Arduino Servo Library.

Changing the Modulation Frequency

Most microprocessors permit you to change the modulation frequency for PWM pins. The Arduino has its own set default values. For pins 3,9,10,11 it is approximately 488 Hz. For pins 5 and 6, it is about 977 Hz. These values are for a stock Arduino running at 16MHz. You can change these frequencies easily by writing new values to the appropriate timer register. For example, to change the frequency of timer 2, which controls pins 9 and 10, to 3,906 Hz, you would set its register like so:

TCCR1B = TCCR1B & 0b11111000 | 0x02;

On the Arduino website, there is a nice tutorial on setting timer frequencies and their ramifications.

Low Pass Filtering

Now that you understand how PWM works and can even change the frequency, it is time to take a look at how to implement a simple low pass filter. This simple piece of circuitry will convert your PWM output into a voltage corresponding to the percentage of the PWM waveform. You will then have a complete D-A converter for your Arduino or other microcontroller.

RC Low Pass Filter

RC Low Pass Filter

If we examine the circuit on the left, when a voltage is applied to the input of R, the capacitor C will begin to charge. When it is charged, it will cease to conduct current and the voltage at the output of this circuit will match the input (assuming a high impedance load). If you remember that capacitors block DC currents, but pass AC currents, you can see that any DC voltage input will also be output, but high frequency AC voltages will be shorted to ground. For anything in between, i.e. lower frequency AC voltages, they will be filtered according to the R/C time constant formed by the resistor-capacitor network.

While this circuit is very simple, choosing the appropriate values for R & C encompass some design decisions – namely, how much ripple can we tolerate and how fast does the filter need to respond? These two parameters are mutually exclusive. In most filters, we would like to have the perfect filter – one that passes all frequencies below the cutoff frequency, with no voltage ripple. While no such ideal filter exists, we can achieve close to it by using a multiple pole filter. Such a filter would incorporate many components in a ladder configuration. While such a filter has wonderful performance characteristics, its complexity and cost is unnecessary for simple D-A conversion.

In such cases, we only need a simple single pole filter as shown above. We can achieve a reasonable voltage ripple for a single price – a low cutoff frequency. A low cutoff frequency has two ramifications. First, it limits the speed by which we can vary our output voltage. Second, there is a response delay when changing the voltage until the steady-state voltage is reached. For many of the more common applications, this trade-off is perfectly acceptable. Let’s now look at an example.

First, let’s choose our maximum ripple voltage. When we filter this high frequency PWM signal, a small component of it will always make it through the filter. That happens because our capacitor is too small to filter it out entirely. We could choose a very large capacitor /resistor combination that would get a very high proportion of it, but then it would take a long time to reach the proper output voltage as the capacitor charges. That would greatly limit how fast our signal can change and be seen at the output. Therefore, we need to choose a reasonable value for the ripple voltage. A popular application would be to change the voltage of a MOSFET. Since MOSFETs are voltage controlled devices, we can easily drive them with our microcontroller with PWM and a low-pass filter. Any ripple voltage present at the input would also be present at the output. For this example, assume the MOSFET will be driving a non-critical load such as a high power LED. In this instance, we merely need to stay within reasonable limits so the peak current in the LED will not be exceeded. In this case a 0.1 volt ripple would be more than adequate.

Next we choose a capacitor value. While it would seem the next step would be choosing a cutoff frequency (and it normally would be), there are additional considerations such as output load and capacitor cost. If we were only driving the gate of a MOSFET, there would be no output load to speak of. In such case, we could choose a cheap ceramic cap such as 0.1uF and then choose the resistor we need to achieve the cutoff frequency desired. If, on the other hand, we need some current from our output, then we will need a smaller resistor and a correspondingly larger capacitor. For a recent circuit, I found I needed a 2.2uF capacitor to prevent my modest load from altering the output voltage too significantly. Designing this circuit for non-trivial loads is beyond the scope of this article. If you find yourself in such a need, the best approach would be to start with at least a 1uF capacitor and then test how your output voltage changes with load. Increase your capacitor until the load has a low enough effect to be acceptable. Another way to look at this circuit would be to think of it as a poorly regulated power supply. It only meant to convert digital signals to an output voltage; not to drive a load as well. Buffer the output with an op-amp or a FET first. Then drive your load.

For our example, let’s choose a capacitor value of 1.0uF. For driving a MOSFET, you can use something even smaller, but this size will let us have a small load. Next, we need to choose a cutoff frequency or response time. These two parameters are related but not the same. For simple things like driving LEDs, we are more concerned with a response time. Our response time can be pretty generous. Let’s choose a settling time (to reach 90% of the final value) of 0.1 seconds, which would require a resistor of 15K ohms.

You may be wondering how to calculate these values, or others of your own. Rather than delve into a lot of equations, I have found something better. This excellent online calculator does all the hard math for you, calculating cutoff frequency, response times, voltage ripple and other values. It even draws a transient analysis graph for you – displaying your ripple and how the voltage ramps up over time. Here is the output graph for this example:

RC Low Pass Filter Time Repsonse

RC Low Pass Filter Time Response (curtesy http://sim.okawa-denshi.jp/en/PWMtool.php)

Conclusion

You are now armed with the knowledge you need for creating and using your own digital to analog circuit. Such circuits are incredibly useful. My favorite is driving MOSFETs and op-amps. By sampling a current or voltage somewhere, you can then determine what voltage you need to output to create the level of current or voltage you need. By means of such a simple system, you can make your own voltage regulators, current regulators, LED drivers, etc. The possibilities are endless.

If you have any questions about this article, please drop me a note in the comments. If you have any improvements, corrections or additions, please let me hear about them as well.

This entry was posted in Tech and tagged , , , . Section: . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

91 Comments

  1. John
    Posted June 16, 2011 at 2:09 pm | Permalink

    Simple, clear, concise…an excellent tutorial. Thank you.

  2. High Energy Rob
    Posted June 16, 2011 at 6:08 pm | Permalink

    Nice article. Great job.

  3. wilcimar
    Posted June 16, 2011 at 7:53 pm | Permalink

    Hi, I´d like to know if I could use this circuit to convert a frequency to voltage signal from a ignition cable of my car ( by capacitive coupling), for a reliable RPM measuring. thanks.

  4. High Energy Rob
    Posted June 16, 2011 at 8:29 pm | Permalink

    I think you can buy frequency-to-digital converters that would probably work better for a tach. Im also fairly sure that I have seen guages that do this automatically and just require a frequency input. The problem with this circuit is that the signal from the coil on your car is not pulse width modulated, the pulses are always the same length so it wont really work. You could pretty easily turn an arduino into a tach using this circuit on the output though.

  5. Mike
    Posted June 21, 2011 at 4:10 pm | Permalink

    What is the point to this? Most motors handle the PWM just fine. And for applications that need an analog voltage, well…this is only capable of sourcing a small amount of current.

    • Posted June 21, 2011 at 7:49 pm | Permalink

      That’s a good question. For some applications such as the ones you describe, PWM may be just fine. For others, PWM is not acceptable. In these cases you need a low-ripple voltage. When you buffer this voltage with a high-impedance amplifier such as a FET or an op-amp, you can drive any load you like. This application is intended to drive such high impedance loads only.

      One example for this type of circuit is driving high intensity LEDs. For these devices, you can’t just apply a full voltage to them without some sort of current regulation, no matter how short the pulse is. They will burn up. You must create some kind of constant current driver. One way is to use the circuit described and apply this voltage to the gate of the FET. By monitoring the current going through the FET, you can set it to whatever value you like by varying the pulse width.

      Another example would be creating a programmable linear voltage or current regulator, again by using a single FET. You can even create a constant power regulator using this technique.

      Do these examples make more sense of this article now?

      • Posted May 3, 2013 at 1:03 pm | Permalink

        Hello..

        by modulating a signal,

        int pwmPin = 9; // output pin supporting PWM
        int inPin = 3; // voltage connected to analog pin 3, e.g. a potentiometer

        if i use accelorometer.. how about the coding? i dont use potentiometer.

        Thanks

    • Posted July 1, 2011 at 10:52 pm | Permalink

      Thanks alot – your answer solved all my problems after several days struggling

  6. Art k
    Posted November 3, 2011 at 12:08 am | Permalink

    Great article. Do you mind a question.
    I am using the arduino to take two input signals to output a 0-5 volt analog control signal. No real load. Respons time is probably the most critical. What cap and resistor do you recommend?

    Thanks again for a great lesson!!!!

    • Posted December 6, 2011 at 4:29 pm | Permalink

      That all depends on what timing you need. Go to the RC calculator referred to determine them.

  7. Magnus
    Posted November 11, 2011 at 3:25 pm | Permalink

    Could you use this to convert an audio signal to pwn to control a laser which will send the impluse to a photo diode?

    great tutorial :D

    • Posted December 6, 2011 at 4:31 pm | Permalink

      Yes, although you probably just want to send the PWM directly to the laser. Usually lasers are pulsed, not attenuated.

  8. RodP
    Posted November 27, 2011 at 12:50 pm | Permalink

    Hi,

    I’m looking for a circuit that will interpret a signal that changes in pulse frequency and amplitude to drive a small peristaltic pump to deliver a very small amount of liquid. The pulses come from an lpg injector system, namely Prinns. I have a picture of a scope readout showing an example of the pulse but it doesn’t look like I can post it here. Please could you let me know if this might help me with what I’m looking for?

    Many thanks in advance

    RodP

    • Posted December 6, 2011 at 4:34 pm | Permalink

      It sounds like you will need to read your input via an analog pin, do you signal processing on it via code, and then output straight PWM. You won’t need the filter specified in this article at all. Pumps like other motors are usually controlled by being turned on and off, not by sending a reduced voltage.

  9. JStoski
    Posted January 17, 2012 at 6:56 pm | Permalink

    Perfect. Knew I had to buffer the pulses and smooth them out in order to measure the current going through the FETs. Have to control the current _smoothly_, not just max value and off using PWM. Thanks for the link to the single pole filter calculator.

  10. Hannah Herbert
    Posted January 27, 2012 at 10:09 am | Permalink

    Thank you for an excellent tutorial!

    • Hannah Herbert
      Posted January 27, 2012 at 10:14 am | Permalink

      Scott, do you think I could sum digital audio samples using an Arduino and output this value using PWM and the filter you have suggested. Do you think this would suffice to generate a percussion sound like a bass drum or a snare drum?

      Please let me know your thoughts or if you have any better suggestions.

      • Posted January 29, 2012 at 7:21 pm | Permalink

        If you are fast enough :) . You must be able to do your signal processing in time to output your value above the Nyquist rate which is usually considered to be 40kHz for high fidelity music.

        The top frequency for the Timer2 of an ATmega 168 series is 62.5k according to the spec sheet, so as long as you can do your signal processing fast enough to keep up. That would be the trick. Of course you want to make your output filter to be just as fast as well. Lastly you’ll want a high impedance load such as an op-amp or MOSFET in order to make a fast filter.

        I hope that answer makes sense and isn’t too technical. I would begin by designing a filter you think would be fast enough and try doing some tests – both with an oscilloscope and your ears. — Best wishes on your project.

  11. Ajay
    Posted February 20, 2012 at 2:29 pm | Permalink

    Looking for circuit or suitable instrument which can convert vehicle tach/rpm impulses to analog voltage, i.e. output value of tach/rpm needs to get converted to analog voltage as our hardware takes input from 0 to 5v or even up to 20v.

    • Posted February 20, 2012 at 4:10 pm | Permalink

      What you need is a frequency to voltage converter. Something like this one or similar. If you are using a micro already, you can also count the pulses and then output a voltage as my article describes.

      • Ajay
        Posted February 24, 2012 at 6:44 pm | Permalink

        Thanks for the info Scott…..is any ready made Micro board available for PWM to Analog converter?

  12. Asaph
    Posted February 24, 2012 at 5:34 am | Permalink

    Thanks for the PWM insight.

    I would wish to use it for triggering mosfets in a variable frequency inverter.

    Could you shed some more light on the same. you could forward some similar work on the same.

    I will appreciate our help

  13. gusti
    Posted March 7, 2012 at 4:03 pm | Permalink

    Thanks for that great tutorial. Especially for the link to the japanese site.

  14. Scott
    Posted March 25, 2012 at 10:32 am | Permalink

    Hello Scott,

    I have 8-bit digital signal coming in from photodiode (the song that is being transmitted from LED and captured by photodiode). Now I want to convert that 8-bit signal back to analog and recover the song. Would your circuit work for it? Or should I just use the PWM signal as an analog input to the mu-encoder?

    • Posted March 28, 2012 at 6:54 pm | Permalink

      This circuit will work, provided your digital signal is using PWM modulation. Also, make sure response time of the filter is fast enough. For audio, 24K sampling is fine for moderate quality (think cassette tape) audio. For high fidelity, sample at 40K. Also, note for the 8-bit output, your dynamic range will be about 48 decibels. Give it a try and see how you like it (be sure to buffer the filter’s output with an op-amp).

  15. vipul
    Posted April 11, 2012 at 3:16 pm | Permalink

    Hi Scott,
    I am using the arduino and xbee radios with current transducers to monitor realtime power.

    The voltage output of the current sensor is wirelessly transmitted as adc value((0-1024) to a xbee receiver which is connected to arduino uno board. This board basically maps the adc value received via xbee(0-1024) into a 0-255 range pwm signal. But this mapping causes loss in resolution, which affects the system, because i am not actually generating a steady voltage equal to the one i read using the current sensor.

    Do you think a low pass filter circuit will solve this issue by generating accurate voltage from pwm signals coming out of arduino analoque write().

    Thanks in advance

  16. varsha
    Posted April 24, 2012 at 9:40 am | Permalink

    Hi Scott,
    we are making project with the help of arduino kit ATmega8, so we need difference between 8051 micro controller and arduino.

    Thank you!

  17. Mark Murray
    Posted May 27, 2012 at 4:47 am | Permalink

    Nice article, i would like to drive a model train with PWM [0 to 100%] at about 4V up to 1/3 throttle then linearly run up to 12V. I have an arduino and was wondering how to use PWM and then control the output voltage.

    • Posted May 29, 2012 at 3:01 pm | Permalink

      For driving motors, you can use PWM directly – you don’t have to filter it to a voltage. Basically, use the PWM output to turn a MOSFET on and off, switching the full voltage. The motor will coast during the off phase, and the result will be a reduction in torque and speed that is correlated to your PWM percentage.

  18. Tobi Broger
    Posted August 2, 2012 at 3:32 am | Permalink

    Hi Scott.
    Thank you for this excellent tutorial; for me as a Arduino/Electronic beginner really helpful!
    Probably you can help me with some hints on this:
    I would like to drive a tunable lens (http://www.optotune.com/images/products/Optotune%20EL-10-30.pdf) with my Arduino ADK. For this purpose I need DC: 0…300 mA. The manufacturer of the lens proposes some LED Driver Modules. Would the following one (http://www.thorlabs.com/Thorcat/0000/LD1255R-Manual.pdf) work together with the Arduino PWM output? Does that work straight away or do I need the low pass filter your described? Do you know cheaper possibilities (this one is 123 Euros) to do something like that?
    Thank you for your valuable advice!
    Tobi

  19. sri
    Posted October 6, 2012 at 1:33 am | Permalink

    thanks for the article besides that let me ask you one thing, i don’t understand the use of potentiometer to vary the duty cycle .my point is that by varying the bit sequence in our program with specified delay we can change the duty cycle of our pwm just like any other pin isn’t it?

    • Posted October 24, 2012 at 1:55 pm | Permalink

      The use of a pot is just an example of how to change the duty cycle. You can change the duty cycle of any PWM capable pin using analogWrite getting the value for that function anywhere. You don’t have to read it from a pot.

  20. Posted October 12, 2012 at 1:52 pm | Permalink

    Interesting site I’m very glad I stumbled here through google, Gonna have to add this one to the old bookmark list

  21. sam
    Posted October 20, 2012 at 1:00 am | Permalink

    Nice article, is it possible to drive peltier element from the output of low pass filter

    • Posted October 24, 2012 at 1:58 pm | Permalink

      Since you would need to have a driver of some sort to drive any high power device, I don’t see why you would want to change the voltage into the driver. Just using PWM would suffice. The main exception would be in making your own constant current source using a MOSFET. In that case, you drive the FET with the low pass filter.

      • sam
        Posted November 9, 2012 at 12:24 am | Permalink

        Hi Scott,
        Thanks for the reply ,am a beginner in electronics ,am using a op-amp h bridge circuit to drive the peltier . Can i give PWM signal from a atmega32 to a driver circuit for peltier element?

  22. Josh
    Posted October 24, 2012 at 9:21 pm | Permalink

    Hey Scott,
    I am trying to decide if the Arduino is right for me. I am 100% a beginner to this kind of stuff but I have a few things I would like to make that I can not just go out and buy, or so it seems. I have a 12v sensor that outputs a frequency. I want to take that frequency and convert it to a linear 0-5v output that will not be driving anything, its just for data accusation. I also have a pwm output that has a constant frequency and I would like to take the duty cycle and convert that to a 0-5v output for the same use. My question is the Arduino the right thing to use? Maybe just a low pass filter and a frequency to voltage converter would be simpler, I’m just not sure if that will fit my needs of getting both signals to be 0-5v.
    Thanks for your time and your help.

    • Posted November 8, 2012 at 12:17 am | Permalink

      Josh,

      I like your spirit regarding making the stuff you need and want to encourage you in that direction. You can do what you want without an Arduino or microcontroller. It really depends on what your needs are. As far as cost, an ATtiny chip costing $1 will do what you want for less than the freq-volt chip, but you will need to program it. If you actually use an Arduino in a permanent placement, that would of course be fairly expensive. As an alternative you can use the Arduino for prototyping (which is what it is best at), and then switch to just an ATmega328 chip or even program an ATtiny as I said.

      The only real disadvantage to using a microcontroller is the need to program it. Are you a beginner in electronics or microcontrollers? If you are new to electronics, then microcontrollers can actually be easier for you since they greatly simplify the electronics involved. They kind of convert the messy analog world into the tidy digital realm. If you are new to microcontrollers (and not electronics), then I recommend adding this category to your repertoire. It opens a new world of possibilities.

      In either case, I recommend getting your application running using the Arduino – it is beginner friendly and makes electronics beginner friendly as well. When you need to deploy your application, you can burn an ATmega or ATtiny chip using your Arduino and pop it into your final project for only a few dollars.

      Lastly, the other advantage the Arduino offers is intelligence. Your circuit does not need to be ‘dumb’, meaning it can only do simple things like an analog circuit can. You can program in extra features, complex decision making, etc. Smart electronics is the wave of the future.

  23. Jason White
    Posted November 19, 2012 at 10:40 am | Permalink

    Hi Scott,
    Thank you for the article, I’m sure when I’m farther along in my education, I will understand it better. I am 2 to 3 month novice to electronics and Arduino’s, but I Love challenges, so I may have bitten off more than I can chew with my latest project. I guess it’s silly to go from lighting some RGB LEDs to trying to control a model train with a TV remote, but pardon the pun, that’s how I roll. I actually am doing quite well with it. I have managed to get all manner of speed and direction control with DPDT relays and a Darlington transistor, or two types of motor shield. The problem lies in all cases with the annoying hum generated by PWM. I am currently using Lady Ada’s motor shield and I have set e frequency to 64khz which I am told will make the Pwm in audible, but I still hear it. Do you think your low pass filter could help with this? Can It be placed after the motor shield, before the track? Testing has moved from an n-scale running 12v dc at 300mA to a big G-scale pulling .5-.75A at 16V. If this would help with the hum, could you lead me in some direction as to the values of resistor and Capacitor I might need to make my train function more silently? I have considered going back to the Darlington h-bridge and using a tip120 to provide speed control. Would a low pass filter before the tip120 help with the PWM hum?

    Thank a million, Jason

    • Posted December 6, 2012 at 10:42 am | Permalink

      Jason,
      I am not sure why you are hearing a hum. I suspect it is in the motor itself and not related to the actual PWM frequency. I would suggest trying a different frequency and see if the pitch changes.

      If you want to control the motor without PWM by filtering, you will need to use N-channel MOSFETs to drive your motor. The low currents you mention should not be a problem with proper heat sinking. You would probably also need to monitor the current or voltage in order to determine what voltage to drive the FET with. The technical aspects of doing so is too much for this comment, but I plan a future article on the subject.

      You definitely cannot use a low pass filter either before or after Darlington transistors. They are for switching applications only.

      It is nice to hear about your willingness to tackle such an ambitious project. When facing a big learning curve it can sometimes be quite daunting, but with persistence the pieces eventually fall into place. My best to you.

  24. Posted December 3, 2012 at 6:59 pm | Permalink

    As an 87 years-0ld dinosaur who started life with crystal sets, I have dabbled with electronics ever since, without ever really learning the theory; my most recent venture has been a poor-man’s electrocardiograph (described on the above site). It seems to be time to update this effort, and I see the possibility of using one of the Burr Brown analog amps, and – I hope – a sampler employing an arduino device. I taught myself sufficient of several versions of Basic to be able to draw and print-out the necessary wave-forms, and am now battling with C and its variants. I am told that microcontrollers make electronics easier to grasp, but so far this blissful state eludes me. I am most happy to see your kindly and tolerant responses to us uneducated people, and just wonder if you could point me in the right direction with arduino? ( My field is Medicine, and my aim has been to make it possible for electrocardiography to be available to poor parts of the world).

    • Posted December 6, 2012 at 10:50 am | Permalink

      Michael,

      I applaud your efforts with your noble project. The best I can do to help you get started with the Arduino is this article – Getting Started with Arduino. It gives a brief overview and links to some books and other resources.

      I do recommend the Arduino as the best microcontroller to start with. It has more resources, libraries and tutorials than any other platform. The best way to start is to buy an Arduino and start playing around with the sample “sketches” (programs) and go from there. The Arduino website has libraries for everything you will need to do. You just need to use them and modify the examples as needed.

      Best wishes and keep up the outstanding effort.

  25. John Ford
    Posted December 23, 2012 at 10:05 pm | Permalink

    Very informative.
    I need to replace a defunct HPLC gradient controller with absolute minimal cost (since I’m paying out of my pocket). Basically, I need to generate complementary sawtooth waveforms, one changing from 0 volts to 10 volts over 10-120 minutes while the other changes from 10 to 0 volts over the same time interval.
    As I (mis?)understand this method, you effectively get about 8 bits of resolution on the conversion. Is that approximately correct?
    Thanks

    • Posted December 26, 2012 at 6:16 pm | Permalink

      That is correct. On the ATmega328, Timer0 & Timer2 are 8-bit, while Timer1 is 16-bit. Therefore, it is possible to get 16-bit resolution by using Timer1. The Arduino library does not support 16-bit timer values, so you will need to write your own analogWrite equivalent in order to use all 16-bits.

      • John Ford
        Posted January 15, 2013 at 4:48 pm | Permalink

        Thanks, Scott. I appreciate the advice. I’m thinking that an Arduino Due (with two 12-bit DACs) would be an easier implementation for me. I’ve put my name on the waiting list at Adafruit.

  26. GP
    Posted January 23, 2013 at 8:44 pm | Permalink

    Do you trust this method enough to use in lieu of a current limiting resistor for driving LEDs? The Arduino can source up to 40mA of current which is more than sufficient to burn out even most high mcd value LEDs; I am considering using this method to exactly deliver the maximum forward voltage to an LED based on its specifications. Good idea or high likelihood of magic smoke escaping the LEDs?

    • Posted January 24, 2013 at 2:41 pm | Permalink

      You cannot reliably drive an LED using its nonimal forward voltage. If you look at an LED’s IV curve, the current takes off vertically at this bias point. Since the exact voltage various from device to device and over temperature, there is no way to do it. There are two alternatives:

      1) You can drive an LED with much less than its Vf by this method. If the spec says the Vf=3.2 volts and you use 2.8 volts, it will probably work. However, what have you gained? You must use an added capacitor (not very cheap) and it is still an iffy approach.

      2) Use the method to make a constant current source. LEDs need to be driven by a controlled current source as opposed to a voltage source. To make a current source (technically a current sink), use an N-channel FET as a voltage controlled resistor. Put a small resistor between the source and ground and measure the current by means of the voltage across that resistor. The LED goes between Vcc and the FET’s drain. Set your analog voltage to the FET’s gate to a nominal value (such as 1.0 volts) and measure your current flowing through the resistor. Increase your analog voltage driving the FET’s gate until you get the current you want. You need to test and adjust your current constantly. This method is a fair bit crude, but it will work. A better approach is a strictly analog one such as using a bipolar’s constant VBE to provide the needed feedback or else an comparator.

      Obviously, this approach is overkill for low current LEDs, but is a legitimate way to drive high current ones.

  27. dan
    Posted January 24, 2013 at 6:44 pm | Permalink

    ok im using arduino mega 2560 to control the speed of a dc motor. i want to vary the speed of the dc motor according to a load from a load cell off a digital scale. i know i have to use the pwm, to control this. however im completely new to this and have no ideal where to go from here. i have the arduino, dc fan, power supply, and very little time to do this any help will be greatly appreciated

    • Posted January 28, 2013 at 3:59 pm | Permalink

      It sounds like you just need to use the analogRead & analogWrite functions as well as processing the data. Read your data from your scale using analogRead(), and then power your motor with an N-channel FET, giving the PWM to its gate with analogWrite(). For small FETs, you can drive their gates directly or with a small series resistor. For larger ones, you may have to use a driver circuit.

  28. Posted February 9, 2013 at 9:52 am | Permalink

    Hi Scott,

    First off, thanks very much for the great article!

    I came across this while looking for a way to convert an analogOut to 0-5v in order to control a mains dimmer (http://www.amazon.co.uk/dp/B001IROCTO/?tag=provideyourown1-20). I had enough of an exciting time soldering that whole assembly together! I’m quite a noob when it comes to electronics, so I’m a bit nervous about making a low-pass filter myself, for fear of getting lost in what exactly I need… I’ve poked around on Amazon and eBay but can’t seem to find any for sale, or it’s not clear whether or not they’d be suitable for my application…

    If you’ve got a spare moment, would you mind pointing me in the right direction? I believe I simply need a 0-5v signal to control the power of the light through the dimmer, but of course I could be way off!

    • Posted February 14, 2013 at 12:39 am | Permalink

      Just use the example given. Prototype it and measure the voltage output with a voltmeter. It should correspond to your PWM duty cycle. Provided the dimmer circuit you cited takes 0 to 5 volts, you should be good to go.

  29. Brian
    Posted February 9, 2013 at 11:46 pm | Permalink

    Hi Scott,

    Wow, I love what your doing and how much your helping others. I often search for information for myself and very rarely share solutions. I’m glad someone out there does. Very inspiring.

    Keep up the good work.

  30. andy
    Posted February 11, 2013 at 12:57 pm | Permalink

    this could be exactly what i’m looking for. i want to take a pwm signal from my computer’s motherboard and drive an analogue dial gauge. what components would i need for this?
    thanks in advance :D

    • Posted February 14, 2013 at 12:42 am | Permalink

      If your dial gauge measures up to 5 volts, just the resistor and capacitor given should work fine. If your gauge requires a higher voltage, you will need to drive the gate/base of a transistor hooked up to a voltage source matching the gauge, and then filter that PWM signal as before.

  31. Holger
    Posted February 18, 2013 at 10:00 am | Permalink

    Hi Scott, thanks for all these great thoughts, its fun reading through this thread!

    I have to drive a Photomultiplier (PMT) control circuitry with a 0-5V DC control voltage (CV) to generate the respective high voltage (HV) that regulates the PMT’s sensitivity.
    As the HV follows the CV according to the equation
    HV = CV*250
    any ripples are scaled up by a factor of 250 as well which could cause some additional noise on the PMT output due to sensitivity fluctuations.
    As the Arduino’s PWM output is 5V (UNO in my case), I thought of a 2 pole active low pass filter with an OpAmp (e.g. a LM358 at 14Vcc) to get the full 5V back after the low pass.
    Do you think that this will produce a DC stable enough or can you think of a better circuitry to be driven from a PWM pin for my purpose?
    Thanks
    Holger

    • Posted March 6, 2013 at 11:45 pm | Permalink

      Hi Holger,

      You may have to do some testing to see what is acceptable. Multiple-pole, low-ripple filtering is a good bet. An alternative would be to use an R2R resistor ladder. It would take a lot of pins, but you would have no ripple.

      That’s the best I can come up with. Have fun.
      Scott

  32. Enrique
    Posted March 17, 2013 at 10:30 pm | Permalink

    Hi everyone,
    I´ve been working in DAC to drive a directional proporcional valve (0 -10V), but I´ve got de DAC (PWM to Analog) with a AOP LM741. will I need another step to drive the coil of the valve?

    • Posted April 24, 2013 at 12:30 pm | Permalink

      An op-amp should drive a small coil, but don’t forget to add the bypass diode to protect against the inductive transients.

  33. Jason
    Posted April 21, 2013 at 4:05 pm | Permalink

    I have a gear reduction motor that has its own motor controller. It has one analog input controlling direction and speed. +5vdc thru -5vdc, Ovdc being the stopped position. +5vdc full speed counter clockwise, -5vdc full speed clockwise. Is there a way to make the pwm output from the arduino output +-5vdc? Thanks

    • Posted April 24, 2013 at 12:28 pm | Permalink

      Jason,

      You’ll need to use an op-amp configured as a non-inverting amp with a gain of 2 and supply it with 10 volts (assuming rail to rail op-amp), to give you the required 10 volt peak-peak voltage swing. Then use another op-amp configured as a voltage-follower with a 5v input to create a ‘virtual ground circuit’ (google it for details). Use the output of this op-amp for your ground and the first op-amp for your signal.

      • Posted May 3, 2013 at 1:07 pm | Permalink

        Hello..

        by modulating a signal,

        int pwmPin = 9; // output pin supporting PWM
        int inPin = 3; // voltage connected to analog pin 3, e.g. a potentiometer

        if i use accelorometer.. how about the coding? i dont use potentiometer.

        i use http://fr.hobbytronics.co.uk/imu-5dof-adxl335-idg500

        thanks

        • NAcho
          Posted April 20, 2014 at 5:52 pm | Permalink

          I’m sorry, I didn’t read all the comments. If my question has been asked before, please point me to the answer and I’ll be grateful.

          I want to convert: PWM to Analog 0-5Vdc.
          Is it possible? Easily.
          Thank you.

  34. sab
    Posted May 9, 2013 at 5:19 am | Permalink

    Hi Scott,
    i am wandering on how to operate and to make just a simple program for my 6A Hbridge motor controller, here it is,http://www.e-gizmo.com/KIT/hbd6.htm, and the manual is https://docs.google.com/file/d/0BxdLxDCD6HidMTFJVFdfeC1pQ3c/edit?pli=1, i really dont understand what does the PWM means but because of this tutorial i think i have an idea on how to this , advance thanks =)

  35. Chris
    Posted June 13, 2013 at 12:58 pm | Permalink

    Scott,

    A very late comment but just getting into this stuff and came across your excellent article.

    I wonder if you can help me.

    I am driving a PC fan through an H bridge motor controller. I send a PWM signal from the arduino, and can vary the motor speed. Problem is that I get an annoying hum, which only occurs with PWM. If I use a lower voltage (non PWM) on the fan I don’t have a problem.

    So I imagine that I should use a low pass filter to change PWM into something more like straight DC. I used the calculator to size R and C values, but find that there doesn’t seem to be enough voltage left after the resistor to drive the fan, is the fan barely runs (low speed).

    Perhaps I have misunderstood but I would assume that the resistor in the filter will cause a volt drop as current passes through it?

    I’m a complete beginner at this so any suggestion welcome.

    Chris

    • Posted June 16, 2013 at 1:15 am | Permalink

      Chris,

      The problem you are seeing is the fact that the motor is putting a load on the filter. Such a filter needs to have a buffer between it and a load. Yes, the resistor is a huge voltage drop at all but the smallest currents, and the capacitor can store only the smallest amount of charge. Any kind of load at all with cause the filter to not function properly.

      What you need is an amplifier with high input impedance and low output impedance. Either an op-amp or a MOSFET will serve this purpose nicely. Both have high input impedance (they won’t load the filter at all), and they both have low output impedance (they can drive a large load without bogging down).

      In the case of using a N-channel FET, put your load between your supply and the FET. Your duty cycle will not be follow a linear relationship to motor speed however. If you want such a relationship, insert a small current sense resistor and feed the voltage across it back into your Arduino and scale your PWM to produce the current level desired.

      For a choice of FET, this one in a TO-220 package will handle a couple of amps. If it gets too hot, just add a small heat sink.

  36. Michael
    Posted June 29, 2013 at 11:41 am | Permalink

    hey scott
    i was hoping someone else would ask this with all the comments…
    but no one did so it may be a bad question, but could clear this up for me.
    in your schematic of the filter what connects to the other end of the capacitor? the schematic shows nodes with no further indication of what they are connected to. my assumption is common ground or nothing as dc cant pass through the capacitor.

    thanks. ill be messing around with this circut to fade in and out a large LED array with my arduino.

    • Posted July 12, 2013 at 10:06 pm | Permalink

      Yes – the lower wire with its connections is the common ground for both input and output. I apologize that the drawing is not more clear on that.

  37. Asterios Stamatis
    Posted July 4, 2013 at 12:29 pm | Permalink

    Greetings,

    I would like your advice because i am a little bit confused. I have a project in which i have to dim a 10V lamp according to a digital value. I just ordered the arduino starter kit. I have an LPC2468 board but seems to be too compicated for that and the community is not that big.
    I started to read some things and it seems easy to dim an LED. But how can I produce voltage from an Arduino board? Is there an easy way? My project is supposed to read a value (luminance) from a file and dim the lights accordingly. In addition arduino produces PWM equal to 5 V. is there a way to amplify it to 10V?
    Its been a long time since the last time that i read about electronics, so plz make it as easy as you can..!!!

    Best Regards,
    Asterios Stamatis

  38. LewTwo
    Posted August 5, 2013 at 10:09 pm | Permalink

    First: Thank you for the well written article.

    Second : There may be an excellent application for this technique …
    supplying and analog reference voltage to the Arduino’s “AREF” pin.
    This would allow the user to adjust the reference voltage through software to meet the needs of the signal that they were intending to read (temperature sensors come to mind). There is already a 32K Ohn resistor on the Ref Pin but that would be on the wrong side of the capacitor. Is there a convenient way to modify the calculation to take this into account?

    • Posted August 15, 2013 at 12:34 am | Permalink

      Since the input impedance to the AREF pin is probably quite high, you don’t have to worry about the effects of an additional resistor. I am not sure this is the best way to go about what you want to do though. Using a precision 2.5v reference IC is what I would suggest. It would be very accurate and independent of supply voltage.

  39. Posted August 6, 2013 at 3:46 pm | Permalink

    great article . Dear i have a question . now i got a mic+amp+pot i want to feed it into arduino and get an output digitally and send it via a TRx RFM22 . do i need a buffer for it ?
    second thing , what if i use my mic+amp+pot as input , then the output i want to hear it via speaker . should i still use a buffer ? ….
    Do i need to divide 1023 from ADC by 4 so it can be heard properly in the output ? because i know the ADC reads from 0 to 1023 and the PWM from 0 to 255 . wouldnt there be loss in data ?

    • Posted August 15, 2013 at 12:43 am | Permalink

      On the transmitter, I would have to study the spec sheet more to be sure, but you should just give it a try – if it doesn’t work, add a buffer. For output to a speaker, you definitely need a buffer. On the 0-1023 input, no you don’t need to divide, but rather scale both the input and output. For example, if you want to do internal calculations in terms of percent, then scale your input from 1023 to 100, and your output from 100 to 255. The Arduino supplies a ‘map’ function for this very purpose. See – http://arduino.cc/en/Reference/map

  40. Manikandan Selvam
    Posted August 15, 2013 at 8:32 am | Permalink

    I’m doing PWM to analog voltage conversion in my project. We are using second order RC low filter to convert from digital to converter.
    It would be helpful if you share the calculation to find out value of the step response and peak to peak ripple voltage and settling time.

    and how to make the relation between pwm input signal and rc filter in equation to get the output waveform.

  41. tenCents
    Posted August 20, 2013 at 7:33 am | Permalink

    Adequate and well explained, got me up to speed quickly. Thanks for your effort. I’m just getting into this Arduino stuff and loving it. Salutations!

  42. David Pan
    Posted October 11, 2013 at 8:29 pm | Permalink

    How can I type numbers from 0-255 from seiral USB keyboard to control PWM and analog output?

  43. Ferdous Ahmed
    Posted November 12, 2013 at 3:17 pm | Permalink

    Hey Scott

    I’m just trying to get two Analog output from Arduino. can you give some guidance to do so. I have a duo device. Thanks a lot

    Ferdous

  44. SJ-Peng
    Posted December 24, 2013 at 1:18 am | Permalink

    Hi this article is fantastic!!

    And one question I would like to understand. How to convert PWM -> RC filter to +- voltage.
    ex. Here I have a PWM channel where the voltage level is 5volt. so if I use your suggestion, only 5 volt is available for filtered ouput. So how can I get negative 5 volt by using the similar manner? Many thanks for your kindly help.

    SJ-Peng

  45. banz
    Posted January 16, 2014 at 10:10 am | Permalink

    hi Mr. Scott,

    i wonder if our group is using the correct value for resistor and capacitor for the low pass filter. 10k ohm and 3.2 nF respectively for a 5khz cut-off frequency. this application is for our project wireless communication based laser with certain distance to cover.. we are using a PIC 877A for a PWM output, then we decided to low pass filter the PWM output to generate analog waveform.

    does it make sense sir?

    and one thing also i have read some forums online is that in order to acquire the right value for resistor we have to refer first on what input impedance we have in our audio amplifier, say if input impedance is 10k ohm then the resistor will also then be 10k ohm..BUT as far as what i have searched, typical input impedance say for LM386 is 50k ohm. seemed to be too large.

    what could be the right thing for this sir?.

    alternatively, we planed to use IC 555 timer to generate PWM and wire up the low pass filter for analog output. i wonder if what could be other consideration for this?. or say is this possible and applicable for our project?.

    i hope u can help us with our project. THANKS LOT and thanks for your info. GOD BLESS.. :)

  46. Aydin Gulgun
    Posted March 14, 2014 at 9:43 am | Permalink

    hi, i find your project when i was searching for an audio to pwm transformation.
    i m trying to drive some pomps to create an equalizer graphic with water.
    i understand that what i want is kind of opposite of what you did here but i m wondering if you can do this, can the oposite be done? what i mean is can we input an audio signal and convert it into a pwm signal? if yes can you help me to understand the prosses. and i m sorry for my bad english.

  47. Allan
    Posted March 26, 2014 at 10:33 pm | Permalink

    Thank you Scott. I believe you have described what I am needing which is a method for an Arduino to mimic the controller for a submersible Speed Wave DC aquarium pump. I think these pumps must have their own PWM controls potted into the pump. The external controller provides a steady 24 volt source to the pump and a 0 to 4.9 volt control signal for on/off and 6 speed levels. I have assumed at this point this 0 to 4.9 control signal is not PWM from the controller to the pump. My questions are: One, why would I care about cutoff frequency? I think I need to pay attention to the ripple and how long it takes to go from one voltage to another. Second, the OKWA calculator looks at 0% to X% as duty step. How can I figure the time going from X% to Y%? I assume this is the ramp time going from one speed to the next for the pump application. Thanks again.

  48. Greg
    Posted April 18, 2014 at 6:22 pm | Permalink

    I’m sorry, I didn’t read all the comments. If my question has been asked before, please point me to the answer and I’ll be grateful.

    My question is: Would I be able to control sound volume (from an external source) through a transistor with this analog output? If not, do you have any suggestions? In my project space is verry limited so as few components as possible would be nice.

    Thank you!

    • NAcho
      Posted April 20, 2014 at 5:51 pm | Permalink

      I’m sorry, I didn’t read all the comments. If my question has been asked before, please point me to the answer and I’ll be grateful.

      I want to convert: PWM to Analog 0-5Vdc.
      Is it possible? Easily.
      Thank you.

  49. Logan
    Posted June 7, 2014 at 11:24 am | Permalink

    I’m curious of a DAC like this would work for driving galvanometers, which don’t like raw PWM input (At all…), for a UNO-programmable laser light show. Assuming it would, any idea what changes might need to be made? Sorry if this is a noob question, I’m kinda new to both Arduino’s and Galvos.

  50. Posted June 13, 2014 at 7:31 pm | Permalink

    Pretty! This was an extremely wonderful article.

    Thanks for providing this info.

  51. Vin
    Posted June 19, 2014 at 1:38 am | Permalink

    Hello Sir. I need an analog control signal ranging grom -5V to +5V. Can I use this approach to get 0 to 5V, and then use an amplifier with gain 2 to get 0 to 10V, and clamp it negative by 5V to obtain -5V to +5V?

  52. Posted June 28, 2014 at 9:31 pm | Permalink

    Good day! This is my first visit to your blog! We are a collection of
    volunteers and starting a new project in a community
    in the same niche. Your blog provided us useful information to work on. You have done a outstanding job!

  53. Posted May 3, 2013 at 1:05 pm | Permalink

    Hello..

    by modulating a signal,

    int pwmPin = 9; // output pin supporting PWM
    int inPin = 3; // voltage connected to analog pin 3, e.g. a potentiometer

    if i use accelorometer.. how about the coding? i dont use potentiometer.

    thanks

  54. Posted June 16, 2013 at 1:19 am | Permalink

    You’ll have to figure out how to interpret your accelerometer data by studying the specs/tutorials you already have. Modulating the signal is simply changing your analogWrite value based on how you want to interpret your measured data. Does that make more sense now?

20 Trackbacks

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" extra="">

*