Part 2: Hobby Power

Adjustable Linear Power Supply

Johann Wyss

Issue 28, November 2019

This article includes additional downloadable resources.
Please log in to access.

Log in

Build a 3.3V to 12V hobby power supply with current limiting and voltage display.


A reliable power supply is a must for any electronics enthusiast’s workbench, and ideally, it should provide common voltage outputs with an adequate current to suit most prototyping needs. Also important for prototyping, is current limiting, which can avoid damaging the circuit if you accidentally build or wire it incorrectly. By limiting the current, there is less chance for components or PCB tracks to overheat and burn out.

This month, we present our feature-rich hobby power supply, complete with backlit LCD to show the voltage and current, current limiting functionality, and thermally controlled fan to cool the power supply only when it needs it to avoid excessive noise.

The supply can comfortably provide 3.3V to 12VDC at currents up to 1.2A, and is built into an enclosure that will look great on your workbench.

Not only do we show you how to build a prototype and main build, but we also show you the theory behind the design. This knowledge can help you design your own power supplies in the future, or to modify our design to suit your own needs.


In last month’s issue, we began the design process for a linear adjustable benchtop power supply, capable of delivering 1.5A at varying voltages ranging from 3.3V to 12V. We designed and built a prototype, which we used to confirm the functionally and performance of the device. This month, we design the voltage and current measuring and displaying circuit, a constant current circuit to control an indicator LED, and maintain the required load on the circuit to maintain regulation.

Current and Voltage measurement

One of the first tasks was to design and implement a method of measuring and displaying the voltage and current output of the power supply. Our initial attempts to measure the current used a 0.1Ω resistor as a shunt in series with the output on the low side. We could then measure the voltage drop across that shunt and use Ohms law to calculate the current.

i.e. if we had 1 Amp of current flowing through the circuit, we would measure across the shunt a voltage of: V = IR = 1 × 0.1 = 100mV

The 10-bit ADC in the microcontroller used in the Arduino development board can measure 1024 different voltage levels. This means at 5V the minimum resolution the ADC can reliably measure is: 5V / 1024 = 4.88mV

If let’s say we only had 100mA of current flowing through the circuit, we would get a voltage drop of 10mV this drop is way too small to get any reliable measurement. Therefore, we opted to build an amplifier circuit to amplify this voltage by 30. This would mean we could take a reading with the ADC divide the result to remove the gain and then perform the Ohms law calculations to calculate precisely what the current was.

However, it was not quite as simple as that. In a previous project, we learned that we needed to use an instrumentation amplifier to reliably amplify such small voltages. After having a look at the local suppliers, we learned that we could get two different types of instrumentation amplifiers the INA126 and the AD623.

However, neither of these are ideal for a current sense and amplification role and neither were able to produce the accuracy we were expecting. As such we opted once again to use the convenience of a module specifically the INA219 current sensing breakout board from Adafruit. This module and accompanying Arduino library make reading small currents exceptionally simple and impressively accurate.

With this module, we had our current and voltage sensing job complete and now needed a way to display the results.


QP5521 1602 LCD from Jaycar.

For the display, we opted to use the very inexpensive and easily obtainable 1602 LCD this is a display we have used many times in the past owing to its simplicity of use. We can simply get the readings from the INA219 and display them straight to the LCD just using the Arduino print commands and the Liquid Crystal library.

Constant current circuit

In the previous issue, we considered just using a single resistor and LED to create a power status LED and provided a small load on the circuit that the LM317 needs in order to maintain voltage regulation. However, this would cause the LED to change its brightness depending on the set voltage output. We would need to pick the resistance value based on the highest potential the power supply could deliver which would be 15V give or take with no load applied. That means to maintain the 20mA forward current and 1.8V forward voltage of the LED we would need a resistance value of:

R = (Vin - Vout) / If = (15 - 1.8) / 0.02 = 660Ω

However, if we were to drop the output voltage to 5V the LED would no longer get the 20mA forward current but rather it would only get around:

(5 - 1.8) / 660 = 4.8mA

This would cause the LED brightness to fluctuate dependent on the output. This isn’t ideal and isn’t exactly an elegant solution. However it is very simple to rectify by creating a constant current driver circuit.

We want to maintain a constant current as close to 20mA as possible. In this circuit, the two transistors regulate the current. This circuit is an adaption of the textbook Widlar current circuit. In this circuit, we are using two 2N2222 NPN bipolar Junction Transistors. The base of transistor T1 is pulled high via R13, allowing current to flow into the base of T1, which allows current to flow from Vcc through the LED into the transistor T1 and through R12. As the current increases the voltage drop across R12 increases which is connected to the base of T2. This results in the base of T1 receiving less current, reducing the amount of current flowing from its collector to emitter (conventional current flow) and thus the current through the LED. This of course results in the voltage drop across R12 being reduced stopping current flowing through T2 which once again allows current to flow through T1. This process is repeated very rapidly and as such provides a fairly constant load on the circuit.

To calculate the ideal value of R12 we use the equation:

R12 = T1VBE / If = 0.7 / 0.02 = 35Ω

R13 was picked to reduce the overall current loss to the circuit and thus wasted power, at 2.2KΩ the current can be anywhere from 6.8mA to 570μA. According to the datasheet the 2N2222 has a small signal current gain β i.e. Hfe anywhere between 50 and 300. This means at the lowest current of 570μA to the base of T1 the 2N2222A can still produce sufficient amplification to reach the 20mA desired current.

