Building a Constant Current/Constant Power Electronic Load

A while back I built a simple constant current electronic load using an aluminum HDD cooler case as the heatsink. While it was sufficient for a few amps’ load under low voltages, it could not handle load much higher than a few dozen watts at least not for a prolonged period of time. So this time around, I decided to build a much beefier electronic load so it could be used in more demanding situations.

One of the features a lot of commercial electronic loads has in common is the ability to sink constant power. Constant power would come in handy when measuring battery capacities (Wh) or testing power supplies for instance. To accommodate this, I decided to use an Arduino (ATmega328p) microcontroller.

The schematic below shows this electronic load design. To make the schematic less cluttered, I had deliberately omitted the filtering capacitors and decoupling capacitors. I also omitted the microcontroller circuitry as it is rather standard. All the connections to the standard Arduino board are clearly marked for easy references. The Arduino source code can be downloaded towards the end.


At a first glance, the circuit here seems a lot more complicated than the simple one I built before. But the core power stage portion is actually quite similar.

I used 6 IRFP150N‘s to handle the load. These 6 MOSFETs’ are divided into three groups: each group consists of two MOSFETs paralleled together with independent gate driving resistors. The three pairs are then driven independently via three Op Amps. This design ensures equal distribution of the load current among these three groups of MOSFETs. With this configuration, the maximum power this electronic load can dissipate is at least 200 Watts for a conservative estimate.

In the circuit above, IC1A forms a voltage follower, which buffers the DAC output and the inputs of the three driving Op Amps. An LM324 is used here for the four Op Amps. Of course, the choice of the OpAmps here is not critical and you can substitute with pretty much any general purpose ones. The DAC I used is Mcirochip’s MCP4921. MCP4921 is similar to MCP4821 which I used before. The main difference is that MCP4921 uses an external references whereas MCP4821 has a built-in 2.048V reference. This is also the main reason I chose MCP4921. By varying the external reference voltage, we can strike a balance between the maximum current allowed by the electronic load and the current adjustment resolution.

In my design, the reference voltage to the DAC is provided via a resistor divider from the voltage reference IC TL431. The DAC’s external reference is configured as buffered input for high impedance so that the DAC reference input does not affect the accuracy of the reference voltage set by the resistor divider. When the external reference is set at 0.5V, the load current can be adjusted up to 15A (0.5 V / 0.1 Ohm * 3). MCP4921’s output voltage can be adjusted to upwards to either 1 x Vref or 2 x Vref, so the current range can be doubled via a software command without the need to change the reference voltage. If you do not need such a high current range, you can lower the reference voltage, it will give you a better current resolution (Vref / 4096 per adjustment step).

An encoder is used for current adjustment. By default, the current can be adjusted at a resolution of approximately 1mA/step. By pressing the encoder button, this resolution can be changed to 10mA/step and 100mA/step respectively. This makes it easier to to coarse adjustments.

Constant power mode is achieved by calculating the desired set current via the measured load voltage.

Here are some pictures showing the construction of this electronic load. The heatsink I used is a huge piece of aluminum block I got at a local auction. The original owner builds audio equipment and he used these heatsinks for his class A amplifiers. Anyway, the size of the heatsink is probably an overkill, but it certainly works nicely even without forced air cooling.


The entire control circuit is built on a protoboard. I used the Arduino board I made earlier and used headers to mate it onto the main board.

CircuitBoard1 CircuitBoard2

Here is a picture showing the finished controller board:

As I mentioned earlier, the heat sink I used is ridiculously huge, here is a picture putting everything into perspective:

This picture shows the electronic load operating in constant power mode, absorbing more than 200W of power at more than 60 Volts.


Because we are using a microcontroller here, we can add other features easily. While I did not include in my firmware code, you could easily add in a constant resistance mode for example. Or you could enable the data logging capability by writing out the current and voltage at a present interval.

The following is a short video, demonstrating the functionalities of this electronic load:

View on YouTube in a new window



