Introduction: Digital USB C Powered Bluetooth Powersupply

Ever wanted a powersupply that you can use on the go, even without a wall outlet nearby? And wouldn't it be cool if it was also very precise, digital, and controllable via PC and your phone?

In this instructable I will show you how to build exactly that: a digital powersupply, which is powered over USB C. It is arduino compatible and can be controlled via the PC over USB or via your phone over Bluetooth.

This project is an evolution of my previous powersupply, which was battery operated and has a display and knobs. Check it out here! However, I wanted to go smaller, so that's why I made this!

The powersupply can be powered from a USB C battery bank or phone charger. This allows for up to 15W of power, which is enough to power most low power electronics! To have a good UI on such a small device, I included Bluetooth and an Android app for the controls.This makes this powersupply ultra portable!

I will show the whole design process, and all project files can be found on my GitHub page:

Let's get started!

Step 1: Features & Cost


  • Powered by USB C
  • Controlled via Android app over Bluetooth
  • Controlled via Java over USB C
  • Constant voltage and constant current modes
  • Uses a low noise linear regulator, preceded by a tracking preregulator to minimize power dissipation
  • Powered by ATMEGA32U4, programmed with Arduino IDE
  • Can be powered by a USB C battery bank to make it portable
  • USB C and Apple charger detection
  • 18 mm spaced banana plugs for compatibility with BNC adapters


  • 0 - 1A, steps of 1 mA (10 bit DAC)
  • 0 - 25V, steps of 25 mV (10 bit DAC) (true 0V operation)
  • Voltage measurement: 25 mV resolution (10 bit ADC)
  • Current measurement:
    < 40mA: 10uA resolution (ina219)
    < 80mA: 20uA resolution (ina219)
    < 160mA: 40uA resolution (ina219)
    < 320mA: 80uA resolution (ina219)
    > 320mA: 1mA resolution (10 bit ADC)


The complete powersupply costed me around $100, with all one-off components. While this may seem expensive, powersupplies with far less performance and features often cost more than this. If you don't mind ordering your components from ebay or aliexpress, the price would drop to around $70. It takes longer for the parts to come in, but it's a viable option.

Step 2: Schematic & Theory of Operation

To understand the operation of the circuit, we will have to look at the schematic. I divided it into functional blocks, such that it is easier to understand; I will thus also explain the operation step by step.
This part is quite in depth and requires a good electronics knowledge. If you just want to know how to build the circuit, you can skip to the next step.

Main block

The operation is based around the LT3080 chip: it's a linear voltage regulator, which can step down voltages, based on a control signal. This control signal will be generated by a microcontroller; how this is done, will be explained in detail later.

Voltage setting

The circuitry around the LT3080 generates the appropriate control signals. First, we will take a look at how the voltage is set. The voltage setting from the microcontroller is a PWM signal (PWM_Vset), which is filtered by a lowpass filter (C23 & R32). This produces an analog voltage - between 0 and 5 V - proportional to the wanted output voltage. Since our output range is 0 - 25 V, we will have to amplify this signal with a factor of 5. This is done by the non inverting opamp configuration of U7C. The gain to the set pin is determined by R31 and R36. These resistors are 0.1% tolerant, to minimize errors. R39 and R41 don't matter here, as they are part of the feedback loop.

Current setting

This set pin can also be used for the second setting: current mode. We want to measure the current draw, and turn the output off when this exceeds the wanted current. Therefore, we start again by a PWM signal (PWM_Iset), generated by the microcontroller, which is now lowpass filtered and attenuated to go from a 0 - 5 V range to a 0 - 2.5 V range. This voltage is now compared to the voltage drop across the current sense resistor (ADC_Iout, see below) by the comparator configuration of opamp U1B. If the current is too high, this will turn on an led, and also pull the set line of the LT3080 to ground (via Q1), thus turning off the output. The measurement of the current, and the generation of the signal ADC_Iout is done as follows. The output current flows through resistor R22. When current flows through this resistor, it creates a voltage drop, which we can measure, and it is placed before the LT3080, since the voltage drop across it should not influence the output voltage. The voltage drop is measured with a differential amplifier (U7B) with a gain of 5. This results in a voltage range of 0 - 2.5 V (more on that later), hence the voltage divider at the PWM signal of the current. The buffer (U7A) is there to make sure that the current flowing into resistors R27, R34 and R35 is not going through the current sense resistor, which would influence it's reading. Also note that this should be a rail-to-rail opamp, because the input voltage at the positive input equals the supply voltage. The non inverting amplifier is only for the course measurement though, for very precise measurements, we have the INA219 chip on board. This chip allows us to measure very small currents, and is addressed via I2C.