Of course, the circuit isn’t perfect. When the output from the power supply is down to its lowest value of 1.25V there is insufficient voltage to meet the forward voltage of the LED 1.8V and the voltage drop VBE of the transistor T1 .7V. This means that the LED will still dim at the very low voltages less than 2.5 – 3V.

We simulated the circuit using National Instruments (NI) Multisim. In the simulation, we simulated the changing output voltage from the minimum of 1.25V to the maximum of 15V. We then recorded the current through the LED and into the collector of T1 as shown in green. The current through R12 shown in blue and the current wasted through T2 was red.

Note: This is a constant 16mA draw on the system, but it also has a wasted component that varies from 570μA to around 7mA. This is a draw on the system that will not be recorded on the display circuitry but will remain a load on the LM317 circuit. This could be easily reduced by increasing the value of R13, if required.

As we can see from the simulation results the current through the LED is very small when the voltage is at the minimum 1.25V however it rapidly jumps to around 16mA around 2.5 – 3V.

This behavior isn’t easy to overcome due to the forward voltage of the LED itself there are few options without limiting the power supply output to over this voltage, as such we conclude this circuit is suitable for the task.

Temperature Sensor Circuit

The next circuit we needed to implement was a temperature sensing circuit. Our initial thoughts were to have a completely analog circuit that would output a voltage that could control a fan directly, however, since we need a microcontroller to control the LCD screen, we may as well have the temperature measurement handled via the microcontroller reducing the component count. We opted to use the LM335 temperature sensor for this build. It has a linear output and is very inexpensive and easily obtainable.

In this configuration, the LM335 and R17 create a voltage divider with the LM335 changing its resistance linearly in relation to the temperature with a rate of 10mV per degree Kelvin. This means at room temperature or 25°C the output from the LM335 will be:

25°C + 273.15 = 298.15K or 2.98V

According to the LM335 datasheet, we need to maintain a current of around 1mA through the device to allow for accuracy and minimise self-heating. To calculate the value resistor needed for R17 we can just use ohms law. We know the input voltage is 5V and that at room temperature we will drop about 3V across the LM335 so we know we need to drop 2V across R1. Since we know we want 1mA the calculation is:

R = (Vcc - Vsensor) / Iout = (5 - 2.98) / 0.001 = 2020Ω

Since that’s not a standard value we can just round it to 2.2kΩ.

Note: This circuit can be adjusted via a 10K potentiometer to calibrate it perfectly. It isn’t something we need for this project as near enough is perfectly fine for this task. However, we opted to include the footprint for the potentiometer on the PCB design just in case you wanted to experiment with the sensor. To precisely set the output you need to solder in the optional R19 10K potentiometer to the PCB. You also need to have a precision thermometer on hand to use to calibrate this one.

Note: Use the precision thermometer to get the current temperature in Celsius and then convert that to Kelvin by adding 273.15 to the recorded temperature and divide the result by 10. That will give you the required precision output voltage.

You then use a multimeter to measure the voltage output and adjust the potentiometer until it matches that value, when you’re done you can just add a drop of hot glue to the potentiometer to prevent it becoming out of spec.

Fixed Regulators

In order to run the microcontroller sensors and the fan, we needed a way to create stable voltages for the circuit. The sensors and microcontroller need 5V which means we needed a 5V regulator while the fan required a 12V input. We decided the most cost-efficient solution was to use a couple of fixed voltage linear regulators.

Whilst it’s quite possible to have used a smaller package it seems they are significantly more difficult to acquire locally and would be running close to their maximum current output of 100mA.

As with all linear regulators, we have added the mandatory bypass cap on the input and a larger cap on the output, these are for stability and prevent oscillations in the circuit.

Due to the large size and low currents, we don’t need to add any heatsinking to these regulators, and they have been left upright on the board to reduce their footprint on the crowded PCB, and increase airflow around the regulator.

Fan Control Circuit

Since we were using the microcontroller in the project, it made sense to use it to control the fan. This also allowed us to avoid running the fan continuously and unnecessarily when operating at low currents. We opted to use a PWM signal to control the fan's speed - only running the fan when the temperature sensor detected temperatures over a specified value. This would allow the supply to run silent at lower currents, and avoid unnecessary current drain. We are using an IRF540N logic level MOSFET to drive the fan from a 12V regulated supply. This MOSFET is overkill for the circuit but it is a junk box part which means it’s fairly inexpensive and most of us hobbyists will have this in our part bins or a selection of drop-in replacements as the pinout is the common configuration allowing the reader to substitute with many different available alternatives, just make sure the pinout matches, that the MOSFET is a logic level FET and that it can handle a maximum of 250mA current through its drain (ID). In the circuit, R18 is designed to keep the gate of the MOSFET pulled low until a high pulse is sent from the microcontroller preventing a floating undefined state. D7 is a flyback diode which will give the energy stored in the inductive load i.e. the fan motor a path to travel back through the fan when the gate is pulled low and the path to ground is removed.


