Electronic – arduino – Providing a linear adjustable DC voltage from PWM ( 1.5V to 3.3V)

arduinolm317mosfetpwmvoltage-regulator

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?

Best Answer

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:

schematic

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).