Additional things

At the output of the LT3080, we have some more stuff. First of all, there is a current sink (LM334). This draws a constant current of 677 uA (set by resistor R46), to stabilize the LT3080. It is however not connected to ground, but to VEE, a negative voltage. This is needed to allow the LT3080 to operate down to 0 V. When connected to ground, the lowest voltage would be about 0.7 V. This seems low enough, but keep in mind that this prevents us from turning the powersupply completely off. Unfortunately, this circuit is at the output off the LT3080, which means its current will contribute to the output current we want to measure. Fortunately, it is constant so we can calibrate for this current. The zener diode D7 is used to clamp the output voltage if it goes above 25 V, and the resistor divider drops the output voltage range from 0 - 25 V to 0 - 2.5 V (ADC_Vout). The buffer (U7D) ensures the resistors are not drawing current from the output.

Charge pump

The negative voltage that we mentioned before is generated by a curious little circuit: the charge pump.
It is fed by a 50% PWM of the microcontroller (PWM).

Boost Converter

Let's now take a look at the input voltage of our main block: VCC. We see that it is 5 - 27V, but wait, USB gives a maximum of 5 V? Indeed, and that's why we need to boost the voltage, with a so called boost converter. We could always boost the voltage to 27 V, no matter what output we want; however, this would waste a lot of power in the LT3080 and things would get toasty hot! So instead of doing that, we will boost the voltage to a bit more than the output voltage. About 2.5 V higher is appropriate, to account for the voltage drop in the current sense resistor and the dropout voltage of the LT3080. The voltage is set by resistors on the output signal of the boost converter. To change this voltage on the fly, we use a digital potentiometer, the MCP41010, which is controlled via SPI.


This leads us to the real input voltage: the USB port! The reason for using USB C (USB type 3.1 to be exact, USB C is just the connector type) is because it allows a current of 3A at 5V, that's already quite some power. But there is a catch, the device needs to be compliant to draw this current and 'negotiate' with the host device. In practice, this is done by connecting two 5.1k pulldown resistors (R12 and R13) to the CC1 and CC2 line.
For USB 2 compatibility, the documentation is less clear. In short: you draw whatever current you want, as long as the host can provide it. This can be checked by monitoring the USB bus voltage: one the voltage drops under 4.25V, the device draws too much current. This is detected by the comparator U1A and will disable the output. It also sends a signal to the microcontroller to set the maximum current.
As a bonus, resistors have been added to support the detection of the charger ID of apple and samsung chargers.

5V regulator

The 5 V supply voltage of the arduino normally comes directly from the USB. But since the USB voltage can vary between 4.5 and 5.5 V according to the USB spec, this is not precise enough. Therefore, a 5V regulator is used, which can generate 5V from lower and higher voltages. Still, this voltage is not terribly precise, but this is solved by a calibration step where the duty cycle of the PWM signal is adjusted accordingly. This e voltage is measured by the voltage divider formed by R42 and R43. But since I had no more free inputs, I had to make a pin pull double duty. When the powersupply boots, this pin is first set as an input: it measures the supply rail and calibrates itself. Next, it is set as an output and it can drive the chip select line of the potentiometer.

2.56 V voltage reference

This little chip provides a very accurate 2.56 V voltage reference. This is used as a reference for the analog signals ADC_Vout, ADC_Iout, ADC_Vbatt. That's why we needed voltage dividers to bring these signals down to 2.5 V.


The last part of this powersupply is the connection with the cruel, outside world. For this, we need to convert the serial signals into USB signals. Fortunately, this is done by the ATMEGA32U4, this is the same chip that is used in the Arduino Micro.


The Bluetooth part is very simple: an off-the-shelf Bluetooth module is added and takes care of everything for us. Since it's logic level is 3.3V (VS 5V for the microcontroller) a voltage divider is used to level shift the signal.