In the previous issue, we ran some basic tests on the 12-position switch by running high currents through it for a few hours. To extend these tests we left 1.5A running through the switch 24 hours a day checking on it daily. After 7 days we confirmed that the switch had failed and destroyed one of the contacts. This confirmed our suspicion that the switch was not sufficient for the task. The switch simply can’t handle the current requirements for extended periods despite the low power dissipation across the contacts, this prompted us to search for a replacement.

High Current Rotary Switchform Element14.

We found a suitable replacement at Farnell / Element14 with the HS16-1N-AT432 11 position 1 pole 12A switch. This is a beast of a switch in both its size and its current handling abilities. Of course, this switch isn’t the only available option, there are many suitable switches on the market, or you could use a fly lead design that replaces the switch with banana plugs allowing you to select the desired current by manually making the connections with jumper leads. Whilst this is easy to do it does not look so great and takes up a bit of room. Therefore, we opted to use the larger and more expensive switch for this project.

Circuit Improvements

Along with the new circuitry we also made several improvements to the circuit to aid in the performance and extend the longevity of the supply. We have altered the value of R1 from 270Ω for 470Ω, this change will allow the circuit to take advantage of the full range of deflection on the potentiometer while still maintaining the minimum load requirements.

With this new value we can get a maximum voltage output of:

Vout = Vref × (1 + R2/R1) = 1.25 × (1 + 5000 / 470) = 14.5V


Vout is the maximum output

Vref is the 1.25V voltage reference of the LM317

R2 is the potentiometer

R1 is the fixed value resistor.

Note that with this combination of resistances the voltage regulating LM317 would not be able to maintain unloaded voltage regulation. This is because the LM317 needs between a 3.5mA and 10mA current draw for the regulator to function. The maximum current this circuit can draw with the potentiometer at zero volts can be calculated using Ohms law.

I = Vref / (R1 + R2) = 1.25 / 470 = 2.7mA

With the new constant current / LED indicator circuit we are able for the most part to ignore this load as there is a fairly constant 16mA draw across all voltage ranges from 2.5V plus the current through the second transistor which ranges from a few microamps to around 7mA dependent on the output voltage. However, it’s very possible that at voltages less than 2.5V that the LM317 will lose regulation as the maximum potential current draw is 2.7mA + the 1.5mA draw from the constant current circuit as shown in the DC transfer characteristic graph. This could potentially result in the lowest possible voltage output being 2.5V which is still within our design specifications and thus perfectly acceptable.

An early prototype, which didn't include the 7812 regulator for the fan.

The Fundamental Build:

Breadboard Prototype

Building the device on the breadboard is not ideal however it was for us the best way to prototype the additional circuitry as we could use last month’s prototype for the power delivery side. For the prototype, we opted to use the Arduino Nano microcontroller development board. This allowed us to easily program the device via USB while writing the code for the project.

Parts Required:JaycarAltronicsCore Electronics
1 × Arduino Nano (Or Equivalent)XC4414Z6372A000005
1 × 1602 LCDQP5521Z7000AADA1447
1 × INA219 Breakout module--ADA904
1 × 1N4001 Diode (Or Equivalent) *ZR1004Z0109ADA755
1 × 5mm Red LEDZD0150Z0800FIT0242
1 × LM7805 Voltage RegulatorZV1505Z0505ADA2164
1 × LM7812 Voltage RegulatorZV1512Z0510014-9756124
2 × LM317T Voltage RegulatorsZV1615Z0545002-863-LM317TG
2 × 2N2222A NPN TransistorsZT2298Z1035 ##ADA756
1 × MJ2955 TransistorZT2235--
1 × IRF540N MOSFETZT2466Z1537COM-10213
1 × LM335 Temperature SensorZL3336Z2530-
1 × 47Ω 0.25W Resistor *RR0540R7030COM-10969
1 × 330Ω 0.25W Resistor *RR0560R7040PRT-14490
1 × 470Ω 0.25W Resistor *RR0564R7042COM-10969
1 × 1KΩ 0.25W Resistor *RR0572R7046PRT-14492
1 × 2.2KΩ 0.25W Resistor *RR0579R7565COM-10969
1 × 10KΩ 0.25W Resistor *RR0596R7058PRT-14491
1 × 8.2Ω 0.6W Resistor *-R7708-
1 × 12Ω 0.6W Resistor * -R7512-
1 × 24Ω 0.6W Resistor *-R7519-
1 × 120Ω 0.6W Resistor *-R7536-
1 × 1.5Ω 1W Resistor * -R7203-
1 × 2.7Ω 1W Resistor *-R7206-
1 × 4.7Ω 1W Resistor *-R7209-
1 × 0.82Ω 5W Resistor * -R0310-
1 × 1Ω 5W Resistor *-R0311-
1 × 1.2Ω 5W Resistor *-R0312-
1 × 10Ω 5W Resistor *RR3250R0323-
1 × 5K Linear 16mm PotentiometerRP7508R2203-
1 × 10KΩ 0.5W 25-Turn TrimpotRT4650R2382A003-CERM10K
9 × 0.1µF Ceramic Capacitor (Or Equivalent)RC5496R2865COM-08375
3 × 47µF 25V Electrolytic CapacitorsRE6110R4805CE05271
1 × 220µF 25V Electrolytic CapacitorRE6160R5144CE05149
1 × 55mm Long Fan Type Heatsink HH8570H0520-
1 × TO-220 Heatsink Insulator Kit *HP1176H7310-
1 × 40 Pin Male Pin Header Strip (Or Equivalent)HM3212P5430FIT0084
1 × 40 Pin Female Pin Header Strip (Or Equivalent)HM3230P5390PRT-00115
2 × 2 Way PCB Mount Screw TerminalsHM3172P2032BPRT-08432
1 × Plastic Instrument Enclosure-H0480F-
1 × 11 Position 1 Pole High Current Rotary Switch-Element 14: 2501119 / RS Components: 125-1886-

