I'm not an electrical engineer, so a simple task has me baffled for the last week or so.

I am working on project where I am required to feed a blackbox device with a stable adjustable voltage. The box will be sampling the voltage provided by analog read.

The readings I provide it will be around 1.8 & 3.1V (2 modes of operation) and will be shifting for values of 0.01V to limits of +-0.2 (so in mode1 I need readings of between 1.6 and 2.0 and in mode 2 I need readings between 2.9 and 3.3) This readings will be changing so Vout must reflect the changes in a timely manner.

I am using an Arduino to obtain the data, calculate it to voltage and push out a PWM.

I am using a pro mini, powered by 5V applied to its raw pin which puts the device into 3.3V mode. Thus my Aref and 100% PWM cycle both equal 3.3V

The frequency of PWM is at about 20kHz (I can slightly modify this if required).

I have slapped together another Arduino to act as my signal analyser (as I lack an oscilloscope), with which I am probing the Vout line (it implements an LCD and pushes analogRead data to screen, with some added qualifiers I can make it show me the extreme values of Vout).

So now that I can see what is being spit out I can start working on it. So I read a lot of filters literature, but half of it is not really making sense to me. What I gathered is that I need to implement a lowpass filter to smoothen Vout.

So I tried building a RC filter, selecting C and R values "by luck", trying different combinations and orders of RC filters I can manage to get the Vout swing (initially 3.3-0) down to 3.3-2.7 when targeting 3V. Although better, it is still nowhere near the accuracy I require. (the parts I have on hand just now are a bit limited, so there were a 0.1uC,1/8uC 1uC, a 100uC, a 1500uC, and resistors from 10K down to 0.25K in my tests) IIRC the combination I have set up currently is 100uC/1K 1st order (adding orders was giving me negligible improvements, so I might be misunderstanding that concept)

Further reading has hinted that I might need a bit more than just a filter to deal with this, so far internet's best suggestion seems to be a combination of LM317 as an adjustable regulator and a MOSFET to convert the PWM to a variable resistance.

Figure 37 in the LM317 tech sheet seems like the regulator part I could use for this, but I can't seem to figure out the variable resistance part of what I need.

So my question is twofold as I am assuming I might have gone a wrong direction with this:

  1. Is this the best way to do this? I am trying to keep parts and cost numbers down, so I don't want to go down the whole MOSFET regulator road if it turns out I'm just using an incorrect filter.

  2. How do I do solve this challenge?

  • \$\begingroup\$ How fast does the final signal need to change? What is the input impedance of the device that you are driving? \$\endgroup\$ – Dwayne Reid Feb 7 '15 at 13:02
  • \$\begingroup\$ If I'm reading this correctly you are taking an analogue voltage, converting it to digital via an arduino then taking the digital output of the arduino, converting it to an analogue voltage and then feeding this analogue voltage into a 'black box' that will convert it. It seems to me you are totally over complicating the design. A 'stable, adjustable voltage doesn't necessarily mean a variable regulator. Resolution (0.01V) doesn't necessarily mean 'steps of'. \$\endgroup\$ – JIm Dearden Feb 7 '15 at 13:09
  • \$\begingroup\$ @DwayneReid: The signal change should happen in a fraction of a second, a 1/10 feels like still marginaly acceptable, maybe 1/2 as a maximum limit but idealy in under 1/10. Cant answer the impedence question, lack knowledge.. \$\endgroup\$ – Ebis Feb 7 '15 at 14:10
  • \$\begingroup\$ @JImDearden: I think youre misunderstanding,probably be due to my writing; The product is one arduino reading of a seperate sensor. This arduino does sensor input processing and then outputs this signal to the receiver(blackbox). The second mentioned arduino is just used for prototyping to analise the Vout signal. Once I am satisfied with Vout, I will be removing it from the build \$\endgroup\$ – Ebis Feb 7 '15 at 14:11
  • \$\begingroup\$ @DwayneReid: followup on the impedance question; the receiver read pin would be in a state of high impedance, a thourough search of the data sheets brings forth the number 100Mohm, though an output impedance of 10K or less is suggested for best accuracy. \$\endgroup\$ – Ebis Feb 7 '15 at 15:19

There are plenty of ways to do what you want. There are even ICs that will do it for you (programmable voltage regulators).

But if you want to follow your path, first you need a PWM with more than 8 bits resolution (10 mV is the step, 3.3 V is the max voltage you want to reach - this is 330 steps or 9 bits), make sure that your PWM has the correct resolution.