Be Sociable, Share!


  1. Rob B says:

    First of all a huge thanks for publishing this design. I have already purchased the major power components to build my own. I am also trying to spin up a PCB and have it fabbed up in one of the online board houses. While waiting for all the components to arrive I have had a play with your code on an UNO with the ADC, encoder and reference connected. The problem I have is the rotary encoder seems to be totally ignored. The encoder I have is this one The pins are labeled +v, gnd, SW,CLK and Data At first I thought the switch was faulty or incompatible but it seem to work OK with the basic test sketch provided in the library (Teensy PJRC) I tried removing the encoder from the PCB to use it ‘naked’ also with a Arduino Mega to with no improvement. I would greatly appreciate some help getting this to work.

    • kwong says:

      Hi Rob,

      These encoders typically have 5 pins. I am not sure how the board is routed, but the one side with three pins are the side for the encoder, with right pin being common and first two pins for the gray code output. The other side with the two pins is the switch. Could you trace those pins and see if the connection is correct?

  2. Rob B says:

    Hi again Kerry. It looks like I have found the issue with the rotary encoder. I have spent the last two days wrestling with this issue only to find the problem lies with the newest release of the Arduino software. By recompiling with 1.05 the encoder now works. I tried this approach after reading a comment from the encoder library author that using the polling method is highly dependent on a fast main loop time. I suspect with all the latest ‘improvements’ the compiler is not as well optimised as older releases. To test this theory I might try the code on my DUE or Teensy3.1 Actually if the Teensy was localy available here I would simply embed that as it has a native DAC so it might be possible to eliminate the Vref and external DAC needed for the Uno
    I would be interested to see If you have any luck using the latest Arduino software.
    Thank you again for the time and effort in creating and sharing these projects.

  3. theslowdiyer says:

    Hi Kerry,

    Very interesting article/build, thanks for publishing it. You mention that you have omitted some capacitors from the schematic, is it only the standard supply decoupling caps on the opamp/DAC/78L05 and the LCD that are missing or is there something else? Otherwise is it as simple as hooking up the Arduino and loading the code?

    Seriously considering laying out my own PCB for this design :-)


  4. steven says:

    Hello Kerry,

    What is the maximum input voltage for the electronic load ? Current and voltage are limited by MOS or software (or both) ?
    Thanks your help.

    • kwong says:

      Hi Steven,

      The input voltage is limited mainly by the MOSFET. Since I used ATMega328p’s analog input pin to sense the load voltage, you will want to adjust the voltage divider (and the software constant) if you want the load voltage to be higher as the input can’t go above 5V.

  5. Sujeeva says:


    I programmed an Atmega328p with compiled code (Arduino 1.05 with added Encoder Library works OK).

    I assembled the project in a Solderless Board for the test (I am still waiting for the DAC chip to come).
    MCU (Atmega328p) with All 3 Switches and the Encoder along with the LCD works OK.

    I have a few points to get clarified before going ahead as I am using an Atmega328p stand alone instead of an Arduino Module.

    1:Connecting A5 (Pin 28 of the MCU) to GND Load Voltage comes to 0 but when connecting it to VCC (Pin can’t go above VCC) the voltage goes to 117.3V obviously a voltage divider is needed , A5 (V Load) in the schematic appears to go directly to A5 input,What should be the Voltage divider ratio ?.

    2;LCD (1602 LCD Module) pin 5 (RW) is not connected in the schematic but it had to be connected to GND.

    • kwong says:

      Well.. the divider ratio is up to you as long as the ratio you use is relfected in code. So if your maximum load voltage is 100V you will need a 19:1 ratio divider so the input to the analog pin does not exceed 5V.

      • Sujeeva says:


        Thank you for the support,
        It works and the voltages given appear correct.
        To complete the project I have to wait until the DAC arrives from ebay(Another 2-3 weeks).
        I am using a 16MHZ crystal is it correct ?.

        • Rob B says:

          Yes 16MHz is the standard Uno clock frequency. I am using a 16 MHz Nano for my build.
          I also used an I2C 20×4 LCD. This frees up a bunch of IO’s that can be used for other functions and display ‘soft’ key legends on the LCD.
          In testing I have found an old school AMD CPU cooler and fan is ideal for two mosfets and up to 250W dissipation. So with 3 coolers 600W disipation should be achievable. The current crop of Intel coolers are too small to mount two mosfets and are likely to be less effective at heat dissipation since modern CPU’s are more energy efficient. IRFP640 mosfets might be the optimal mosfet to choose with a quoted 300W max dissipation each althogh I have not tested them.

          • Sujeeva says:

            That means you are using a serial LCD module that can be connected with just 4 wires instead of 10 wires needed for a parallel LCD.16×2 LCD shows 2 display lines.Does 20×4 LCD show any other information ? and if so how did you connect the module ?.
            With regard to the MOSFETs I prefer those with TO-247 or TO-3p case instead of TO-220 as I have experienced frequent failures of TO-220 MOSFETs under high power even when used within the ratings whereas TO-247 and TO-3P are very reliable (May be the surface area).
            In addition I expect to see how IGBTs behave here those may not be suitable due to high saturation voltage and the reading may become inaccurate at lower voltages (AS the current is not sensed through a load resistor).
            I have a large enough heat sink for the project.
            I hope the DAC will arrive soon for me to complete and run a test.

            I am looking forward to see if someone add a Constant Resistance mode as well.

  6. William Gordon says:

    Hi Kerry…
    We are considering using your circuit but beefing it up to be able to handle loads up to 500VDC @3.5A. Our guys seem to think that if we choose higher voltage MOSFETS, caps, etc. and add some isolation to protect the higher voltage that this might work.
    I was wondering if you would have any thoughts, comments, or suggestions about doing this. If we do this successfully, we will spin PCBs, do a sheet metal chassis/enclosure, and make this almost like the old Heath Kits from years ago. And of course we will share the final design(s) for others to utilize.
    Thank you for any help or direction you can provide…

    William H. Gordon

    • kwong says:

      500V @3.5A that’s 1750W maximum power dissipation!

      In principal similar designs with lots of high voltage MOSFETs carefully balanced in parallel should work, but I think you will need a much more robust design. For instance, if a MOSFET fails (e.g. DS shorted) it would short your 500V voltage rail which could cause some serious damage due to all the energy dumped in at once. And without proper isolation, this could be quite dangerous as well.

  7. Sujeeva says:


    I am having a problem with the Reset switch S1 in CC mode, It brings the display to 0 but the load current stays as such and it needs to rotate the encoder at least one step in either direction to stop the load current, I found that connecting a Diode from A0 to D5 (Cathode to Anode) fixes the issue.

    I can’t find any fault in the circuit either.

    The CP mode works perfectly.

  8. Joseph Burgio says:

    Hello, I am sorry To bother you but yes i am making this too! I was wondering instead of the irfp150n if i could use a cheaper IRF540n.

    • kwong says:

      Correct. -40 V comes from the negative side as you can see from the last picture.

      The current and voltage controls do not use pot, they are rotary encoders. The pot is for adjusting the contrast of the LCD.

    • kwong says:

      You sure can. Those were just the MOSFETs I had on hand. As long as the MOSFETs are adequately rated, you should be fine. These linear loads can use pretty much any MOSFETs.

      • Joseph Burgio says:

        I am sorry, I never used a Rotary Encoder, Is the encoder ENCA and ENCB

        • kwong says:

          Correct. Those two are the encoders for controlling voltage and current settings.

          • Joseph Burgio says:

            Thank you for all your time :) That should be all my questions for now! Well i mean until the parts come in! But would you advise against Designing an etching my own board due to the high current? or do you think it would be okay using thick traces?

          • kwong says:

            Thicker and wider traces are definitely beneficial, you can always solder on additional copper wires (or just tin the traces) to increase current capacity if needed.

  9. […] could more easily tweak for myself. A bit of googling turned up a few promising pages, most notably this one on Kerry Wong’s (excellent) […]

  10. theslowdiyer says:

    Got my prototype boards nearly ready, but I need to do the mechanical stuff and tweak the software for use with an I2C-display before I am ready to test.

    Apart from my “tweaks” I’ve followed the schematic as published (including the A5 connection directly to the load-input), so is there anything I need to be aware of before I plug it it to prevent it from blowing up? :D )

    Link to my small writeup of the progress and pics of the board:

    Thanks in advance for any comments,


  11. gunche says:

    What function have C1? Is it reduce AC resonance in the opamp or decoupling feedback signal? Is it connected right, it is in serie with the 500 ohm…
    Why is R6 so small 500ohm why not 10K?

    Hope you understand.

  12. jyp says:

    Dear Kerry,

    Thanks for this; I think it will come in really handy!
    I have a question regarding the R1, R2, R3 resistors. In the schematic, it lists it as 0.1 Ohms. But when I open the picture of the circuit on the heatsink, the actual cement resistor seems to be 1 Ohm.
    Can you comment on this?


  13. Steve says:

    Hi, where can I get the encoder.h file from the ones I’ve tried to download gives me errors
    great project

  14. John says:

    Hi, I’ve a quick question. After building the circuit (great design BTW) I found, that there is a minimum “idle” current of 0.7A. DAC seems to work ok as it goes to 0V, but I can’t get any lower current than 0.7A. Any help on this?


    • kwong says:

      Hi John,

      0.7A seems to be quite high. As some had pointed out, since LM324 is not rail-to-rail, the buffer (IC1A) might be outputting a voltage when the input voltage is zero. To test this out, connect the output from the DAC directly to the output of IC1A (pin 1) and thus by-passing it. If this solves your problem, you can either operate without the buffer or use a rail-to-rail buffer in its place.

  15. John says:

    Thanks for so fast reply. I’m tracing the problem right now – I found that I’m getting 0.0012V directly from DAC (0mA settings) at pin 3 of LM324 and it rises up to 0.020V on pin 1 of LM324. This is the reason of such high idle current. Tomorrow I’ll try to remove the IC1A and connect output of DAC directly to the other three op amps. Hopefully it will solve the problem. If not, I may replace the IC with other LM324. I’ll let you know either way. Thanks again!

  16. John says:

    Hi Kerry. The above steps solved the problem, however the minimum idle current is not 50mA in my case, but 120mA. I’m not into arduino – C is my primary programming language and I’m gonna to stick to it, but I found a small error in your program. In order to be able to reset current in CI mode (CP works ok), you need to add after the lines:

    //reset output current to 0
    encoderValue = 0;
    DACSetValue = 0;

    also setDACOutput(encoderValue);

    otherwise your dispaly shows 0mA, but the current is still the same. Someone mentioned that before, but he used diode to simulate encoder movement that invokes changing DAC settings. Check yourself.

  17. brandon says:

    hello , the vr1 is that just a zener diode across a pot ? if so what value ? or is it something else im missing

  18. Jindra says:

    Hello, big thanks for your desing. I inspired and build constant power discharging device with mail reporting via Blynk.

  19. Stephen says:

    I dont see how your measuring the current or voltage of your load, was that portion left out?

  20. Fred Cathers says:

    Hello Ken,

    Very nice circuit. Simple and to the point. I have made some observations and would like your thoughts on them.
    1) Maximum power of the IRFP150 is about 200 Watts so 6 should allow for over 1000 watt load. (8.1 amps each at 24 VDC)
    2) Changing the value of the series resistor to 0.02 and one resistor per device allows for a 165 millivolt drop instead of almost 3 volts also a 2 watt resistor
    3) Changing the resistor requires adding gain in the feedback stage (about 10) This can be done with LM324 4.5K feedback and 500 to ground on the neg input. Also a 0.22 cap in parallel with the
    4.5k to keep oscillations out. (Open loop gain is wild)

    4) by measuring the supply voltage to the drain of the IRFP150, total power may be calculated to keep from destroying the MOSFETs.
    5) Yes, you now need that big honking heatsink. May consider adding a fan after the heat calculations.
    6) with circuit modifications 1.65 volts on the control give 8.1 amps of sinking power.
    7) Give me an Email and I will send you the LTspice simulations.

    Best Reguards,

  21. Fred Cathers says:

    Hello Ken,

    Another thought is to used a tool call PCB artist from from Advanced Circuits.
    They have a experimenters deal of 4 PCBs for 33$/each 2 sided 1 oz copper (size restriction but not bad)
    Plus the development tools are FREE! schematic & layout.
    Quality is great and comes with a reasonable library.

    Best Regards,

  22. Byung-Yong Kang says:

    It will be desirable that the function of low voltage cut-off is included in this electronic load.
    The function is necessary in testing battery pack.

  23. Chris says:

    Hi Kerry!

    Build a DC Load myself and has been produced using EasyEDA processing.
    I have noticed one thing wrong with my design. As I approach 20V (or above) @ 5A, my power supply (DUT) current drops down to 4.99 and lowest 4.98. Once you go below 20V @ 5A it returns to normal and is stable.
    Any ideas on this?
    I would have to guess that where Im using a ground plane for all grounds, im experiencing a voltage drop. Could this be the cause?

    I am using a precision 10V source (MAXIM RFEF01C), LM358N, 2x IXYS ixfh36n60p (YES overkill ) and a 0.5 ohm 50W resistor.

  24. MEDRAD says:

    Hellou Ken,

    You’ve made a very helpful DC load circuit and thank you for bringing this design to everyone.
    Meanwhile, i’m building my own DC load circuit and i started by finding out some components like IRFP140N (4 of them, i would only use 2 stages instead of 3), TL431, DAC, UNO, …
    I’ planning to buid a 3s battery discharger test bench with a discharge current up to 50-60A but i’m stuck with 0.1ohm resistors. Would you please help me out, how can i calculate the values of these resistors in respect to the rated power (let’s say i will have 10 watts for each resistor).
    Today, i started some calculation but i found that each stage of your design can handle up to 10A (30A in total with 3 stages) is that right ?

    Another thing, is there any simple current measure circuit that can handle up to 60A ?

    Thank you in advance.

  25. sangseu says:

    First thank you for posting your work.
    I’m working with electric load project. I set current mode at 0.5 A, then increase voltage from 0V to about 55V, circuit sink current as calculated. But, when voltage increase about 60V, current sink increase too. Did I missing some things ? I using FET IRFP250N, Fluke 17B+ to tracking current. Here is my schematic:

    • kwong says:

      Circuit looks ok to me. Did you use a resistive load? The circuit might be oscillating. You can check that by measuring the waveform from each current sensing resistor.

      • sangseu says:

        Thank for your reply. Sorry, what does “resistive load” mean ? I think my circuit act doesn’t look like oscillating. When voltage continue increase up to 60,…70V circuit continue sink current up to 1, … 4A and burn 5A protect fuse.

        • kwong says:

          I meant a load resistor. Another possibility is the tempco of your current sensing resistor and when you pass a high current through them they heat up and their resistance change (which translates to change in current as the voltage across the sense resistor is pegged to the voltage reference via the opamp).

          • sangseu says:

            Oh, that maybe my missing. I’m using 0.1 Ohm-5%-5W-Ceramic resistor to sensing current. I’m going to replace it by a ohmic shunt resistor or once like your and report as soon as possible. Thank you, kwong.

          • sangseu says:

            I’ve using 10mR ohmic shunt but doesn’t solve issues.

          • kwong says:

            Very strange indeed, as the overall current is guaranteed by the feedback loop.

          • sangseu says:

            Circuit work nice when V_DS < 60V. I've try 8xLM358 with 8xIRFP250N but circuit still over sink current. I'm using +12V and -5V as power supply for OP-AMP because I need invert negative voltage to measuring. Does it is problem ?

  26. Phil says:

    Hi Kerry!
    Thanks for sharing your work!
    Why do you think that I’m getting 117 volts on the LCD ? I’m loading the circuit with a 4 V @ 1A.

  27. DEicher says:


    Thanks for sharing this design. I’m new to Arduino, I’m wondering how you connect this circuit to the Arduino. What connector do I need to mate with the appropriate connector on the processor card?

    thanks for any help you can offer.


  28. Roberto says:

    Hello Kerry
    about electronic load can you send me your code?

    Many thanks

  29. Deeej says:

    Hi Kerry,
    Many thanks for your design. I have just built it and the analogue side works fine but I am having trouble with the display – unreadable, all segments “lit”. Have tried 3 different displays and another Uno, all to no avail.(have connected R/W to GND. Any thoughts on what I may have done wrong?

  30. Deeej says:

    Yes I have tried that, thank you. Have checked out the Unos and the displays in other ccts and they worked fine. Wiring checked, checked and double checked, even downloaded the sketch more than once and unzipped with different programs (getting desperate). Maybe I should stick to things I know about and forget about this micro controller stuff. Many thanks anyway.

Leave a Reply