Parts Required:

* Quantity shown, may be sold in packs. Prototyping hardware and accessories are also required.

## This distributor does not sell the identical part, however, this part should suffice as a substitute. Please take the time to double check compatibility before purchasing.


The code is very simple owing to the awesome libraries from Adafruit available for the LCD and the INA219 modules. To get the program running you will need to download and install both libraries.

The 1602LCD uses the liquid crystal library that can be found here although it seems this library comes pre-packaged on newer versions of the Arduino IDE. If yours does not have it or you want to learn more check it out here:

The INA219 breakout module library can be downloaded in the Arduino IDE library manager or directly from the Adafruit Github repository:

Note: The code also uses the wire library to allow I2C communications however, this is a built-in library with all but the very oldest versions of the Arduino IDE. If you’re having issues with this particular library, we thoroughly recommend you update your IDE. Failing that you can find more info on the wire library here:

There are a few variables that you can change in the code to make it completely custom and designed for your specific needs and requirements. For example, the line:

float refV = 5.02; 
// measured voltage at 5V pin of micro 

Allows you to set the actual measured voltage of your 5V line, this should increase the accuracy of the temperature readings especially if your USB voltage is as low as ours was producing only about 4.6V on the 5V line from the Arduino Nano.

int minTemp = 20;
int maxTemp = 60;
int samples = 5; 

These variables allow you to set the temperature levels in which the fan starts and when it is at full speed. By default, we have set it so that the fan will start spinning very slowly at 20 degrees and at 60 degrees it will be at 100% speed. You can change these values to suit your circumstances.

The samples variable sets the number of times we read the temperature and is used to create an average reading which helps to keep the fan stable and free from jitter caused by spurious readings. You can change this value to alter the number of samples taken for averaging.

