Let’s test the system’s current and power capabilities!
Current Control
One thing I noticed very early on in this project was that the system had very poor control over current, which is bad for a variable load. When I set the current to be 2 A, the actual current was about 1.4 A. When set to 4 A, the actual current was about 3 A. Due to this poor performance, I implemented the current control loop discussed earlier. This made the results better, and I moved passed it. Since the assembly is complete, and the code is all done, I decided to revisit this issue and find out why the error was so big without a control loop.
It turns out this is a hardware problem. As discussed before, an opamp compares the current going through the variable load and the output of a DAC, and then adjusts its output (and the load’s conductance) accordingly. Unfortunately, the opamp cannot do this if it is oscillating:

Above is the opamp’s output. For a given DAC voltage, the opamp output should rise if not enough current goes through the load, fall if too much current goes through it, and be stable otherwise. But why, then, does the opamp output oscillate when not enough current goes through the load?

The large gate capacitance of the transistor causes a phase shift, resulting in oscillation. Since the power transistor is actually a bunch of smaller transistors connected in parallel, the gate capacitance can be quite substantial; 40,000 pF at 25 V, according to the datasheet. This, together with R8, causes the voltage at the gate to be a delayed version of the opamp’s output. Since the opamp is reacting to the current through the load now, but its actions are delayed, the system becomes unstable. The oscillating output of the opamp results in an average current that is incorrect. The control loop shifts the center point of the oscillation, resulting in correct average current, but it’s still oscillating, which can be disastrous for certain applications.
The key to fixing opamp instability is a feedback capacitor; C38 in this case. While R8 and the gate capacitance slows down the opamp’s response, increasing the delay around the loop, C38 provides a low impedance (quick) way for the opamp’s output back to the opamp’s input. In other words, C38 provides a shortcut to counteract the delay. C38 was originally meant to prevent oscillations, but apparently 47 pF is too small for it to be effective. After some simulations, I settled on a new value of 10 nF.

The waveform above shows the opamp’s response when current through the load goes from 0 A to 4 A. As you can see, the opamp output is stable before and after the transition, and the transition is very smooth. No more oscillations!
After the oscillations were removed, I was curious how accurate the current control was without a control loop. The following test was done:

Control loop is disabled for this test
The results are shown above. We can conclude the following:
- The error is mostly independent of voltage across the load
- The error seems to change by about 10 mA per amp. At 1 amp, error is ~35 mA. At 2 A, error is ~25 mA, etc.
- The error is in the range of tens of mA
In a previous post, I used the following image:

Here, you can see that the output of the comparator depends almost entirely on the ADC reading. For example, if target_current is 1 A, but the ADC reports 0.5 A, then the output of the comparator will go up. If the ADC continues to report 0.5 A for some reason, then the output of the comparator will continue to increase, potentially reaching a massive number. This arrangement was necessary because when the opamp was oscillating, the output of the DAC didn’t correspond well to the current through the load. Therefore, it was necessary to let the comparator have a wide output range to counteract the oscillation. As stated before, setting target_current to 4 A would result in a current of 3 A. This would cause the comparator output to increase until the ADC reported 4 A.
This has two major disadvantages. Firstly, the comparator output has too much freedom. Let’s say that no power supply is connected to the variable load. If you set target_current to 1 A, then the ADC will always report 0 A since there’s no voltage across the transistor. This will cause the comparator output to increase to it’s maximum value, resulting in the transistor being as conductive as possible. Then, if power is applied, since the transistor is at maximum conductance, the power supply hooked up to the load will probably blow a fuse or trigger the overcurrent protection since the transistor has become a dead short.
Secondly, this control loop can only run as fast as the ADC can be sampled. Since the comparator output can only be updated when the ADC is read, and the ADC can only be sampled at 60 Hz, the control loop can only run 60 times per second at most. This is fine for constant current mode, but if you want to test a system with variable output voltages, and the system is in constant power or constant resistance mode, then 60 Hz is probably too slow.
By fixing the opamp instability, we can come up with a new scheme to address both of these issues:

In the new control scheme, desired_current is calculated. Then, offset is added to the calculated value. I’ll address what and how offset is calculated later; for now, say it’s 0. In other words, desired_current is written directly to the DAC. This will affect the conductance of the transistor, and this will result in a change in the current through the load. This current is then measured and then read by the ADC. Now, the software reads the ADC, compares it to desired_current, then adds the difference to offset. The whole loop then starts again.
Let’s take an example. Say you want to set a current through the load as 1 A. According to the table presented earlier, the resulting current is 1.025 A, which is a little over. Now, offset becomes -0.025 A. Then, instead of the DAC being updated for 1 A, it is updated for (1-0.025) = 0.975 A. The current through the load is measured again, and offset is updated once more.
How does this new scheme address the two issues brought up earlier? Let’s take a look.
Firstly, this new scheme allows the DAC to update much more quickly. In the old system, the comparator output determines the value written to the DAC, and as said before, the comparator output only updates at 60 Hz. In the new system, the DAC is updated at 1 kHz since the DAC output depends primarily on desired_current. Sure the value written to the DAC is modified by offset, which does update at 60 Hz, but offset is very small; offset is for fine tuning. In other words, now that the opamp is fixed and the current through the load has a strong dependence on the output of the DAC, we can get close to the desired current through the load rapidly, and then approach the desired current using offset.
Secondly, offset is bounded to ±50 mA. In the old system, if the ADC showed that the current through the load was too small, then the transistor would become more and more conductive, which resulted in the possibility of blowing a fuse or resulting in overcurrent. Now, if the ADC reports that the current through the load is too small, then offset will continue to increase until it hits 50 mA. Then, since it has reached its limit, it will stop increasing. Now, the transistor will only conduct 50 mA more than it’s expected too. For example, if the load is set to conduct 1 A, but there is no voltage across it, then offset will increase to 50 mA. Now, when power is applied across the load, instead of blowing a fuse, the load will only consume about 1.05 A. As the current through the load is measured, offset will eventually decrease, and the current through the load will become 1 A.
Thermal Testing
How much power can this thing handle? Let’s test it out!
Disclaimer: unfortunately, I only have a power supply that can output about 150 W. I’ll can test up to the limit, but then I’ll have to extrapolate if the load can handle more.

The above shows the results of my experiment. Thermocouple 1 is the most important temperature, as it was placed very close to the transistor on the heatsink. This is the temperature of the heatsink. Of course, the temperature is overestimated due to its proximity to the load, but I wanted to be conservative. Now, in order to calculate the junction temperature, I used the trusty equation ΔT = P * RTH. Here, ΔT is the difference in junction temperature and heatsink temperature, P is the dissipated power, and RTH is the sum of all thermal resistances between the transistor’s junction and the heatsink. The datasheet gives the thermal resistance from junction to case (of the transistor), and then case to heatsink. I also applied thermal paste between the case and the heatsink, and accounted for it in my calculations, but it is ultimately negligible as it adds almost no thermal resistance. Using the thermal equation, we can calculate the junction temperature as the sum of the temperature reported by thermocouple 1, and the product of power and thermal resistance.
The transistor is rated for a maximum junction temperature of 175 °C. At 150 W, it reaches 76 °C. Quite a ways to go! Fortunately, the data is almost exactly linear. Increasing the power dissipated by 25 W increases the junction temperature by 8 °C. Knowing this, we can extrapolate that at 450 W of dissipated power, the junction temperature will be 173 °C. This sets the maximum power of the load to 450 W, but to be conservative, let’s say that the maximum power is 400 W.
Conclusion
After fixing a problem with the hardware, we were able to improve the system performance by improving system response speed to changing voltages across the transistor. Thermal testing has shown that, conservatively, the maximum power limit for the system is 400 W.
Closing Thoughts
The opamp being unstable is an interesting example of the interaction between hardware, software and system engineering. I find it fascinating that the change in behavior of a single component led me to rewrite the load regulator control loop, which in turn hugely improved system performance. Really goes to show how much impact hardware can have on the software architecture and system performance. The moral of the story is that a system can be hobbled by poor hardware design. Conversely, investing a little more in better hardware can improve software and the system by leaps and bounds, and make your life a lot easier. (Another moral is when you encounter a problem, probably best to figure it out immediately rather than ignoring it and forging on. Though if I did that for this project, I wouldn’t have learned the moral above. Can’t win, right?)