The Design Process of Building a DIY DC Dynamic Load
The conclusion of a very long time investigating the building of a combined AC-DC Dynamic Load (DL) led me to the realization that this is not really possible. At least not without making drastic compromises about accuracy and precision. The AC measurements do not need to be very precise and are, in my case, only occasionally needed, but DC measurements typically need to have the highest precision, stability and accuracy.
The attempts for this combined AC-DC DL are described in another Blog post. There is a lot of information there, so get some fresh Java and have a look. https://www.paulvdiyblogs.net/2022/08/dynamic-acdc-load-cc-cv-cw-batt.html
The above picture shows a stage in the development with the new DC DL prototype as the basis.
To help design this new version of the instrument, I asked for the help of my friend Bud. He is a real designer, and we've done a number of projects together, like the high current RPi UPS, the VBA Curve Tracer and the 100MHz Differential Probe all described on this Blog in different posts.
Bud started a Blog post on Hackaday mostly for the hardware design aspects that can be found here: Dynamic Electronic Load | Hackaday.io I have added that same information in a section below here, so it's all together in one place.
At this moment, we have finished the design of the new version and the final board V5.1 has been produced by my sponsor PCBWay.
Although we have a stable fully working system, I'm still tweaking the software side a bit, because this instrument will do some things a bit different, compared to many other DIY DL designs.
I'll explain that later in more details but here are some pictures to hopefully wet your appetite from the previous prototype V5: (this is almost the final version, read on...)
Specifications:
- Input voltage: 1..100VDC.
- Reverse polarity protection to -100V and a 10A fuse.
- DUT is disconnected by a relays for invalid inputs like reverse polarity.
- Maximum current of 10A @ 40V
- Maximum power 180W @25 degrees ambient temperature (heatsink temp 85C)
- Off state DUT current 1.9uA at 2V, 57.7uA at 60V.
- Volt Accuracy: 0.4%
- Current Accuracy: 0.4%
- Power input: 12VDC Wall-wart 0.5A with reverse polarity protection to -24V and PTC fuse
- CC, BT & CV modes with real-time operation in hardware.
- CP and CR modes have active regulation supported in software (resolution +/-156uA).
- Pulse/transient mode supported by an external Function Generator. 5V=10A
- Current monitoring with a DSO. 1V=10A
- GUI: 128x128 OLED 1.5' color display and a rotary encoder with dual button functions.
- Two temperature controlled fans.
- Protection for over voltage, over current, over power and over temperature limits
- Overall dimensions: 21cm long, 18cm wide and a height of 118cm.
- Weight: approx. 1110 grams
Testing the V4 prototype
This earlier version for the AC-DC attempt is still using the Arduino Nano as the processor. It also had provisions for an on-board transformer, but that got too hot so I took it off.The Nano is not fast enough to process the CP and CR modes, which are regulated in software. At this time, I was planning on implementing the CV mode in software as well, but that did not work at all with this prototype. While looking for a faster processor, I eventually settled on the ESP32. It has all that we need, even though we won't be using the BLE and WIFI capabilities.
This was the first time I really started to work with the ESP32 so I started to experiment with it. This processor is not only much faster than the Arduino Nano, it has a dual core and it has a native RTOS. (real-time operating system) I was hoping that these major features would overcome the Nano limitations.
In the picture below you can see how I tested the ESP32 in-place of the Nano. I simply took the Nano out of it's socket, and used jumper leads to connect to the ESP32.
The next step was to test the ADC that we were planning to use, the 16-bit ADC1115 instead of the on-board 8-bit ADC from the Nano. The on-board ADC for the ESP32 has too many issues, so we can't use it with this application. The ADC1115 has double the resolution, the down side is that the communication with the chip through i2c is very slow.
In the above picture you can see that I wired-up the ADS1115 ADC on a break-out board. With this prototype, I still used the 16-bit PWM functionality, but we were already planning to use a hardware 16-bit DAC.
So after checking and verifying the changes, this resulted in a new prototype, that we called V5.
Testing the V5 prototype
Version 5 incorporated the ESP32, the 16-bit ADS1115 ADC, the REF5040 4.096 Voltage reference for the DAC, the 16-bit DAC8571, test hardware for the CV mode and Bud's vastly improved circuitry to drive the MOSFET's.
Unfortunately, we discovered a few layout issues that we needed to fix by jumper wires and Manhattan style additions. We also found that the ADS1115 was happy with 3V3 i2c voltage levels, but the DAC, that we could not test earlier because of its tiny package, did not. That called for two bi-directional 3V3 to 5V level convertors, and I used a 4-channel circuit board connecting it Manhattan style to test that. To be able to increase the i2c clock speed, I changed the 10K pull-ups to 2K2.
We then figured out a slightly different circuit for the CV mode, eliminating an extra DAC that we were planning to use. Using that earlier method would actually be cumbersome to drive with the planned user interface so the new method uses two CMOS switches to automatically change the configuration to use the DAC for the CC mode and also for the CV mode.
Unfortunately, we also found out that the heatsink I was planning to use, that would fit nicely in the enclosure I also wanted to use, could not handle the heat transfer. Not even close. Not only did things got really hot, we were far away from the specifications! I measured the NFET package temperature at well over 160 degrees C, and the heatsink temperature rose to almost 100 degrees, and that at a mere 90W for only a few minutes. Bummer!
The obvious solution is to use a different heatsink with a significantly larger surface.
Unfortunately, larger heatsinks are very hard to find, unless you go for the typical PC CPU coolers. The ones that are available literally tower above the NFET, and it's not easy to use them for two NFET's or find an enclosure for this construction.
We found two heatsinks that looked promising and I ordered both of them. Luckily, the most promising arrived early, so we could start to test with it. This is the one on the left. It has the largest amount of contact surface.
The one on the right relies on a fan at the end (or even both ends) to blow the air through. Unfortunately, that calls for a small diameter fan and they have difficulty getting enough air displacement, unless they rotate faster, making a lot more of a whining noise. Which is another reason why it is not my favorite.
The one on the bottom is the one I had been using. I purchased a number of them for other projects many years ago. I did an extensive search, but I could not find anybody offering them anymore.
The different heatsink called for drastically different construction because the length of the leads to the NFET's and the critical components on the PCB are very critical. We did not want to split the NFET's and give them each their own heatsink, or mount them on either side of the heatsink.
This is why we ended-up with the contraption below to just try it out. It did not need many PCB changes, so was relatively easy to setup and test. The original fan is now moved from the top to the bottom, getting its air from the bottom of the enclosure. The fan is blowing directly to the fins of the heatsink. We will need to use a second fan to suck the hot air out of the enclosure, which has some ventilation slots.
The first test already showed that we could now easily handle 90W for quite some time, which was not possible with the previous setup. The enclosure we selected later required us to rotate the heatsink 90 degrees horizontally, so a fan mounted on the back panel can suck the hot air out.
A longer-term test at 150W showed that we were on the right track. Everything stayed at manageable temperatures.
At this moment, let me explain what you see on the above OLED display.
On the top, you see the actual DUT (Device Under Test) voltage in blue and below it, the actual DUT current value in green.
Below that is a line that shows the mode (CC = Constant Current) the NFET's are driving the DUT (ON) and the actually calculated DUT power in Watt. The display is in red because the power approaches the maximum value and is there to warn the user.
Underneath the horizontal line is the parameter you set with the rotary encoder. The mA suffix changes with every mode. The last line shows the actual 16-bit DAC value (while testing) and the heatsink temperature in degrees Celsius. The color is orange to warn the user that the temperature is above 60, it turns to red above 90 degrees.
The colors are used to warn the user for conditions like over temperature (90), over-power (150), low (<1V) or negative DUT (wrong polarity), Voltage too high (>100V), over current (>10A), etc.
The discrepancies in the display values for set/actual current are caused by the fact that I for this test I didn't use the sense inputs yet so the drop in resistance due to the high power and long leads is not accounted for. Yet.
The User Interface to drive the instrument is kept as simple as possible, and I let the software do most of the setup underneath the hood.
The rotary encoder that you see mounted on the PCB is there so I can more easily test the setup with this prototype. It will later be placed on the front panel. In the CC mode, as you see above, you set the current by turning the knob. The knob currently has two speeds. If you turn it fast, the resolution goes to 10x so you get to your destination rather quickly. Short pressing the rotary encode button switches the DUT output to on and off, by turning off the drive to the NFET's. A long press switches to the next mode. You simply cycle through the modes in a loop, so from CC to CV, to CP, to CR and from the BT mode back to CC. When you switch to another mode, the output is automatically disconnected, and the instrument is prepared for the next measurement. The mA suffix you see in the Set line, changes with the modes, so from mA, to V, to W, to R and in the BT mode back to mA. There is no separate transient or "pulse" mode, because this feature can be used in all modes. That may not be very practical in all modes but the pulse functionality is as versatile as your function generator supports. (amplitude, frequency, pulse form, pulse width, rise/fall times and offset)
On the front panel, in addition to the rotary encoder and the OLED display, there will be two toggle switches, one for selecting the sense input terminals, and one to select power. There are two BNC connectors, one for the transient/pulse input and one for the DUT current output to a DSO. There will be an USB-C connector to the ESP32 that is required in the Battery Mode and also allows for updating of the firmware. And finally, two 4mm Banana connectors for the power connections and two 4mm Banana connectors for the sense inputs. Simple and efficient. And no, there is no keypad. It is not needed. I dislike keypads so did my best to design around it.
A suitable enclosure
The heatsink has been tested and verified that we can now easily get to 150W, but that is still outside of the enclosure. Because of the height of the contraption, we also had to find another enclosure that would accommodate this construction. Unfortunately, there are not many compact enclosures that answered our requirements.
We prefer a plastic enclosure, because the heatsink is connected to the DUT through the non-isolated NFET's and that can get up to 100V DC.
We also need to modify the enclosure to get enough air in and out. That's a lot easier to do with a plastic enclosure. And we want to be able to make a PCB-based front and back panel.
The height of at least 9cm dictates that you will get (instrument) enclosures that are very wide, and not very deep. They are unsuitable for our requirements, but it's up to the other makers to select what they want.
The enclosure we selected is from the company TEKO. They have many enclosure types, but we selected the AUS series that is pictured below. The top one in the picture below is the one I already used for several of my designs, and was planning to use. With the new hardware construction, it is not deep and high enough. The middle one is wider, but has the same height. We settled on the bottom one, the TEKO AUS33.5. TEKO is a German manufacturer but with a little Google-action, you can find them all over the world, and there are suppliers that send them all over the place. I use www.tme.eu a lot for my purchases, and they carry these enclosures.
So with this version of the prototype, I have been very busy with the testing, implementing and again testing the changes we needed/wanted to make, and all the while further developing the software.
Final Version 5.1 PCB
Based on the now fully working V5 prototype, we have redesigned the board for the new heatsink configuration and made several other changes and corrections. The PCB has been produced again by my sponsor PCBWAY. They financially sponsor this project by producing the boards and sending them to me for free. The turn-around is mostly within a week, and the quality is excellent.
The small TO220 heatsinks you see on top of the NFET's help to disperse their heat better, because they are in the forced airflow. Instead of one 4-pin fan, we now have two connectors (the white ones top left) so the first fan sucks fresh air to the heatsink and the second fan that sucks the hot air out of the enclosure. Both fans are temperature PWM speed regulated by the sensor on the heatsink.
We also switched to another OLED display source, because the one I purchased many years ago was no longer available. We selected a good quality and commonly available version but that has a different pin-out so we fixed that on the PCB as well.
Here is a quick sneak preview of the completed instrument . Note that I switched to even larger TO220 heatsinks on top of the NFET's to get rid of even more heat now that these fins are in the airflow of the second fan.
Here is an overview of the construction.
Battery Test Mode
https://www.paulvdiyblogs.net/2019/03/a-pretty-universal-battery-cell-tester.html
I modified the original code that was running on the Arduino, made it work in the ESP32 environment of the DL and integrated it into the main menu structure.
Designing the Dynamic Load
Making a Current Source that does not Oscillate
We've seen some DIY articles that show the most basic topology for making a current source controlled by a voltage source. Here is a typical topology:
There is no compensation to prevent oscillation -- it assumes that the amplifier has infinite bandwidth and infinite gain. A more practical circuit might be this one:
R1 and C1 create a "pole" that overrides the Opamp's internal compensation to possibly prevent the circuit from oscillating. But this still neglects real world problems. Consider the circuit below:
R2 is added because the gate capacitance of M1 is large (maybe 10nF), which causes the amplifier to become unstable and oscillate. Adding R2 "isolates" the amplifier from the capacitance of M1. R2 is typically 50-300 Ohms. Now we're getting close to something useable.
The size or value of the current shunt R3 is also important to take into consideration. There are two important parameters that drive the value. One is the voltage drop over the resistor at maximum current, which drives the value to be as low as possible, to keep the power dissipation low. However, the value of the resistor also determines the value of Vcontrol, which will be a lower voltage with a lower Ohm shunt. With smaller control voltages you are quickly getting in the realm of component issues, tolerances, offset errors etc. But read on to find how we plan to get that under control.
Our Approach
Oooh...lots more components.
True, but this schematic also accounts for the inductance of the leads connecting the source to our load (DUT). The inductance of the leads makes a big difference in compensating the circuit to prevent oscillation. The values of R_Lead and R_LEAD vary with the length of the wires used to connect V_SOURCE to our load. Typical numbers for L_Lead and R_LEAD are 3uH and 100mR, respectively.
The addition of Q1 and Q2 are not the traditional Totem Pole configuration to drive MOSFET's that you see a lot. In our design, the addition of Q1 tends to isolate U1 from the gate capacitance of M1 and still provide plenty of current to drive the gate. Q2 doesn't do anything...yet. R4 and C1 create a unity-gain crossover that is low enough that the phase shift through the circuit doesn't reach 180 degrees to cause it to oscillate.
With R4xC1 having a short time constant (high frequency) the open loop response of the circuit would look something like this:
Note that the phase margin is nearly 90 degrees and the gain margin is 25 dB, indicating that the circuit is very stable and unlikely to oscillate. But what happens when we include the DUT lead inductance?
Now the phase and gain indicate that the circuit will oscillate at about 283KHz. It's pretty ugly. But this has to be taken into account in the design. The most straightforward way to compensate for the lead inductance is to de-Q it so it doesn't create a large peak in voltage. That's where the snubber circuit comes in (R_SNUB and C_SNUB). If we add about 5 Ohms of resistance across the lead inductance it will reduce the Q of the resonant circuit and help prevent that oscillation. Here's what the open-loop response looks like with RSNUB=4.7 and CSNUB=1uF:
It's better, but the slope of the gain is too steep and the phase margin is only 23 degrees -- not good enough. Also notice that there is a peaking in the gain/phase response at 5MHz -- stay away from this. The easiest fix to increase the phase margin is to increase C1 until you get adequate phase margin. So increasing C1 from 300pF to 3.9nF gives us this:
This looks even more problematic, but it's not. Note that the gain slope as it crosses through zero dB is only 20dB (very desirable for a stable amplifier). Note also that the phase margin has increased to 86 degrees and the gain margin is around 35dB. What we have given up is bandwidth since this loop only has a gain-bandwidth of around 25kHz. But that should be good enough for our purposes. We still need the snubber because without it the phase margin would still be near 90 degrees, but the gain margin degrades drastically to less than 10dB, which is marginal to prevent oscillation.
But wait...there's more. If we decrease the set point current from a high current to a very low current, say less than 25mA, the gain-bandwidth of the loop decreases to around 130Hz. This is smaller than desired, but probably still usable.
So what are the other components for?
R1 provides current to decrease the emitter resistance of Q1 and also drive the gate toward GND. Q2 protects Q1 from a nasty transient that could damage it. And R2 limits the current into the base of Q2 if the Opamp output goes below GND. More on that in "Forcing Zero Current - Nicely"
NFET Selection
Bud had picked out quite a few NFETs that he thought would be good candidates for this project: IRFP150, IRFP250, IRFP350, IRFP460, etc. In my previous attempts, I used the FCH072N60 that we used in the Curve Tracer design and this worked well for me. I also tried it in the V5 with good results.
What's so critical about the NFET selection you ask?
Most MOSFET's are designed for switching applications. That's their target market. We use them differently, as a variable current source and that's not an ideal application. The most critical specification for our application is the Safe Operating Area (SOA for Current vs Voltage) under DC operating conditions. For some NFET's, this is not always specified, go figure!
Here is the SOA of the SUG80050E that is specified as a 150V and 100A device. The SOA diagram however, shows that we can only use it up to 10A at 40V and 4A at 100V - at 25C and at DC!
After reviewing Kerry Wong's video about linear FETs Bud went back through his list of candidate NFETs and culled out most of them. Nearly all of them did not specify a SOA under DC operating conditions...big red flag! Bud then went back to DigiKey and LCSC to see if there were any that would satisfy our SOA of 100V @2A.
He found these:
- SUG80050E (Still the best one)
- FCH76N60NF (OK and we have a simulation model)
- IPZA60R045P7 (can't get the sim to run with this spice model)
- IXTH60N20L2 (expensive and no model)
- IXFH56N30X3 (ditto)
- MS170N15IDC0 (Chinese, but specs look OK. Needs derating. No model.)
- NVHL055N60S5F (no model)
- RU1Z200Q (Chinese.)
Without a SPICE model it is difficult to tell if it will work in the circuit. Therefore all we can do is list them as potential substitutions for the one we eventually pick, which right now looks like the SUG80050E. Spoiler alert, we did.
Opamp Topology Analysis
After we got the Constant Current (CC) loop stable it was time to account for the configuration of the rest of the circuit -- the topology. We stumbled upon a topology that appears to yield very good accuracy with the addition of just a few resistors. Below is the basic topology of a single NFET current loop:
What we need to know is how the output current depends upon the input voltage, VIN. The schematic above uses only 2 values R1 and R2 as a special case of this topology that we employ. V+ and V- are the voltages at the inputs of the ideal Opamp (infinite gain, no offset).
The equations that govern this are:
V+ = (VIN - V2)(R2/(R1+R2)) + V2
V- = V1(R1/(R1+R2))
Since the Opamp forces V+ = V-, when you solve for V1 it yields:
V1 = VIN(R2/R1) + V2 , as you would expect.
And the output current, I_OUT is therefore:
I_OUT = (V1 - V2)/RS = VIN(R2/R1)/RS
Note that V1 and V2 drop out of the equation. Like an instrumentation Opamp. The only errors are the ratio of R1/R2 and the value of RS, the shunt.
When we expand the topology to two separate current loops we get this simplified schematic. Again, the resistors values are special cases to match the topology and make the math easier.
Now it gets a bit more complicated. We want the current, I_OUT, to be only a function of the input voltage, VIN. Here's the equation for V+, which is the same connection for both Opamps:
V+ = VIN R1/(R1+R2) + R1/(2(R1+R2)) (V2A+V2B)
and since V+ = V-,
V1A = VIN(R2/R1) + V2A/2 + V2B/2
But what we really need to know is what the output current is:
I_OUT = IA + IB = (V1A - V2A)/RS + (V1B - V2B)/RS
The Opamps are forcing V- to equal V+, and therefore V1A = V1B, so we can substitute :
I_OUT = IA + IB = (V1A - V2A)/RS + (V1A - V2B)/RS = 2(R2/R1)VIN/RS,
which is only dependent upon VIN and the three fixed resistor values. Of course, this is a trick of a sort since I've forced the resistor values to be identical or a 2X multiple. But realize that the errors in the method are below the tolerance of the resistors (sub-1%).
By inspection, it is obvious that if the "B" side of the circuit has errors that increase the current through MB, then a corresponding decrease in current will occur through MA. In order to prevent this disparity from getting too large, a careful layout symmetry between the two sides must be preserved.
Accounting for the dual sense resistors
The next step in the process is to expand the sense resistors to two sets of two. This is to keep the power dissipation in the resistors to a reasonable limit. The math gets a bit unreasonable (for me) and so Bud resorted to LTSpice to corroborate the result -- it is the same.
This is the same circuit as before, but this time Bud inserted parasitic resistors, the ones labeled RP, to indicate where the various error voltages will come from. The values of RP depend upon the quality of the PCB layout -- they are not all the same. Note also that the ground return point of the current could be different than the ground reference of Vin. This is an important given for this topology that could mislead the unaware.
The analysis shows that the errors will still be cancelled to a first order. Again, you get the same result, if you keep the resistor values in the same ratios, the output current is only dependent upon VIN, R2/R1 and RS.
One complexity is that the 2kR resistors must be Kelvin connected across the sense resistor, RS, in order to get the full benefit of this approach.
Simulation Results:
To prove the point, Bud simulated the circuit in LTSpice using Monte Carlo analysis. Here's the complete circuit:
The tolerance of the gain setting resistors is 1%, but I set them to near 0% in the first simulation while letting the parasitic metal trace resistors have a tolerance of 20% and a tempco=4300ppm/C. The simulation ran 50 times at 25C and 50 times at 100C. The results were uninteresting to say the least -- total variation in output current from the 10A set point was...13.6uA. That doesn't include any Opamp variation except temperature. That is a variation of only 0.000136%!
When Bud added a 1% tolerance to the other resistors the result was more interesting:
The bottom plot pane is the output current. It varies as expected, about +/- 1.3%. The top plot pane is the current through M2, which varies a lot more due to the 20% tolerance and higher TC that I set for the parasitic resistances. The results get even more interesting when the resistor tolerances are set to 0.1%.
The output current variation drops by a factor of 10, but the variation in the current through M2 doesn't decrease much since it has the added variation of the parasitic trace resistances.
So it would seem that using 0.1% resistors should negate the need for a trim...but not so fast. Try to find 80mR 0.1% sense resistors.
If you re-run the simulations with 0.1% tolerances for the "regular" resistors and 1% tolerances for the sense resistors the simulations show that the output current variation is 0.62% (not 0.15%). It seems using 0.1% resistors will not yield much better results than 1% overall, unless you can get 0.1% sense resistors (good luck). We're keeping the trimmer.
Accounting for Errors in the CC Loop
We have selected a topology that minimizes gain errors to a first order -- primarily resistor tolerances. The next question is what Opamp will give us the best bang for the buck when it comes to all of the errors associated with the amplifiers? Bud put together a spreadsheet to add up the various errors caused by the Opamp.
For perspective, it is worthwhile to note that 1mA of current requires only 20uV of voltage across the 20mR sense resistor. With these small voltages you are quickly in the realm of component issues, offset errors etc.
I (Bud) have used a MCP6V51 Opamp on another project and was impressed. It is a chopper-stabilized (i.e. zero-drift) Opamp with incredible specifications. On the right side of the spreadsheet above is the TL071 -- a general purpose JFET-input Opamp. The first section lists each Opamps specs with regards to input offset voltage and input bias/offset current, as well as the open-loop gain (AOL) for both typical and worst-case values. Below that I calculated the effective resistances at the inputs to the Opamp and the expected maximum temperature range (25-100C).
AOL Error
In this application the amplifier has to drive the NFET gate to around 3-4V before any current flows in the NFET. If the open-loop gain is low then the amplifier will require more of a voltage difference between the + and - inputs, which incurs an error. The MCP6V51 has a typical open-loop gain of 150dB (32 million V/V) vs. the typical TL071 AOL of 125dB (which isn't shabby at 1.8 million V/V). To output 3V the MCP will need a voltage difference of 94nV vs. 1.7uV for the TL. Under worst-case conditions, the MCP needs a difference of 0.8uV vs. 7.1uV for the TL. So the the lower AOL causes about 0.3mA of error from the TL vs. only 0.04mA of error from the MCP.
Input Current Errors
Input bias current and input offset current errors are typically better for the TL but worse for the worst-case specifications. They are small for both Opamps.
VOS Error
The input offset error is the biggie, and it's made worse with temperature drift. Worst-case VOS for the MCP is nearly 20uV, which is 1mA of error. Worst case VOS for the TL is more than 4mV -- an error of more than 200mA. Even the typical TL VOS error is nearly 60mA, not good enough.
Temperature Drift
The initial offset of the system can be removed by measuring and storing the offset current. But as the box heats up from a high wattage load, the offset and gain terms will drift, causing errors. If you compare the VOS drift terms between the two Opamps there is a clear winner. The MCP has 50X lower drift over temperature.
Forcing Zero Current - nicely
When the system boots up the relay should be open and the CC DAC should be set to zero. But this doesn't necessarily set the output current to zero. If the Opamps controlling the current loops have a positive offset they will be unable to fix the current at zero. And if the offset is negative, the Opamp output will drift to its negative supply rail if not constrained. Therefore, the only way to get zero DUT current is to force it through some other means.
Dominik solved this problem by yanking the Opamp input to a high voltage, which drives the output to its negative supply rail. This does indeed enforce a zero current state at the output, but not without issues during normal operation. Here is some detail about his solution:
The leakage current from the collector of Q11 is not usually a term anybody cares about. In this case, the S9015 has ICBO=50nA, which is pretty low. However, this current generates an offset term across R18 equal to 0.5mV, or 5mA per Opamp (and there are 4 of these, but not all will generate a Worst Case (WC) leakage current. In our case, it would create an output current error equal to 12.5mA.
The Keysight design just yanks downward on the Opamp output, forcing the Opamp to output a short circuit current. This is bad because the Opamp generates a relatively large output current, but is good because any error current from the downward yanking device gets swallowed by the Opamp in normal operation and doesn't impact performance.
Both of the approaches above force the Opamp into a state of inequality. The output is driven to a rail and the inputs aren't equal, which is a bad thing. When the Opamp is released from this condition there is usually a transient spike of uncontrolled magnitude until the conditions of equilibrium are re-established. Generally not good.
The BAV199 low leakage diodes are actually specified over temperature and voltage which is pretty unusual! They're spec'd at a max reverse leakage of 5nA at 25C, and 80nA at 150C. The datasheet even provides data for typical and max leakage current as a function of temperature: 3pA typical at 25C, 300pA typical at 100C, 5nA max at 25C and 30nA max at 100C.
In normal operation D3 leaks current into the "+" input of the two Opamps controlling the current loops, getting absorbed by the 500R equivalent resistor at that input. But this is partially compensated by a reversed biased D2 leaking current into the "-" input of Opamp U1 (and D1 leaking into U2), getting absorbed by the 1k resistance at those inputs. The currents are not going to match, so we can use typical vs worst case to see what the range of error might be. But the difference between typical and WC is so large that the typical value can be set to zero. If D2 is leaking worst case then it will produce an output current error equal to -(30nA x 1k)/0.04R = -750uA. If D3 is the WC condition then it will produce an error current equal to +(30nA x 500)/.02R = +750uA. So it seems the error current will drift somewhere between +750uA and -750uA WC as the box heats from 25C to 100C. If we just use typical numbers then the offset error drift is only -7.5uA. That's manageable.
How it works
Normally, the DAC_OFF signal generated by the ESP32 is low (zero volts). Therefore Q6 and M3 are "off" and the BAV199 diode, D3, is reversed biased and not influencing the current loop significantly. If the DAC_OFF signal is asserted to 5V then Q6 drives the gate of M3 to a VGS ~ 4V and M3 switches "ON", which then pulls its drain to -5V. R29 then forward biases the upper diode of D3 and pulls the "+" input of U1 below ground. The amount of negative voltage at the "+" input of U1 depends upon what the DAC value is. If we assume the DAC is outputting 4.096V or less, then the Opamp "+" input is yanked below GND. Since the gate of M1 can't go below GND the Opamp output will drop, forward biasing D2 until the Opamp inputs equalize...somewhere around -1V. R3 is there to limit the current into the base of Q2. So now the gate of M1 is at GND and there is just some leakage current flowing through the NFET.
Note that the ESP32 is a 3V3 device, so the DAC_OFF voltage is not asserted to 5V. This is accounted for in the final circuit values.
The final result of all this is that there is no big current spike at the output when DAC_OFF is de-asserted.
PCB Layout Challenges
At first, we were going to use a higher amount of copper for the PCB, but that would increase the price and the delivery time. It's also easy to forget to order this thickness, and that could cause serious issues for other Makers. So instead, we are specifying the default 1oz copper for this PCB. That change increased the traces carrying 10A to blow up to 6mm width and the traces carrying 5A are now 2.5mm wide.
The GND reference
The first thing to notice is pin 2 of J1 (find it just below and to the right of U7) -- that is ground zero for the entire PCB. It is the absolute GND reference potential for the system. This is where the negative input lead of the load connects to the PCB. All of the various power inputs and outputs connect to this point.
The 12VDC power adapter negative lead (in Blue) snakes around to the right and comes directly to that lead (a Kelvin connection). The top-side metal traces (in Red) that bring currents from the sense resistors, R4-R5 and R8-R16, are split equally/identically in terms of resistance, from those resistor's pads to J1 pin2. Those traces carry a maximum of 5A/each and are properly sized, by width (2.5mm), to carry that current without over heating.
The snubber capacitor, C11, also connects directly to the J1 pin2, but with a much smaller trace width since the currents should be smaller.
Lastly, the ground plane is almost a Kelvin connection but must share a small section of bottom-side metal trace. Hopefully, it will not matter much.
High Current Paths
The high current traces carry 10A max and require a trace width of 6mm. The input connector, J1, has a 6mm wide trace (in back-side metal, Blue) from it's positive terminal to the fuse, and also from the fuse to the relay (back-side metal, Blue), where the trace eventually splits and reduces to 2.5mm to handle the 5A currents to the drains of M1 and M2.
High Voltage and Creepage
The pads of the high voltage devices/connectors must have sufficient distance from other pads to prevent creepage. High potential between pads located close together can develop conductive "growths" that cause parasitic currents to flow and can eventually cause failure. This is not only a problem for exposed pads or traces that are not covered by the solder mask. The recommended pad separation distance to prevent creepage for a 100V potential is about 1.5mm. Traces located under a solder mask only need to be separated by 0.4mm to withstand 100VDC. The layout conforms to these restrictions.
Kelvin Connections
This connection technique is named after Lord Kelvin. Here is the layout detail on the left side:
The current tends to spread in 45 degree funnels from a single point to a connection point, such as a pad on a component. In order to make the Kelvin connection, the current should be zero at the point of the Kelvin connection. I made triangular copper pours to distribute the current to the two sense resistors. The back-side of the pads should have zero current flowing to it and therefore a good place for a Kelvin pickup. The pickup points are on the middle-inside of the pads on the sense resistors. Those traces connect the feed resistors for sensing the voltage across the sense resistors.
There is another method of picking off Kelvin connections from SMD devices, but this method was recommended by the manufacturer of the sense resistor...who am I to argue. We'll see how well this performs when we get the PCBs to evaluate.
Theory of Operation
( I have made a few refinements for the off-board parts, so PCBWay can produce and populate the board for their clients)
Dual fan
1a to give both fans their own pull-up so we could, potentially, still monitor one of them. At this moment, we only have V5.1 produced and that is what Bud and I are using. Eventually, we will publish the Gerbers for V5.1a, but will do that when we have completed all the tests.
Power Supply
DAC Circuit
The ADC Circuit
The DUT input protection
The nice things about relays are that they don't leak current when they're open and have decent contact resistance when closed so measurement errors caused by the contacts are minimal.
The CC mode operation
The CV Mode Challenge
The baby is ugly, but can it perform the function?
It appears so, but when Bud designed it we only had simulation to rely upon
(and simulation is not reality). Here's a simulation result showing the system
at startup. The parameters were VLOAD=20V, RLOAD=1k, ISET = 0.05 (125mA max)
and VSET=0.2V (5V). The green line is the load voltage. The red line is VCV and
the blue line is the load current.
In CV operation VSET is a voltage between zero and 4V, which equates to
a load voltage of 0-100V. ISET sets a maximum output current for the current
loop and the CV loop decreases that current, by forward biasing D2, until the
current at the load balances. This will happen when V_DUT equals VSET. There
must be a current limited voltage source or a series resistor, RLOAD, in place
for this to work. The astute observer will note that the voltage feedback is
via the "+" input of U2 and therefore there is nothing controlling
the CV loop dynamics except what is available in the CC loop. The easy way to
see this is realize that at high frequencies U2 is essentially a voltage
follower to its + input. This may prove to be a big mistake. (spoiler alert, it is not) It would have been
preferable to use two inverting opamps in the CV loop so that the V_DUT signal
would be attached to the "-" opamp input and separate loop dynamics
could be implemented. (Like what Keysight did.)
The
system is held at zero output current for 5ms and then released. The CV opamp
is out of control until VSET changes from zero to 0.2V, but it has to slew to
1.2V below GND before it takes control from the CC loop. Since the CC loop can
output 125mA it drives the output voltage to zero (125mA x 1k = 125V, but only
20V is applied). Once the CV loop overcomes the CC loop the current decreases
in the CC loop and the load voltage rises to the set point (5V). A 1V-peak
sinusoid on top of VLOAD is applied at 560ms to show that the CV loop can keep
the output voltage stable when disturbed. I think it performs pretty well, if
slowly.
But slowly might be OK. The way that Paul is approaching the user input
is to start at low values and have the user scroll the setpoints to whatever
he/she desires. A user is a pretty slow animal too.
To demonstrate the other end of the spectrum, here is a different set of
conditions/parameters:
The input voltage is only 5V and the max CC current is set to 10A. RLOAD
= 10R and VSET = 0.1V (2.5V). Note that the CV Opamp takes longer to slew to
start controlling the CC loop, but the result is pretty much the same. There is
a lot more disturbance caused by the 2Vp-p wiggle on the load voltage, which
begins at 900ms. Still, the reduction in load voltage wiggle is substantial.
At this point in the design process Bud was hoping that the CV mode is
"good enough".
When we actually tested this with the real hardware, I found that it works really well! Unfortunately, it will take a few more weeks before Bud can build his instrument and compare notes.
The acid test is of course to lower the DUT voltage by applying more and more current. They way I implemented this in software, is to first measure the DUT voltage, and then set the CV mode voltage at 110% of that value. This will not cause any current to flow when you turn-on the Dynamic Load, but you are now already close to the tipping point. If you now lower the set voltage by the rotary encoder you will see that the current will start to increase, eventually forcing so much current that the DUT voltage starts to cave in. It's the tripping point that is so difficult to implement in software due to the relatively slow loop response, typically resulting in a sudden over current that can cause issues, especially with power supplies that have a CC/CV mode itself. It's easy to mess-up the regulation, making the CV mode pretty useless.
Our version works really well, kudo's to Bud!
The V5.1a schematic shows the real implementation of the CV mode. When the CV mode is selected, the DAC output is switched through a CMOS switch (U15) to an Opamp (U10) that controls the output circuitry through R567 and D3. This is the same circuitry that turns the output section on or off. (signal DAC_OFF) The CMOS switch U14 supplies a maximum current of about 4A for the CV mode set by R42 and R46. You can change that if you're brave.
Using the CV mode
CV mode with a regulated (CV/CC) power supply
Note that with a Lab Power Supply as a DUT, the CV mode is a bit more difficult to use due to the rapid switch of the power supply from CV to CC at the DL tripping point. You need to carefully adjust the encoder to get to an actively controlled load.
CV mode with an unregulated supply
To better test the CV mode and get more familiar with it, you can use an (unregulated) power supply that does not have current fold-back or current limiting/regulation. A transformer with a (bridge) rectifier and an electrolyte filter capacitor will much better show the CV mode regulation in operation. This kind of DUT will clearly show the sagging DUT voltage as a result of the load.
CV mode with a battery
Basically any battery or cell will provide another DUT to get familiar with the CV operation. Be aware that some of these cell can deliver a lot of current. This is one of the reasons that in the firmware, the current limit in this mode is set to 4A, hopefully preventing injuries or fire-works. Because the battery or cell will to its utmost to keep the voltage stable, you can clearly see the effect of the current changes.
Transient/Pulse Mode
Instead of adding a special external digital transient mode, we decided to add an input for a Function Generator (FG) to produce arbitrary waveforms. The resolution is 5V = 10A. The Function Generator allows you to set an offset, to allow switching between a lower and a higher current, use different frequencies, different waveforms, and even set the leading and/or trailing edges of the waveforms. Whatever your FG can do. Of course, you can still feed a TTL level signal created by anything you concoct (555 timer?) or desire to use. You can even use the calibrator output from your scope.
To protect for ground shorts between the Function Generator and the instrument GND, which is connected to the DUT, we use a PTC.
There is no special transient mode, this functionality works in principle in all modes, although in reality, that may not be very practical.
Nota that the transitions or edges that are turning the load on and off are not very fast, so of limited use to really test power supply transient responses, but it is sufficient in most cases.
DUT Current monitor
We also added a Current Monitoring capability -- a voltage output scaled to 1V = 10A, to see the real-time current transient output on a DSO. This allows us to see the DUT responses when power is applied or removed to test the regulation of the DUT. This works together with the Transient/Pulse Mode.
To protect for ground shorts between the DSO earth ground and the instrument GND, which is connected to the DUT, we use a PTC.
When using the Current Monitor, you will see some "hash" on the trace.
Here we see the monitoring of a 1Amp current, but on top of the trace we also see the SPI related hash. The OLED display is updated at regular intervals with some critical information, and every second with the rest, as indicated by the hash with a longer duration.
Unfortunately, these high-speed SPI signal transitions find their way into the rest of the circuit.
Above you see the SPI CLK signal in relation to the hash on the Current Monitor.
Here is the CLK signal in more detail. The SPI CLK signal generated by the ESP32 has a period of about 120ns at a 3V3 level. This is powerful enough to make it's way into the rest of the DL circuits.
I tried to reduce this effect by designing an SPI-isolator circuit that galvanically separates the OLED display circuit from the rest of the circuits. The OLED display board has it own Buck regulator to create a 3V3 voltage and also has a higher voltage Boost regulator to supply approx. 12V. At first I tried to give the OLED board it's own power supply, but that didn't make a difference. Of course that still used the same common ground. Interestingly, when I pull the OLED plug from the main board, the hash is gone. This lead me to design a circuit that galvanically separates the OLED board from the rest of the DL circuits, with the (unfounded) hope that the hash originates from the OLED board, making it's way back to the main board.
I designed the circuit such that it can be inserted in-between the connector on the main board, and the OLED display cable going to the other end.
The ADUM5000 provides a galvanically separated power supply where the output can be selected between 3V3 and 5V with a jumper. The ADUM7440 is a 4-channel isolator circuit. The 5th connection, the RST line, is not passed through, but re-created by an R/C combination to provide a power-on reset.PCBWay produced the board and shipped it to me free of charge as part of their sponsoring agreement with me.
Dynamically increasing the ADC resolution
While working with the DL in real applications, and also during the development of the calibration and verification instructions, I became aware of a "design" constraint that I initially built in. While developing and testing the instrument, I was forced to set the internal gain of the ADS1115 ADC to the minimum (gain=0) because the maximum voltage that we apply to the ADC input required that.
As you can see in the DL schematic, the DUT input voltage going to the ADC is divided by 24.15 through the input attenuator, With 105V as the maximum before the software cuts the load, the attenuation drops this to a value of 4.37V. Below is the table in the ADC1115 data sheet:
A Programmable Gain Amplifier (PGA) inside the ADS1115 can be programmed with different gains to create the maximum LSB size for the input. As you can see, I could not program a gain higher than 0, so we were "blessed" with a high enough input range (6.144V), but "stuck" with a resolution of 187.5 uV. And that for the whole range from 1..105V. While investigating the data sheet again, I got an idea and searched around for confirmation. The information is scarce but it seemed possible to change the gain dynamically and when I tried that, it worked.
In the firmware, I now read the ADC first to see what the DUT voltage is, set the appropriate gain if not already correct, and if needed, do a second ADC read with the new gain. This works great so we now have a much better resolution for lower voltages. That's the good news. Unfortunately, this does not work well with reading the current. I do however use the optimum gain setting for the temperature input.
The resolution for the DUT voltage is now:
- Gain 0 for 99-105V 4.54mV/bit
- Gain 1 for 49-99V 3.02mV/bit
- Gain 2 for 24-49V 1.51mV/bit
- Gain 4 for <24V 0.75mV/bit
The downside is that we now have to send more sets of instructions over the SPI bus to the ADS1115, instead of one, and that increases the loop-time of the firmware to about 35mS. This influences the dynamic behavior for the CP and CR modes a little because they are regulated in software, based on a calculation that involves the DUT voltage and the DUT current. A small price to pay.
Because the OLED display will flip about 3mV in the 49-99V range for every bit change of the ADC, I'm using a moving average filter with a ring buffer size of 16 to reduce the annoying flipping of the OLED display. This filter is only used for the OLED display values, and is not used for the values that are used in the main loop so that we keep the system as responsive as possible.
The CP and CR modes
As we have seen earlier, the CC and CV modes, and the derivative BT mode of the CC mode are all regulated in hardware. The system sets the parameters by the rotary encoder and furthermore just collects the voltage and current values to display them.
The CP and CR modes are different. In both modes, we use the desired setting (in Watts or Ohms) and translate that into a DUT current, because that is what we can control. This means that in the CP and CR modes, we need to use the encoder setting in either Watts or Ohms and calculate on the fly what the current needs to be, to create the right amount of load for the DUT.
Several DIY designs I found allow you to setup the measurement, but they don't take changing DUT voltages into account. That's not good enough for me, so I do the calculations and regulation on the fly. This is the main reason why we need a very fast processor, and also a very tight controlling loop so the response to changes is as fast as possible. That's also the reason I selected the ESP32 with the RTOS system, so I could create different tasks that run on different cores, and keep the main loop as fast as possible (currently about 18ms).
In essence, the controlling loops for the CP and CR modes measure the difference (the delta) between the desired setting and the measured and calculated DUT result, and adjust the DAC on the fly to create the desired result. The DAC is incremented and decremented in steps based on the delta between the desired and real results until the delta is zero. Initially, when you turn on the load, the delta will be reduced progressively in several steps getting to a zero difference. This happens with the loop-time of about 35ms and that determines the step granularity over time. The positive side effect of this active regulation is that it compensates for temperature related changes. The resolution of the regulation is +/- 1 bit of the DAC setting or about 156uA.
From a user standpoint, the CR mode works a little different from the other modes (albeit more like the CV mode) because you would expect the decoder to start with an initial low value. A low (resistance) value will result in the maximum current and this is undesired and not very user friendly. So the solution to this is that the system measures the DUT voltage, and creates an initial resistance value that will result in a safe current of only 100mA, when this mode is selected. The user can then change the resistance from this setting onwards.
One Caveat to watch out for in the CR mode
When the regulation loop is trying to get the delta to zero, there could be some overshoot in the current when the DL is turned on with low resistor values (high currents). If you use a lab power supply at the maximum, it could trip the CV/CC regulation of the supply.
In the above screen shot, the DUT voltage was 30V, the DL was set to a resistor value of 10 Ohm, which would result in a 3A load when the DL is turned on. The overshoot in this case is approx. 400mA for a short period. There is no problem when switching the DL load off.
Temperature drift
Here are some measured temp drift numbers that Bud made:
60V -- 1.000722A @ 30C, 1.001466 @46C (0.074%, 46ppm/C)
60V -- 3.000393A @ 30C, 3.0103 @80C (0.33%, 66ppm/C)
30V -- 6.0014A @ 30C, 6.020A @ 79C (0.31%, 63ppm/C)
The above numbers are consistent with the 50ppm/C sense resistors we used. That's what we bought from LCSC. You can get 25ppm/C 2512 resistors for about $1/each from Digikey ( TLRP3A30CR080FTE) or LCSC. LCSC even has 15ppm resistors for about $12/each Y14870R08000D0R. A 15ppm/C resistor would be a big improvement -- maybe only 25ppm/C drift, which would be 0.125% across 50C. If you used the 25ppm/C resistors figure around 0.175% f, which might be worth spending the $4 on (or only $0.8 at LCSC).
Construction
Details of the construction will be described in a dedicated Blog post here:
https://www.paulvdiyblogs.net/2024/09/building-diy-dynamic-dc-load.html
Note that I'm still tweaking the Blogs for this instrument.
Gerber Files, Firmware & BOM's
If you like what you see, please support me by buying me some Java: https://www.buymeacoffee.com/M9ouLVXBdw
For those that did, thank you!
No comments:
Post a Comment