// Sensor Reading
voltage = ina219.getBusVoltage_V();
current = ina219.getCurrent_mA();
current = (current / 1000);
temp = 0;
for (int i = 0; i < samples; i++) { 
temp = (temp / samples); 

In this code, we are simply calling the Adafruit library function “getBusVoltage_V” which will return the value and store it into our float variable called voltage. We then do the same with the current function storing it into the float current.

We then convert the mA reading into Amps by dividing the reading by 1000.

We then set the temperature variable to zero and use a for loop to repeat the number of times stored in the sample’s variable.


This line may seem pretty complex at first but it’s actually pretty simple. On each loop of this for loop, we are adding the previous reading to the next to sum them in our case 5 times.

We take a reading of the LM335 sensor attached to analog pin 1 and we convert it to a voltage reading. Since the LM335 sensor produces an output of 10mV per degree Kelvin we just need to convert that reading into Celsius by subtracting 273.15 from the result providing us a temperature in degrees Celsius.

// LCD display
if (count > 100) {
  lcd.print("Volts: "); 
  lcd.setCursor(0, 1);
  lcd.print("Amps: "); 
  lcd.print(current, 3); 
  count = 0;

In this section of the code, we are simply using the Liquid crystal library functions to first clear the display, this will ensure that there are no residual digits displayed. We then use the print function to display the word “volts” and the value stored in the variable voltage followed by the letter V to signify the unit.

We then use the function lcd.setCursor(0, 1); This translates to:

lcd.setCursor(col, row) 

With the 1602 LCD, it means we can have 16 characters on up to 2 rows.

We need to use the setCursor function to move the cursor to a new position in the bottom row. Therefore, we need to give the function a 0 to signify we want the cursor to be placed on the first character position and a 1 to signify we want it on the bottom row. Again, this is made easy thanks to the library, addressing the LCD without this library isn’t overly difficult but it certainly takes much more effort.

The command:

lcd.print(current, 3); 

It is identical to the voltage reading however we have limited the output to only 3 digits. This was done to provide an easy to read current display capable of showing 3 significant figures.

Note: You may notice that we have the display code inserted into an if loop. We did this because the program runs very quickly and would produce a blur of numbers on the least significant digit of the current reading, having the display only refresh once every 100 loops of the program allowed the program to slow down a little and provided a little stability to the readings.

// Fan Control
fan = map(temp, minTemp, maxTemp, 30, 255);
if (temp < minTemp) {
  fan = 0;
if (temp > maxTemp) {
  fan = 255;
analogWrite(6, fan);

In the fan control section of the code, we take the temperature value we collected earlier, and using the Arduino map function, we assign the fan a PWM value between 30 and 255. We set the minTemp variable to 30 and the maxTemp variable to 255.

This value will define the pulse width modulation PWM value we write to the digital pin which controls the gate of the MOSFET with the fan attached. We have the minimum value as 30 because at any lower duty cycle the fan does not rotate but rather creates a coil whine which is much more annoying than the sound of a fan… As such the final part of this section is to set any value lower than our pre-defined min temp will result in 0% duty cycle while any result greater than out max temp will result in a 100% duty cycle.

Of course, the entire code is available for download on our website.


To test the power supply, we used our Powertech MP3084 Laboratory Power Supply to provide 19V and a maximum of 3A to the circuit. Any DC power supply capable of delivering between 19V and 25V with a current capability of 2A should work perfectly fine with this project.

For suitably qualified users, a toroidal transformer capable of providing 18VRMS AC at 2A+ would also be acceptable, however, this is beyond the scope of this project.

The circuit has been specifically designed to work with old laptop chargers, which are generally a switchmode supply that usually outputs 19V at around 3A. You could repurpose an old one or buy a universal type at most electronics retailers.

With that said, this project can operate at voltages lower than 19V, however, the circuit will be unable to provide 12V with a load exceeding 1A. The output will always be around 6V lower than the input due to the voltage drop across the LM317 regulators, so keep this in mind when choosing how you will power the device.

The Main Build:

Adjustable Linear Power Supply

ADDITIONAL Parts Required:JaycarAltronicsCore Electronics
1 × ATmega328P MicrocontrollerZZ8727Z5126CE05190
1 × 16MHz CrystalIncluded with ZZ8727V1289AIncluded with CE05190
2 × 22pF Ceramic Capacitors *RC5316R2814Included with CE05190
1 × 47μF 25V Electrolytic CapacitorRE6110R4805CE05271
3 × 1N4001 Diode (Or Equivalent) *ZR1004Z0109ADA755
1 × SPST Mini Rocker SwitchSK0984S3210POLOLU-1406
1 × 2.1mm Bulkhead DC SocketPS0522P0622PRT-10785
1 × Red Banana Plug SocketPS0406P9261CE05165
1 × Black Banana Plug SocketPS0408P9262CE05221
1 × 4-pack Rubber Non-slip FeetHP0815H0940COM-10594
2 × Plastic KnobsHK7764H6061 ##COM-09998
4 × 20mm M3 Screws *HP0410H3130A ##FIT0281 ##
4 × 15mm M3 Screws *HP0406H3150A ##-
8 × M3 Nuts *HP0425H3175POLOLU-1069
4 × 6mm M3 Screws *HP0400H3110AFIT0060
4 × 6mm Standoffs *HP0920 ##H1342 ##POLOLU-2088 ##

ADDITIONAL Parts Required:

OPTIONAL: (for AC INPUT)JaycarAltronicsCore Electronics
4 × SM5822B 40V 3A SMD Schottky Diodes *ZR1025--
1 × 2200µF 25V Electrolytic Capacitor RE6330R5205-


* Quantity shown, may be sold in packs. Prototyping hardware and accessories are also required.

## This distributor does not sell the identical part, however, this part should suffice as a substitute. Please take the time to double check compatibility before purchasing.


After testing the circuit on the breadboard, we began to design the PCB for the project. We used the free version of EagleCAD from Autodesk to design the PCB with the maximum allowable area of 100mm × 100mm. All of the high current traces in the circuit were given a minimum trace width of 50mil which equates to 1.27mm. Using the Digikey PCB Trace Width Calculator we can expect to see that at the maximum current of 1.5A the PCB will increase in temperature by 1.1°C as the trace will have a resistance of 74mΩ causing 167mW of power to be dissipated across it.

This is using the distance from the input to the output of 300mm as the basis for this calculation and as such is just a ballpark figure. Where space allows, we have used 100mil traces or utilised both sides of the PCB to reduce this resistance as much as practical.

You can find the Digikey calculator here:

Note: The PCB industry uses the imperial standard as a rule. When we are talking about mil in relation to PCBs, we are referring to 1mil being 1 thousandth of an inch which equates to 0.0254mm sometimes you will also see 1mil written as 1 thou.

The signal wires to and from the Microcontroller and sensors utilize a 20mil trace width or 0.5mm these traces don’t require any significant current, so voltage drop, and power dissipation are not of concern. However, the traces supplying the power to these devices have a 40mil trace width which is more than enough.

We flood filled both sides of the PCB with a ground plane which reduces the number of required traces dramatically however, it also makes it a little more difficult to solder as the larger surface area works as a heatsink pulling heat away from the solder joint. Whilst we utilised thermal reliefs of the ground connections it seems they are underperforming and could be improved by increasing them. However, to overcome this we can simply increase the soldering iron temperature and solder all grounds first. Then revert to normal soldering temperatures.

Being a double-sided board, we have used a large number of vias to connect the ground planes in areas likely to require high return currents this is especially obvious in the lower right side of the board (Top) where the 100mil output trace essentially cuts the output ground connection off from the rest of the PCB. These vias will allow the current multiple paths to ground.

There was one section where we had no option but to change the layer of a high current trace, for this we used multiple vias. However, vias are usually quite high resistance, therefore, we left the solder mask off of vias so that we can fill the vias with solder to increase the current handling capabilities.

Note: We recommend that you add solder to the 3 via locations shown. This will help to reduce the resistance of the vias and thus reduce the voltage drop and power loss across them.

The PCB was designed to have the 3 main heat dissipating components all on the same side which will allow us to have them all share the same heatsink edge. This will allow us to keep the thermal shutdown safety features built into the LM317 as if the fan fails or the transistor overheats it will result in the regulators reaching the same temperature and thermally shutting down preventing damage to the unit.

The MJ2955 pass transistor is to be mounted into the heatsink as such we have added 3 surface mount pads labeled E,B,C for Emitter, Base and Collector of this transistor. We used short lengths of 18 AWG 1mm diameter 24 strand wire soldered directly to these pads to make the connection to the pass transistor. This wire has a max current handling capacity of 4.9A so well within the requirements.


When soldering the PCB components down follow the usual rule of starting from smallest components such as resistors and IC's working up to the larger capacitors and regulators. The only nonstandard method we used here was to leave the leads of the 2 LM317 regulators and the LM335 as long as possible. In the case of the LM317s, this will allow us to get the component as high and centre on the heatsink as possible and will also give a slight thermal dissipation advantage. We soldered the LM335 slightly on an angle this way when the heatsink is attached it will have a constant pressure against the surface and will help in the thermal transfer.

Note: The LM335 has its flat side facing away from the PCB so that it can make as much contact with the heatsink as possible.


Due to limited space on the PCB, we were unable to include the component values. Please use the table to identify the correct components.


We have done our best with this project to make it as simple to build as possible without needing any special tools or equipment. As such the enclosure for this project is an off the shelf enclosure. This way you are free to create the front and rear panels however you want. You can use a 3D printer, milling machine Dremel or whatever tools you have at your disposal we will simply provide the fusion 360 cad files which you can print out and use as a template to manually cut out the panel or export as a .stl for 3D printing or an .svg for carving on a CNC mill.

Note: We have provided front.svg and rear.svg files that can be printed out and used as a physical template. This allows you to use hand tools such as a drill, Dremel, nibbler or similar to manually create the front panel. Just print them out and glue or tape the paper to the panel. These files can also be directly used in CAM software combined with a CNC router or mill to cut the physical shapes into the existing panels.


For us, the quickest, easiest and best-looking option was to 3D print the panels as we have the tools and equipment at our disposal. To get the two colour print we simply printed the first 1.6mm of the .stl in a white Flashforge PLA, once this had printed we simply printed the remaining on top by printing the model from from 1.6mm on using Flashforge black PLA. This was done using layer modifications in Simplify 3D.

Although this can easily be done using other slicers such as Cura. Failing that you could even just manually pause the print once it reaches the text layer and swap filament then.


When building the device, we printed out a copy of the PCB layout and used that as a template to find the best position in the enclosure. Using a centre punch we marked the locations of the four mounting holes on the PCB and drilled these into the enclosure. We then used some 6mm female – female brass standoffs to mount the PCB to the enclosure.

With the PCB mounted we butted the Heatsink up against the LM317 regulators and marked the mounting hole locations using a scribe you can do the same with a felt-tipped marker.

After marking the mounting locations, we drilled the heatsink to 3.5mm to accommodate for the 3mm mounting screws. To mount the MJ2955 to the heatsink, we used the PCB template from the power supply prototype published in last month’s issue, which had the footprint included. We printed this out and used it as a template to mark the centre of the heatsink to fit the two mounting holes and the two pins. We applied some heatsink compound to the bottom side of the transistor and mounted it firmly to the heatsink.

We then attached short lengths of 1mm 18AWG AWG to the emitter and base pads of the PCB to the base and emitter of the MJ2955.

Note: you need to check the pinout for the transistor you have purchased as it’s possible that the combinations may not be identical between manufactures. This is the pinout for the brand sold by Jaycar.


Be sure to use heatshrink on the base and emitter pins of the transistor to prevent them from shorting against the heatsink. To connect the collector of the transistor to the PCB, we used a ring terminal and a slightly longer piece of wire.

We then aligned the LM317’s with their respective holes and carefully placed an insulating sheet of silicone between the current limiting LM317 and the heatsink. You also need an insulating washer to make sure the screw is not making contact with the metal tab of the LM317. This will protect the circuit from shorting between the two LM317 outputs and the collector of the transistor.

The transistor collector and the output tab of the second LM317 share electrical connection so they do not need any isolation, add a little thermal compound to the second LM317 and secure it to the heatsink.

We added a little thermal compound to the LM335 also, this combined with the slight pressure from being soldered in place at a slight angle will allow it to be as sensitive to changes in temperature on the heatsink as possible.

The Potentiometer can be wired to a female header so that it can easily be attached and removed from the PCB. We opted to use a more expensive and larger 10 turn bourns resistor which allows a much greater degree of precision however a standard 1 turn 5KΩ will be just as suitable.

We included a space on the PCB for an external LED if you wish to have an indicator LED, we are quite happy with the LED on the 1602 display and didn’t feel the need to have another indicator LED on the front panel. This does not negate the need for the LED and constant current circuit though. Please ensure you build the constant current circuit and LED, as without it, the LM317 will not have the mandatory load on it and could lose unloaded voltage regulation. You can still easily add this yourself by adding another hole to the front panel using Fusion360 or many other CAD programs.


Sourcing the switch for this project proved to be quite the ordeal. Whilst we suspected the switch used in last month’s prototype was insufficiently rated for the task, it was the only rotary switch available from our local electronics stores. For this build, we had to look to offshore suppliers to get a switch in time to meet the print deadline. As a result, we are using a high current switch (5A@30VDC), which is overrated and takes up a lot of area within the enclosure. We needed to use flush cutters to remove one of the mounting studs built into the enclosure to make the switch fit. We also needed to bend the solder tabs over slightly to avoid them fouling against the enclosure. We recommend you wire the switch before mounting it because it is difficult to access the solder tabs otherwise. We used short lengths of #18AWG 1mm 24-core wire to make the connections, and soldered the wires directly between the switch contact points and the male pin header on the PCB.

The switch needs to be wired to the pin header:

COM. Common connection, directly connected to the LM317 output

  1. 25Ω resistor
  2. 12.5Ω resistor
  3. 8.3Ω resistor
  4. 5Ω resistor
  5. 2.5Ω resistor
  6. 1.66Ω resistor
  7. 1.25Ω resistor
  8. 1Ω resistor
  9. 0.82Ω resistor


Max current

The greatest disappointment in this project was our inability to achieve the desired 1.5A current. We can reliably reach 1.3A however, at this point the current limiting LM317 goes into thermal protection and shuts down. Naturally, this isn’t ideal however, we only wanted such high current demands to deal with peak and surge currents such as the start-up of a DC motor. The LM317 should be able to deliver these peak loads quite fine provided they are not sustained for more than a few seconds. As such we are reluctantly happy to accept this limitation. The vast majority of electronics projects we as hobbyists are likely to encounter use little more than a few hundred milliamps. So, this is still a very useful and handy piece of equipment for our use case. In the future, we would like to revisit this and rectify the issue.

Maximum Voltage

As expected, the maximum voltage is dependent on the current being drawn at the time. This has several causes ranging from internal resistances to the LM317s having a voltage drop across them that varies dependent on the current through them.

We can see that at 1.3A the maximum voltage output drops to around 11.62V this is close enough to call 12V but isn’t ideal. If you must have a neat 12V on the output at max current, consider a slightly higher input voltage. With 20V on the input with a 1.3A draw, we could easily get 12V on the output for example.

Output Noise

The main advantage of a linear power supply compared to a switchmode supply is the low noise operation. Linear power supplies will always have significantly lower noise on the output compared to Switchmode supplies due to their mode of operation. We did some significant testing of the performance of this design in the previous issue, so we won’t go into as much detail again here. Our goal is to check primarily that the noise is at the same or better as the prototype. To do this we used a ground spring on our oscilloscope probe to minimize as much as possible the ground acting as an antenna.

With as close to 1A of current draw on the circuit as possible via a resistive load we checked the noise at each of the key voltage levels. This provided the data for the graph.

The maximum noise witnessed on the circuit had an amplitude of 3.12mV p-p. This occurred with the power supply delivering 12V into an 11.9Ω resistor producing a current of 1.007A. This appears to be slightly higher than the prototype with a 12V output however overall the performance is significantly quieter. The prototype had a maximum peak to peak ripple of 6.16mV with an output of 7V with a 1.148A load.

Oscilloscope screenshot showing the maximum output noise. This was under a 11.9Ω resistive load with an output of 12V.

Voltage drop in relation to current

Another phenomenon we observed while testing the device was that the voltage on the output would drop dependent on the current. With a load of 200mA, for example, the voltage would be 12.13V while at 1A it would be 12V. While not significant it is worth mentioning. This isn’t likely to be of any significant concern to anyone, however, with a fluctuating dynamic load, it could present some circuit instability and oscillations.


We were keen to see how effective the single fan was at keeping the heatsink cool inside the enclosure. To test this, we decided we should measure the temperature of the components inside the enclosure and the sound levels whilst the unit was under a 1 Amp load at the main voltages 3.3V, 5V, 9V, and 12V. We used two K-Type thermocouples one attached to out Uni-T UT804 benchtop multimeter and the other our Digitech QM1571 Handheld multimeter to measure the temperatures.

One thermocouple was attached to the heatsink directly above the LM335 temperature sensor and the other was attached to the heatsink directly behind the current limiting LM317.

We used our dummy load from Issue 22 to apply a load to the circuit and we used another multimeter the Digitech QM1323 to measure the current draw.

We also used a Uni-T UT353 sound meter 1 meter away to record the changes in sound levels. We would leave the power supply to run at this load for 30 minutes before taking all measurements after which we would increase the voltage to the next level and repeat.

As we can see from the graph, the device predictably generates more heat at lower voltage outputs. This is precisely what we would expect from a linear power supply as the regulator is essentially a variable resistance which converts the excess unwanted voltage into heat. This is precisely why linear regulators need large heatsinks. The bigger the voltage potential between the input and output the larger the heatsink needed to dissipate the generated heat. Naturally, this dissipation increases linearly with current.

Measurement accuracy

The Adafruit INA219 breakout module is remarkably accurate with a maximum accuracy of 0.5%. We verified this by comparing the reported values to measured values of both current and voltage.

To test the voltage accuracy, we kept the circuit under a 500mA load and adjusted the voltage potentiometer until it read 3.3V, 5V, 9V and 12V on the connected QM1323 multimeter.

To measure the current accuracy, we kept the power supply at a constant 12V and adjusted the load until the current reading on the supply read 100mA, 250mA, 500mA, and 1A. We then recorded the measured current using a Digitech QM1571 multimeter.

Note: While the circuit was not under load, the discrepancy was slightly higher, although, usually by one or two least significant digits.

This would appear to suggest that the INA219 breakout module was behaving out of specification on the current reading. However, in reality, the multimeter has its own accuracy specification of 1.2%. This means the readings from the INA219 are likely to be as reliable as a standard digital multimeter. This is pretty impressive from such an inexpensive little module.

Maximum Input Voltage

In this circuit, we have ascertained that the minimum input voltage needs to be 19V, at voltages lower than this the circuit will not be able to reach the 12V output.

The maximum input voltage should not exceed 25V. This limitation comes from the linear regulators used to power the ancillary devices such as the microcontroller and the 12V fan.

The LM7805 and LM7812 linear regulators we used have a maximum input voltage of 35V however at this voltage they will need to dissipate: Pd = (Vin - Vreg) × Iout

The 12V regulator controls the fan which can draw 80 - 100mA this means at 24V input the 12V regulator without heatsinking will need to dissipate around 1.2W of energy. Whereas at 35V input the power dissipation would be 2.3W.

The 5V regulator on the other hand only draws around 35mA which at 24V input will dissipate around 665mW and at 35V input it will dissipate around 1W.

Looking at the datasheet we can see that without a heatsink it can dissipate an absolute maximum of about 2.3W when the ambient temperature is at 25°C. However, the temps in Australia vary significantly with temps exceeding 30°C regularly in most areas. This combined with the fact the regulators are in an enclosed space with a heatsink potentially getting to temperatures over 90°C means that the ambient temp inside the enclosure is likely to be much higher. As such our maximum power dissipation without heatsink needs to include the higher temps which shows the power dissipation drop to around 1.5W.

However, this isn’t the only limiting factor, we have based all of our calculations for the device on an input of 19V, with the higher input voltage, the power dissipation in the circuit becomes much higher. With a 25V input and an output of 3.3V, the power dissipation becomes 31.05W with a 1.5A draw and 48W with a 35V input. Naturally, the higher the input over the designed in 19V input will reduce the current output of the circuit as our main limitation in this circuit is the current limiting LM317 which shuts down with currents exceeding 1.3A.

AC input

When simulating the circuit with NI Multisim, an 18V RMS AC input outputs around 4V p-p of ripple on the output. 18V RMS is equal to 51V p-p after the signal goes through the full-wave bridge rectifier, we will lose around 1.4V due to the diode drops and be left with 100 pulses a second of unfiltered, 100Hz pulsed DC with a peak amplitude of around 23.6V. if we subtract the 4Vp-p ripple from this we are left with 19.6V DC on the input to our circuit with a 2200μF capacitor.

Increasing this value will decrease the ripple, and as such, the amount of stable DC headroom. Although, the simulator suggests we will get the 19V we have based this project on.

Now of course simulators simulate ideal components and it’s very possible that the circuit won’t behave as well as the simulator suggests, however, we are not going into detail on how to connect this circuit to an AC source and leaving that up to people with the appropriate level of skill and licensing to do themselves.


The first thing we would rectify if we were to revisit this project would be the lower than expected current output. The datasheet for the LM317 states that it can deliver 1.5A of current. However, with every test, we have been able to do we were unable to reach this claimed output. We suspect that this is a hypothetical maximum if you were able to keep the junction temperature below the 125°C point at which the thermal protection kicks in.

However, this isn’t likely at all possible short of some crazy cooling setup. The LM317 has to drop around 3.6V across it to work with a current draw of 1.5A.

We can calculate the actual power dissipation using the formula:

P = Vf × Imax = 3.6 × 1.5 = 5.4W

However, under a 1.3A load the drop across the current limiting LM317 increases to around 5V reducing the maximum output potential 12V and increasing the power dissipation across itself to 6.5W. This results in the LM317 thermally shutting down to protect itself.

The ideal solution here would be to bypass the first LM317 for when you require currents higher than the 1A maximum. This could be done fairly easily with a switch and would allow for currents many times larger than the current theoretical maximum of 1.5A thanks to the pass transistor.

For example, the switch we used has the option of adding additional elements, which enables the user to add extra poles. We could hypothetically add one more of these poles and on the tenth position, have the second pole create a connection between the input to the power supply, and the output of the first LM317. This would completely remove any current limiting for the circuit by bypassing the first LM317. With this modification, the circuit could deliver significantly higher currents that potentially could exceed 5A.

If you’re not interested in the current limiting function at all, you can simply ignore the current limiting circuit altogether. You can leave resistors R2 - R10 unpopulated on the PCB, as well as the first LM317. If you short pin 2 and 3 of the LM317 footprint together, you will create a path from the full-wave bridge rectifier straight to the input of R11, into the voltage limiting LM317 and pass transistor.

Note: Other sections of the project, including the current sensing module, would need to be verified safe to operate at these currents. The current sensing module is only able to report up to 3.2A. As such, the current reading will likely not exceed this point. The current shunt is a 0.1Ω 2W resistor, which means it has a maximum current handling ability before reaching its rating of:

Imax = √(P/R) = √(2/0.1) = 4.47A

Currents higher than this will likely damage the shunt resistor. Therefore, if you’re wanting to make the changes to the design to work without current limiting, you will need to verify that the current will not exceed this point. Alternatively, you can replace the shunt resistor with a smaller value and modify the code to accommodate.

Part 1