Use a DAC to Adjust a Supply's Vout With an Arduino and Excel
by Rick-ecircuit in Circuits > Arduino
75 Views, 0 Favorites, 0 Comments
Use a DAC to Adjust a Supply's Vout With an Arduino and Excel
Why adjust your power supply output?
- Trim a supply output to a precise level
- Compensate for the voltage drop along conductors to a load
- Track power rails to an ampifier's output for reduced device heat
How can you adjust your fixed supply output with a DAC? The output is typically set by two resistors R1 and R2. However, by adding a third resistor R3, you can use an external DAC voltage to adjust Vout. The method applies to many Linear Regulators as well as Switch-Mode Power Suppies (SMPS) such as Buck, Boost, etc.
We'l use an Arduino UNO's DAC output (0V to 5V) to adjust the Vout of a Buck-Boost Converter from Sparkfun. By simply adding R3 to the PCB, you can adjust the Converter across it's output range (3V to 9V). Because the Arduino's DAC output is a switching PWM signal, a low-pass filter is applied to create a low-ripple DC signal.
The Code calculates the Vdac for a desired output Vout, writes the value to the DAC and then measures the Vout using an analog input channel to the ADC.
You can customize the adjustment range or apply the method to a different supply using the Excel Design Calculator. Dive in deeper to see how the resistor equations were derived.
Schematic and Overview
Basic Operation
With R1=68.1k, R2=620k, R3=510k and Vref=0.8V, the DAC output Vdac adjusts the supply output according to
Vout = Vdac*m + b
where m = -1.2 and b = 9.0. The circuit Scales (m) and Shifts (b) the input Vdac = 0V to 5V to produce Vout = 9V to 3V. The equation provides you with a handy way to calculate the Vdac needed for a desired Vout.
Vdac = (Vout - b) / m
How It Works (Intuitively)
- With R1 and R2 only - The supply's control loop raises Vout until Vfb = Vref. Because of the R1, R2 divider action, Vout must be higher than Vref predicted by Vout = Vref*(R1+R2)/R2
- Adding R3 and Vdac - In this case, Vdac also contributes to Vfb through R3. Now Vout needs to rise to a lesser voltage to achieve Vfb = Vref.
Essentially, the higher the Vdac value, the lower the Vout value needed for Vfb = Vref.
Buck-Boost Converter
The DC/DC Converter from Sparkfun takes a Vin of anywhere from 3-16V and regulates to a Vout between 2.5-9V. We'll feed the Arduino's +5V into the converter's Vin. With a mechanical switch, you can set a Vout of 3.3V or 5V. There's also a custom setting that allows you to solder a resistor based on your specific voltage needs. We'll take an advandage of this! The three resistors of our circuit can be easily implemented as
- R1 = 68.1k - Already exisits on PCB (done!)
- R2 = 620k - Install in custom resistor location. Move switch to CUST position.
- R3 = 500k - Solder onto thru-hole pad of R2. (See Built It below).
DAC Output and Low-Pass Filter
The Arduino provides a Digital-to-Analog Converter (DAC) output via a Pulse-Width-Modulated (PWM) digital signal. The Low-Pass Filter transforms the 0V to 5V PWM digital signal into an DC analog signal. To do this we split R3 = 510k into RLP = 10k and R3 = 500k so that the total DC resistance is 510k. Components RLP = 10k and CLP = 1uF create a low-pass filter that reduces signals above the cutoff frequency.
fc = 1 / (2 * pi * RLP * CLP ) = 15.9 Hz
Ideally, we prefer the PWM frequency to be much higher than fc to reduce the ripple as much as possible. So we'll raise the default PWM frequency of D3 from 490 Hz to 31 kHz by setting a variable in the code.
Voltage Monitor (Vout)
We'll use the Arduino's Analog-to-Digital Converter (ADC) to get a sanity check on the output voltage. But the analog inputs can only handle 5V max, so we'll place a resistor divider (R4=R5=10k) from Vout to Vout1.
Kdiv = Vout1 / Vout = R5 / (R4 + R5)
= 1/2
This reduces our max voltage by 1/2 from 9V to 4.5V. We just need to take our raw ADC reading and multiply it by 2.0 to reflect the actual voltage at the output.
Output Enable
The Converter provides an EN pin that's pulled HIGH (thru a 10k resistor to Vcc). This instantly enables Vout to 9V at power up because D3 (Vdac) initializes to a high impedance state. Now if (for example) you're supplying power to +5V devices at the time, then an output at 9V could damage these devices!
For safety, we install a 1k resistor from EN to GND to bring the Enable voltage below the ON threshold. Then, by using Digital output D5, we can enable the supply Vout, AFTER Vdac is set.
Parts List
Feel free to select alternate components for preference / availability / cost.
Arduino
- 1 Arduino Uno Rev3 Microcontroller Board A000066
- 1 USB Cable Type A/B (generic)
ProtoBoard
- 1 Solderless Breadboard, SparkFun Electronics PRT-12002
- 1 Pkg Jumper Wires, Various Lengths, M to M, Adafruit Industries
Components
- 1 (PCB1) Sparkfun Buck-Boost Converter, COM-15208
- 1 (RLP,R4,R5) RES 10k OHM 1%, ≥1/10W
- 1 (R3) RES 499k OHM 1%, ≥1/10W
- 1 (R2) RES 620k OHM 1%, ≥1/10W
- 1 (R6) RES 1k OHM 5%, ≥1/10W
- 1 (CLP) CAP CER 1UF ≥15V, ≤20%
Build It - Arduino + Protoboard + Converter
Please note, the diagram above is only a suggestion. Arrange parts and wire the circuit anyway you prefer!
Buck-Boost Modifications
Two quick mods for the Sparkfun Converter
- Install R2 into the available through-hole leads marked CUST on the silkscreen.
- Install R3 as a flying component soldering one lead to R2's pad as shown above (this is the Vfb signal). Solder the other lead to a wire that connects to the Vdac signal at Low-Pass Filter's output.
Move the Slide Switch to the Custom position (same end as the CUST silk screen near the switch).
NOTE: If having Vout = 9V during power-up or software upload is not a concern, you can leave out the EN pull-down R6 and D5 wiring.
Solder 5 wires (3-5 inches) to VIN, GND, VOUT, EN and R3 to connect the Converter to the Prototype Board.
Code 1 - Set Vdac for Desired Vout
Set your desired output Vout in the loop() routine. The C code calculates the required Vdac for the desired Vout and writes the value to the PWM output pin. You can add two lines of code to step through voltages 3V to 9V in 1V increments. Or modify the code for any Vout range you wish.
DAC (PWM) Output
In setup(), you need to configure D3 as digital output and set the clock for a higher PWM frequency.
// configure digital pin as PWM output
pinMode(PWMout0, OUTPUT);
// pin 3 for PWM of 31372.55 Hz
TCCR2B = TCCR2B & B11111000 | B00000001;
Specify Vdac
In setup(), initialize the Scale (m) and Shift (b) values. (Get values from Excel Calculator.)
m = -1.216;
b = 9.056;
In loop(), you specify Vout, calculate Vdac needed for Vout and then write the value to the DAC.
// select Vout and calc Vdac needed for desired Vout
Vout = 6.0;
Vdac = (Vout - b) / m;
analogWrite(PWMout0, Vdac);
Monitor Vout
In setup(), enter the resistor divider used for Vout monitoring and calulate the gain.
R4 = 10000;
R5 = 10000;
Kdiv = R5 / (R4+R5);
In loop(), read the analog voltage at input A0 and convert the ADC counts into a voltage. Note: The R4, R5 divider gain (Kdiv) must be included to scale the reading to the actual voltage at Vout.
// read analog input at pin A0
ADCword0 = analogRead(A0);
// convert to counts to volts
Vout_meas = ADCword0 * (5.0 / 1024.0) * 1 / Kdiv;
Loop Through Voltages
If interested, you can add code to step through Vout from 3V to 9V. Comment out fixed Vout = 6.0;
Vout = Vout + 1.0;
if(Vdac > 9.001) Vout = 3.0;
// Vout = 6.0
Output Enable
The goal here is to avoid an output of 9V during power-up or sketch upload. Initially, the supply is Disabled by keeping EN = LOW with pull-down resistor. We'll first set Vdac to MAX for Vout MIN, then bring EN = HIGH.
In the setup() routine
// write PWM out for Vdac_MAX for Vout_MIN
Vdac = 5;
analogWrite(PWMout, Vdac * 255 / 5.0);
delay(100); // delay (ms) for PWM settling
// ENABLE Supply
digitalWrite(ENout, HIGH);
delay(100); // delay (ms) for EN settling
Downloads
Test It!
Single Voltage Level
Let's test our adjustable supply at the lower range.
- Open the sketch "DAC-adjust-PS-1.ino"
- Set Vout = 3.0
- Hit Verify and Upload into the Arduino.
- Connect a Digital Volt Meter (DVM) leads to the Vout and GND.
- Does the DVM reading get close to 3.0V?
- The LED on the Converter PCB should be dimly lit.
Try the max voltage.
- Set Vout = 9V and hit Upload.
- Does the DVM reading get close to 9.0V?
- Does Converter LED get brighter.
Step Multiple Levels
Try looping through voltages 3V to 9V by 1V.
- Add the following lines of code before the Vdac = (Vout - b) / m statement
- Vout = Vout + 1.0;
- if(Vdac > 9.001) Vout = 3.0;
- Connect a DVM or Oscilloscope to Vout. Do the readings increment by 1V from 3V to 9V?
- Does the the LED get successively brighter?
- Do the Vdac print statements run the range from 5V to 0V?
You can loop over a smaller voltage or time range if you wish.
- Modify the following lines
- Vout = Vout + 0.1;
- if(Vdac > 5.501) Vout = 4.5;
- Change the loop delay from 1000 (ms) to 750, 500 or 250.
- delay(1000);
Calculate R1, R2, R3 - Excel
Download a handy Excel Calculator from eCircuitCenter. Apply it, modify it, try different values, customize for your own circuits!
STEP 1. Enter your desired Vdac and Vout input / output pairs that define the adjustment range.
- Vdac0 = 0V Vout0 = 9V
- Vdac1 = 5V Vout1 = 3V
STEP 2. Calculate Resistors
Choose R3 = 100k and then Excel calculates R2 and R1.
- R2 = (Vout0 - Vout1 ) / (( Vdac1 - Vdac0)/R3 )
- = 120 k
- R1 = Vref / ( Vout0/R2 + Vdac0/R3 - Vref/R2 - Vref / R3)
- = 13.26 k
STEP 3. Scale all resistors (optional) and select standard or available values.
- For example, Enter R1 = 68.1k, which is already on the PCB.
- Spreadsheet scales R2 and R3 by 68.1k / 13.26k.
- Lastly, enter nearest standard or available resistors R2 = 620k and R3 = 510k
STEP 4. Calculate ACTUAL m and b (equations above).
This allows you to calculate (in the code) the required Vdac for a desired Vout: Vdac = (Vout - b)/m.
- m = -1.216
- b = 9.056
Explore More!
Learn more from an article DAC Adjusts Vout on eCircuit Center. You can...
Run an LTSPICE Simulation.
- Learn how to model and run a SPICE simulation.
- Play in the sandbox - change values, see what happens, customize for your own design.
Understand how the equations for the R's were derived.
- I was surprised how a simple 3 resistor network presented a real analysis challenge.
Try a new application: How can you make a circuit that takes Vdac = 1V to 4V to adjust Vout = 12V to 5V (with Vref = 1.25V.)
- Use the Excel Calculator and LTSPICE file to create a solution.