Then you need to filter the PWM output. The "simplest" solution is indeed RC. This is not the most efficient but its ok if you can accept some ripple. Take a cuff frequency that is at least 10 times smaller than the PWM frequency for reasonable ripple attenuation (2 kHz in your case). For a first order RC filter, you select R the following way:

R = 1/(2 x pi x C x f)

Then you need to buffer to output of the filter. This can be done with an operational amplifier used as a follower. Make sure that the supply voltage of the operational amplifier is sufficient to avoid saturation and that the amplifier can supply sufficient current for your application.

You can have something like that:


simulate this circuit – Schematic created using CircuitLab

Select R1/R2 to set the gain (or attenuation), select R4/(R3+R4) to set the offset, select C*R2 to set the filter frequency. Output will be opposite to your PWM setting (0=max, 255=min).

| improve this answer | |
  • \$\begingroup\$ I'm trying to reduce the ripple as far as possible, so to get a consistent Vout as I don't know how the signal is processed on the other side, otherwise I'd just average it on the receiver and not bother with smoothing, but that's not an option \$\endgroup\$ – Ebis Feb 7 '15 at 13:29
  • \$\begingroup\$ So, what is your ripple target ? 10 mV ? 1 mV ? \$\endgroup\$ – MAC Feb 7 '15 at 15:03
  • \$\begingroup\$ By the way, the default Arduino PWM is 5V peak-peak and has a resolution of 8-bit or 20 mV. There is a circuit that can change it to 1.0 V - 3.5 V with a resolution of 10 mV. This can serve as front-end "R" for your RC filter or be part of your buffer. \$\endgroup\$ – MAC Feb 7 '15 at 15:06
  • \$\begingroup\$ Just noticed I omited a detail previously, I am running the arduino on 3.3V mode so my PWM peak is 3.3. (corrected OP to reflect this) Would that mean I would need to apply 3.3 instead of 5V in your schematic (above R3) ? Both 5 and 3.3 are available so its just a question of which one to connect \$\endgroup\$ – Ebis Feb 7 '15 at 16:18
  • \$\begingroup\$ 3.3 V or 5 V are ok. It changes the settings for R1-R2 and R3-R4, that's all. \$\endgroup\$ – MAC Feb 7 '15 at 16:21

If you have a 5V PWM signal, at 20 kHz, low pass filtering a 10% duty cycle at about 2 kHz should give you about 0.5v, 50% would be about 2.5V, and 100% would be 5V. It's just the mean value across one PWM cycle.

Once you have this in hand, you should know how to scale and offset your signal. If you need to scale by a gain less than one, you need a voltage divider (i.e.,series resistors) or inverting amplifier (op amp), which you would need to reinvert later. Offset would be handled with an op amp.

The other alternative is to twiddle the PWM pulse widths to get what you need.

| improve this answer | |
  • \$\begingroup\$ Yeah, I get the pwm to voltage equation, thats pretty straightforward, but I need the final signal to be a flat line \$\endgroup\$ – Ebis Feb 7 '15 at 13:33
  • \$\begingroup\$ A 2kHz RC filter will do that \$\endgroup\$ – Scott Seidman Feb 7 '15 at 15:41
  • \$\begingroup\$ Would it need to be exactly 10 times smaller than the pwm frequency or is the trick in making it more than 10 times smaller? \$\endgroup\$ – Ebis Feb 7 '15 at 22:05
  • \$\begingroup\$ We just usually go for a factor do ten for a one pole filter. \$\endgroup\$ – Scott Seidman Feb 7 '15 at 22:07

It seems to me that a component called a Digital to Analog Converter (DAC) would do what you want. You can probably do what you want with PWM and a high-order low-pass filter but the DAC might be simpler for you.

DACs are available with both serial and parallel digital inputs. You mention Arduino, so I'm going to suggest that you want to use a serial DAC because the serial interface uses less i/o pins from the Arduino. However, serial transfers are slower than parallel.

There are MANY different devices to choose from. Putting the string "serial dac" into Google brings up a plethora of choices. Two of the first choices: Linear Technology and Maxim offer free samples. I suspect that most manufacturers of DACs do the same.

| improve this answer | |
  • \$\begingroup\$ ok, I will do more research on DACs, Just considering what you wrote, I might need to go for a parallel one, as speed of updates is important and i still have plenty of pins left \$\endgroup\$ – Ebis Feb 7 '15 at 14:16

A low-pass filter is the way to go. I do the exact same thing in a circuit I'm working on at the moment, so I have something that works:

enter image description here

This is basically just a third order lowpass filter with a cut-off frequency around 350Hz. For a 20kHz PWM signal the ripple will be below 1mV.

If you change your pulse-width it'll take about 2.5ms for the signal to settle.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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