I am trying to convert an Arduino PWM signal into variable DC voltage source. This will be done by varying the duty cycle output from the Arduino. My question arises when I consider building higher order filters. Will a higher order filter (Sallen-Key, Butterworth, etc.) work better than just a basic active RC filter? I want the output signal to be as "DC" as possible even at low duty cycles.
-
1\$\begingroup\$ Yes, generally a properly designed higher order filter will work better than a lower order one in the sense of ripple vs. response time for a given PWM frequency. But you need to define how much ripple is acceptable and how fast it needs to respond. "as DC as possible" is not a specification. \$\endgroup\$– Spehro 'speff' PefhanyCommented Mar 26, 2021 at 1:07
-
\$\begingroup\$ The arduino PWM signal appears to only be around 1kHz, so you'd need a huge inductor for your filter. It might be better to use an analog voltage output to drive a faster PWM driver from a 555 or actual voltage regulator. \$\endgroup\$– K HCommented Mar 26, 2021 at 1:08
-
\$\begingroup\$ One option is to make your own PWM function with higher frequency which would reduce the need for higher order filters. See link for default Arduino PWM when using "analogWrite" function link Suggest to use some type of active buffer (depending on load), and not only passive components. What type of output are you driving and what is the Arduino type? \$\endgroup\$– ErnestoCommented Mar 26, 2021 at 3:03
-
\$\begingroup\$ 3rd order Bessel using a single opamp or two ( one bigger) or even a single transistor (with accompanying 0.6v voltage drop) can be suitable for many needs. \$\endgroup\$– Russell McMahon ♦Commented Mar 26, 2021 at 3:56
-
\$\begingroup\$ @Turbochad: Look into using the TimerOne library. You can set a much higher PWM frequency ( which makes it easier to filter down to "clean" DC) and you get 10 bits (1023 steps) for your PWM duty cycle. \$\endgroup\$– JRECommented Mar 26, 2021 at 10:19
2 Answers
Will a higher order filter (Sallen-Key, Butterworth, etc.) work better than just a basic active RC filter?
Yes it will. It'll be better because, as the "order" of the filter increases, the PWM switching artefacts seen on the output get progressively more reduced in amplitude: -
Picture from here.
So, in the above diagram you have a pass band where the frequency response is maximally flat - this covers DC to some cut-off frequency. Above that cut-off frequency you want to attenuate AC components of the signal and ideally, your PWM frequency will be at least ten times the cut-off frequency.
So, with a first order filter you get 20 dB attenuation but, with a 2nd order filter you get 40 dB of attenuation at ten times the cut-off frequency.
For a 3rd order filter you get 60 dB attenuation at the cut-off frequency. In case you didn't know, that's a real-number voltage attenuation of 1000:1.
Someone might have an idea how to squeeze a better PWM frequency out of an Arduino, but if it is limited as it appears to be around 1 kHz, the switching frequency is working directly against your goal of "As DC as possible". You would need a huge output filter compared to a higher but still easy to work with switching frequency. Aside from the physical size and cost, you need a larger current surge to initially charge the output capacitor and you get a slower response to source voltage or load current changes.
You could use an analog output to control a voltage controlled voltage or current regulator as probably your best option (you could set it up so your reference voltage controlled 0-100% duty cycle or so that the converter just tried to match your reference voltage). This will put much less processing load on the Arduino than manually controlling an output for duty cycle. Even if all you wanted was a meager 100kHz switching frequency, unless all the Arduino is doing is controlling the voltage regulator, you wouldn't want to interrupt it 100,000 times a second from more important tasks without a good reason. The point of those PWM outputs is to automate control of the output, and if they found that worth doing at a meager 1kHz, it will be well worth doing at 100kHz. I'm only specifically aware of ones used for current control in LEDs, but I wouldn't be surprised if you could find PWM drivers or voltage regulators capable of much higher frequency that could be controlled over an I2C bus or something. Might be worth investigating as you could control multiple converters over one pin.
If you're trying to build your own PWM regulator in order to learn, you could try the following, it's worked well for me although it doesn't respond nearly as well/fast as a dedicated chip, it's pretty easy to build up to around 100-200kHz.
First build a triangle wave generator at your desired frequency(op-amp integrator version is easy at low skill level, 555 timer version is easier but less linear) and a voltage reference (you can use a potentiometer if you want it adjustable, but it's getting removed anyway). Use a comparator to turn ON the PWM switch if reference is higher than the triangle wave. This gives you a voltage controlled duty cycle PWM drive. It won't do a very good job with a variable load because it is blind to the output though.
Now replace the voltage reference with a capacitor to ground and set up a comparator or op-amp to compare the output voltage to a new reference voltage. If the output voltage is lower than the reference voltage, charge the capacitor. If the output voltage is higher than reference voltage, discharge the capacitor. This turns the voltage controlled duty cycle drive into a voltage controlled voltage converter. It has the advantage of taking almost all the processing load off the Arduino. If you do the comparator version I recommend setting it up so it discharges faster than it charges to minimize overshoot on startup and load spikes. If you do the op-amp version you have to do a bit more learning, but you can more easily set it up so it adjusts the reference capacitor in proportion to how far out the output voltage is, giving you a faster response. As far as I could figure out, you need two op-amps, one to calculate the magnitude of the output discrepancy, and a second to relate that to the current voltage on the capacitor.
One more option if you're good at calculus and advanced math, you can figure out the actual mathematical relationship between output current, voltage and desired duty cycle and build an analog op-amp circuit to calculate that on the fly. You get better results and faster response at the same switching frequency than with a simple auto adjuster, but the skill level required is high.
Now as a final step that uses more processing power for a better result, you can take out the op-amp or comparator and have the Arduino provide the reference voltage for duty cycle. Give the Arduino the output voltage sense input and also a current sense input. Now you can build a more advanced algorithm that uses current sense to predict changes in output voltage and respond to them proportionally and aggressively. If you have the calculus/math skills mentioned above you can do this in direct math rather than having a system that responds to changes. If you have some of those math skills, you can do a pauper's version where the algorithm interpolates between values in a multidimensional lookup table. Doing so can decrease processing load at the expense of memory use and if the values of the lookup table are filled experimentally, you can bypass the need for calculus. This also lets you add features like current limiting, current control or overvoltage/overcurrent cutoff. Adding more inputs could give you temperature cutout, source brownout protection, or whatever else, but it's worth noting most features you would really want can be built by default into modern voltage regulator chips, saving your Arduino for more important tasks.
Now you've learned what you can learn more or less, so you might want to move on to dedicated voltage regulators/chips that will provide a better result with lower power consumption and the convenience of a modern (MHz) switching speed. You can still use your Arduino to control them, so for example if the 0-100% voltage regulation was to drive a Peltier apparatus in an intelligent way, that might be an actual good application for using a microcontroller because of the multiple inputs and complex efficiency metrics (separate control of peltier and fan based on hot side temp, cold side temp and ambient if necessary). Even for this type of application, an Arduino is probably a huge overkill, but it's an example where you can offset the overhead power loss of running the microcontroller with large efficiency gains.
Sorry I don't know much about advanced filters, but I though you might want to start by making your task easier in the first place. If you have the skills to design efficient high order filters or active filters, you probably also have the skills to not need them for many applications.