And that's all there is to it!

Step 3: PCB & Electronics

Now that we understand how the circuit works, we can start building it! You can simply order the PCB online from your favorite manufacturer (mine cost around $10), the gerber files can be found on my GitHub, together with the bill of materials. Assembling the PCB is then basically a matter of soldering the components in place according to the silkscreen and the bill of materials.

While my previous powersupply had only through-hole components, the size constraint for my new one made this impossible. Most components are still relatively easy to solder, so don't be afraid. As an illustration: a friend of mine who had never soldered before managed to populate this device!

It is easiest to do the components on the front side first, then the back and finish with the though hole components. When doing this, the PCB will not wobble when soldering the most difficult components.
The last component to be soldered is the Bluetooth module.

All components can be soldered, except for the 2 banana jacks, which we will mount in the next step!

Step 4: Case & Assembly

With the pcb made, we can move on to the case. I specifically designed the PCB around an aluminium 20x50x80mm case (, so using another case is not recommended. However, you could always 3D print a case with the same dimensions.

The first step is to prepare the end-panel. We will need to drill some holes for the banana jacks. I did this by hand, but if you have access to a CNC that would be a more accurate option. Insert the banana jacks into these holes and solder them on the PCB.

It is a good idea to add some silk pads now, and hold them in place with a small drop of super glue. These will allow for heat transfer between the LT3080 and LT1370 and the case. Don't forget them!

We can now focus on the front panel, which just screws in place. With both panels in place we can now insert the assembly into the case and close it all up. At this point the hardware is done, now all that's left is to blow some life into it with the software!

Step 5: Arduino Code

The brain of this project is the ATMEGA32U4, which we will program with the Arduino IDE.
In this section, I will go through the basic operation of the code, the details can be found as comments inside the code.

The code basically loops through these steps:

  1. Send data to app
  2. Read data from app
  3. Measure voltage
  4. Measure current
  5. Poll button

The USB overcurrent is handled by an interrupt service routine to have it as responsive as possible.

Before the chip can be programmed over USB, the bootloader should be burned. This is done via the ISP/ICSP port (the 3x2 male headers) through an ISP programmer. Options are the AVRISPMK2, USBTINY ISP or an arduino as ISP. Make sure the board receives power and press the 'burn bootloader' button.

The code can now be uploaded to the board through the USB C port (since the chip has a bootloader). Board: Arduino Micro Programmer: AVR ISP / AVRISP MKII Now we can take a look at the interaction between the Arduino and the PC.

Step 6: Android App

We now have a fully functional powersupply, but no way to control it yet. Very annoying. So we'll make an Android app to control the powersupply over Bluetooth.

The app has been made with the MIT app inventor program. All files can are included to clone and modify the project. First, download the MIT AI2 companion app to your phone. Next, import the .aia file on the AI website. This also allows you to download the app on your own phone by choosing "Build>App (provide QR code for .apk)"

To use the app, select a Bluetooth device from the list: it will show up as HC-05 module. When connected, all settings can be changed and the output of the powersupply can be read out.

Step 7: Java Code

For logging data and controlling the powersupply via the PC, I made a java application. This allows us to easily control the board through a GUI. Like with the Arduino code, I won't go into all details, but give an overview.

We start by making a window with buttons, textfields etc; basic GUI stuff.

Now comes the fun part: adding the USB ports, for which I used the jSerialComm library. Once a port is selected, java will listen for any incoming data. We can also send data to the device.

Furthermore, all incoming data is saved to a csv file, for later data treatment.

When running the .jar file, we should first choose the right port from the dropdown menu. After connecting data will start coming in, and we can send our settings to the powersupply.

While the program is pretty basic, it can be very useful to control it via a PC and log it's data.

Step 8:

After all this work, we now have a fully functional powersupply!

We can now enjoy our own home made powersupply, which will come in handy while working on other awesome projects! And most importantly: we have learned many things along the way.

If you liked this project, please vote for me in the pocket sized and microcontroller contest, I would really appreciate it!

Pocket-Sized Contest

Participated in the
Pocket-Sized Contest

Microcontroller Contest

Participated in the
Microcontroller Contest