Every now and then I was testing some batteries and power supplies. Usually by loading them by a BJT attached on heatsink and controlling the current by potentiometer. I read the current and voltage on two multimeters and estimated the load characteristics. But because I am naturally a lazy person, I decided to build something more automatic. An electronic load. I call it MightyWatt :-)
The basic idea is pretty simple. I connect the device under test to a FET and shunt resistor to measure current. The gate of the FET is driven by an op-amp that maintains either constant voltage across the load or constant current through it. It all attaches to Arduino Uno R3 as a shield. Simple as that. And now for some details:
The main transistor is IXYS L2 series FET that is tailored for linear applications such as this. I use TO-247 package but any through-hole version will do. IXTH75N10L2 has 21 mOhms Rds on and IXTH110N10L2 has 18 mOhms but is also more expensive.
I chose 50x50 mm BGA-style heatsink with 5V fan because it suits the Arduino's outline. It can easily sink 70 Watts. The transistor is mounted on the board upside down so the heatsink can be attached from the top. To get a good thermal contact, the transistor sits on a 1mm silicone pad compressed to about 0.8 mm. There is also Arctic Silver 5 thermal grease, which, at these heat fluxes, is very important.
Measuring the temperature
Underneath the transistor, there is a tiny 0402 thermistor. I cut out a window in the silicone pad for the thermistor and filled it with electrically non-conductive thermal grease. In this way, I get fast response and I don't have to glue anything on the transistor. The measured temperature is, however, lower than the junction temperature so a healthy safety margin is necessary. See the thermal image at the end…
A simple resistor divider between the inputs is used for voltage measurement. Its output is buffered by an op-amp before being measured with Arduino. There is also a selectable 5.7x gain for low-voltage inputs, accomplished by an analog switch. The full-scale is 30 V but the FET can actually handle 100 V.
Current is measured by voltage-drop method across a 4 milliohm power resistor. INA214 current shunt monitor amplifies the signal 100x for a 10 A range. The load would easily handle 20 A and probably could be extended to 30 A if needed.
To set the desired current or voltage, a 12-bit DAC is used. I chose MCP4276 from Microchip. It is cheap and reasonably accurate.
Modes of operation
The load can be operated at constant current (CC) or constant voltage (CV). At CC, the signal from ammeter goes to the inverting input and the DAC signal to the non-inverting input. At CV, the signals are switched so the DAC goes to the inverting input and voltmeter signal goes to the non-inverting input. The signals are switched using an analog DPDT switch. The same style as the voltage gain is controlled.
Because the FET's gate voltage needs to be larger than the 5 V supplied by Arduino, there is a switched capacitor voltage doubler which powers the op-amp.
The load also has some protection against ground loops (PTC) and voltage spikes (TVS). There is a reference voltage of 2.495 V and a single red LED that can be used for whatever is needed but it was thought as an overheat indicator. However, with good software, overheat is very unlikely.
The load as very variable but my version has these specifications:
- 70 W
- 10 A
- 30 V / 5.25 V
- 25 milliOhms minimum resistance
- Constant current and constant voltage modes in hardware
- Constant power and constant resistance in software
So here goes the schematic:
AssembledThis is the (hand) assembled PCB:
- Top: DAC.
- Top right: Voltage reference.
- Bottom right: Fan connector, red LED.
- Bottom middle: Screw-clamp terminal, PTC fuse.
- Bottom left: Current shunt monitor.
- Left: Switched capacitor voltage doubler.
- Top left: Op-amp for gate driving and voltmeter buffering. Two analog switches for voltmeter gain and CC/CV switching.
- Centre: The main FET lying on a 1mm silicone pad with thermistor underneath. Between the FET and the terminal is a 1.5kW transient voltage suppressor.
Nothing much on the bottom except the current measuring resistor and pinheads to connect the load to Arduino. The pinout is for UNO R3, the connection for I2C is different from earlier Arduino versions and it was convenient for me to put the I2C pins to the new location.
And the whole unit with heatsink & fan running:
The sketch I programmed uses serial communication to send status and receive commands. The Arduino's ADC is oversampled to 12 bits for voltage and current. Temperature was left 10-bit. The ADC sampling takes the most time from all the processing.
Voltmeter, ammeter and DAC all need calibration because of some offsets and part tolerances. But a simple linear calibration curve is sufficient.
CC and CV modes are hardware so the control loop is only measuring. But there are also constant power and constant resistance modes, which are software and performed at constant current hardware mode.
There is a watchdog in case commands stop arriving, the load resets itself in few seconds. That means there has to be a constant stream of communication, which brings me to the PC side of the program:
The Windows application was made using C#. It maintains a constant monitoring of voltage, current and temperature and can send commands to set the load. It has also some datalogging capabilities. The only trick was to make it in two threads so that one is constantly communicating with the load and the other is for GUI.
If you were so brave to read up to here, you can have all the source files from my public Google Drive folder.
Some measured data
Two fresh Ikea Alkalisk AA batteries connected in series and measured with increasing current over approximately 30 second:
Single GP ReCyko+ AA accumulator discharged at 1 A. Freshly charged but been in service for 3 years. Still, it had some 80 % of its rated capacity.
The heat of the battle
I run the load at 70 Watts for 30 minutes and tried to find the hottest spot on the case. The ambient temperature was 22 °C and the thermistor reported 92 °C. The case temperature on the sides is quite close to the junction temperature so at 105 °C there is still a healthy safety margin. If the junction temperature was 10 °C higher than the case temperature, it would mean a thermal resistance of 1.33 °C/W. The maximum power dissipation at 25 °C ambient temperature would then be 94 W with the junction temperature at its maximum – 150 °C. But I wouldn't go there for a long amount of time.