Make a Microcontroller-based Boost Converter




For a recent project, I needed to boost the output from a USB (high ampage charging) port from 5V up to 18V to power an amplified speaker. I decided to try rolling my own boost converter (mainly because playing with big inductors sounded cool). My first attempt was a dismal failure (it could only source about 10mA and I needed 600mA!) but, after reading TI's guide to calculating components, I managed to get it working pretty well. (I also converted the calculations in that guide into a spreadsheet to make it easier to work through it.)

It turns out that component selection is a reasonably big deal for a converter or this type. Even after you've got the right "headline" value for a component, there are other factors you need to worry about too...

Step 1: Basic Principle

Wikipedia has a good explanation of the principle but here's a quick guide:
  • The boost converter rapidly switches a switch on and off.  (My design runs at 65kHz.)
  • When the switch is closed (first diagram), it connects an inductor across the input supply while the diode blocks any current from flowing back from the output side.
  • The inductor charges up.  (Although it seems like shorting a coiled piece of wire across the input should waste a lot of power, the inductor actually stores up the energy in its core.)
  • When the switch opens, the inductor resists any change in current (and, shorting it across the supply means it has a lot of current going through it).  Since the output side has a much higher resistance than the switch, the inductor has to raise its voltage to keep the current flowing.  (Resisting change in current by changing their voltage is the magical property of inductors.)
  • The output capacitor charges up from the inductor plus the power supply at the higher voltage.
  • When the switch turns on again, the capacitor is charged at the higher voltage and powers the load until the next cycle.  Since power is only ever applied to the output side part of the time, there will always be a ripple on the output voltage.
  • If the switch is on for a relatively longer time in each cycle (it's duty cycle is higher) then the inductor stores up more energy, resulting in a higher output voltage when the switch turns off.  Controlling the duty cycle lets you adjust the voltage.
So much for the principle, how do you turn that into a real circuit?

Step 2: Choosing the Key Components

For exact values, I've put together a template Google spreadsheet that does the calculations from the TI guide. Below, I've tried to sum up the rules of thumb that I gleaned after reading that document and searching around.

The inductor is the most important part of the circuit.

  • It's headline value is its inductance, measured in Henrys. The spreadsheet will help you calculate the right value. I recommend going for 1.5-2x the calculated value so you have some headroom.
  • You also need to check out:
    • The current rating, this needs to be enough to handle the peak current in the inductor (as calculated by the spreadsheet).
    • Shape: I went for a toroid because they're supposed to have low EMF interference. One source that I read said that bobbin inductors were the best bang for buck if you weren't worried about interference.
    • The core material, you want one that's suitable for a power inductor. I went for a toroid that was marketed as a power inductor. I believe it has a ferrite core.

I used this 150uH inductor.

This is the second most important piece of the circuit, and where I made a mistake first time around. A MOSFET is a good choice because it's easy to drive with a microcontroller. You need to look out for:

  • Rds(on) This is crucial, it's the resistance of the switch when it's turned on. My first attempt was scuppered by having a too-high value here. <10mOhm is ideal. If this is too high then the inductor won't be able to draw enough current and you'll waste power in the switch.
  • The Vgs(th) value, this is the voltage you have to apply to the gate of the transistor to turn it on. If you're using a 5V microcontroller, this needs to be 1-2V.
  • Vds(max), this is the maximum voltage the transistor can handle, go for the output voltage plus some safety margin.
  • Ids(max), the maximum current that the switch can handle. This needs to be bigger than the peak current according to the spreadsheet.

I used this switch.

The spreadsheet should calculate the minimum values for the capacitors in the circuit. I found that, powering an audio amp, I needed a much bigger output cap than was specified.

  • The capacitors in the output stage need to have a low ESR value for efficiency.

I chose a large, electrolytic capacitor with low ESR and then put in parallel with a 22uF ceramic capacitor in the hope of filtering the output further.

On the input side, I used the same setup.

The diode is fairly easy, just go for a Schottky diode that can handle the average current and has a low forward voltage (450mV seems to be the limit for non-exotic parts).

I went for an ATTiny84A because it's available in through-hole packaging, it's not too big and the AVR GCC toolchain is pretty good. I followed this tutorial from Lady Ada to get the toolchain up and running and I used AVR Eclipse to develop the code. I needed fairly precise control of the hardware to get the PWM running at 65kHz so it might have been difficult with the more-abstract Arduino IDE.

Step 3:

Here's the circuit I came up with.

  • At its heart, the microcontroller (code to follow...) uses its PWM output to control the switch.
  • It monitors the output voltage using its ADC, via the feedback potentiometer.
    • If the voltage drops below the target, it increases the duty cycle of the PWM, increasing the current in the inductor and hence the output voltage.
    • If the voltage goes over the target, it decreases the duty- cycle.
    • the voltage can be adjusted by adjusting the pot.
  • The 440 ohm resistor on the output ensures that there's always some load on the converter. I found that value by trial and error. My input 5V power supply would shut down if I didn't draw enough load from it. You might be able to get away with a much larger resistance. It's essential to load the output though; with no load, the converter will become unstable and the inductor will put out a very large voltage.
  • The small capacitors in parallel with the large ones are filter capacitors. Large electrolytics have a relatively high resistance so putting a small ceramic or polymer cap in parallel helps to deal with transient spikes.
  • The 0.1uF cap on the ADC input is simply a filter.

Apologies for the poor-quality photos! I was so excited that it worked that I sealed it inside my project before taking a good shot.

Step 4: Microcontroller Code

I've put my working code up on Github.  It has a few parts:

These #defines and const declarations do compile-time calculations so that the code only needs to do simple uint8_t comparisons rather than floating point which is not feasible in a microcontroller.  Using const encourages the compiler to do the calculation at compile time and forces the type of the result to uint8_t.

#define PWM_FREQ 62500
#define MIN_DUTY_CYCLE 0.40
#define MAX_DUTY_CYCLE 0.80

#define VREF 1.1
#define DESIRED_VOUT 20.0
#define DIVIDER_RATIO 30.0


These define some useful utility macros so that the code is easier to follow:


#define ADC_ENABLE() (ADCSRA |= _BV(ADEN))

The main function has an initial setup phase where it turns on the various peripherals that we'll need:

int main(void) {
    /* Set A7 as an output.  (Needed for PWM.) */
    DDRA |= _BV(DD7);
    PORTA = 0;

    /* Let input power stabilize... */

     * Configure Timer0 as a fast PWM.  It will
     * - turn on the output pin at the start of each cycle
     * - turn it off when the value hits DUTY_CYCLE_REG
     * - wrap to 0 when it hits OCR0A
    TCCR0A = _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
    /* Start with 40% duty cycle and ramp up to avoid inrush. */
    DUTY_CYCLE_REG = (uint8_t)(PWM_RESOLUTION * 0.40);
    /* Set Timer0 clock source to be main oscillator. This enables the timer. */
    TCCR0B = _BV(CS00) | _BV(WGM02);

     * Turn on the ADC,
     * - use internal voltage ref.
     * - configure ADC0 as our source
     * - left-adjust the result, 8-bits is enough for us
     * - disable digital input buffer on pin
     * - enable the ADC.
    ADMUX = /* REF = */ _BV(REFS1) | /* INPUT = */ 0;
    ADCSRA |= /* PRESCALER = 16 = 2^ */ 4;
    DDRA &= ~_BV(DD0);
    DIDR0 |= _BV(ADC0D);

Then, it simply loops, reading the analog value from the potentiometer and comparing it to its target:

while (1) {
      /* Wait for the Timer0 to overflow... */
      loop_until_bit_is_set(TIFR0, TOV0);
      /* End of our OFF period, should be peak voltage... */
      TIFR0 |= _BV(TOV0);  /* Clear the flag. */

      /* Check the output voltage. */
      loop_until_bit_is_clear(ADCSRA, ADSC);
      uint8_t adc_result = ADCH;

      if (adc_result < DESIRED_ADC_RESULT &&
      else if (adc_result > DESIRED_ADC_RESULT &&
               DUTY_CYCLE_REG > MIN_PWM_LEVEL) {

Step 5: Final Thoughts/next Steps

Caveat emptor: I'm not SMPS expert, and I've only built one.  I welcome any feedback from experienced engineers.

One weakness in my current design is that it has no inrush current protection.  I actually had to add a 0.2ohm resistor in series with Vin to avoid tripping the protection circuit in the USB charger.

I had a go at measuring the efficiency of my circuit by adding a shunt resistor to the input supply and loading the output with a high wattage resistor.  The absolute limit seems to be putting out about 25V, where the efficiency drops to about 50%.  At 18V, I get a respectable 75% and at 12V it's more like 80%+.  



    • Trash to Treasure

      Trash to Treasure
    • Tape Contest

      Tape Contest
    • Arduino Contest 2019

      Arduino Contest 2019

    30 Discussions


    3 years ago

    Great idea! I made a boost LED driver version of it for my bike light. When you have a strobe light, it extends the battery life and lets you use a smaller battery pack. Using boost lets you use a smaller circuit board too

    If you want to use smaller inductors and capacitors you should use a 16 MHz or 20 MHz oscillator. It will increase the switching frequency.

    In some of my prototypes, for some reason, the microcontroller shuts down whenever the boost converter turns on even at its minimum duty cycle. It might be caused by noises by improper layout. Once it worked perfectly on a bread board but shuts down on a prototyping board.

    You could experiment with buck converters or making four voltage rails because the ATtiny84 has four PWM channels.

    1 reply

    Reply 2 years ago

    Thanks for the tip; when I started out, I didn't realise how important the high frequency would be and I was too lazy to add a crystal :-)


    2 years ago

    I have tried to make a step up to 32 or 36 volts. What do you advise me? Or a power supply from 220 to 36 volts.

    1 reply

    Reply 2 years ago

    The efficiency drops off the higher you try to boost it. 18V worked for me 5V to 36V might be too much.

    This circuit isn't appropriate for reducing voltage. A transformer-based power supply would probably be better of 220->36V. Dealing with 220V is dangerous; you should consult an expert (or become one!).


    2 years ago

    Does anyone have a code for this? Preferably for ATtiny85?

    1 reply

    Reply 2 years ago

    The code is in the instructable with a link to the github page. It's for an ATTiny84, which is pretty close to an 85.


    2 years ago

    I am trying to build the same thing using an Arduino Uno, could you give me some preliminary tips on how to proceed ? I am a student and this would aid in my final year project.

    2 replies

    Reply 2 years ago

    My number one recommendation is to start simple. Break the problem down into a few pieces and solve each one separately then think about how to combine them.

    You might want to start by reading a voltage using an analog input and writing that to the serial console.

    Then try the other half of the circuit, try outputting a pulsed signal at a fixed rate.

    Then put that together with the analog part of the circuit; you should be able to adjust the output voltage by changing the pulse rate.

    Then start to put those pieces together and control the rate from the analog input.

    One note: my code is for a more basic chip. It should be a lot easier to program an Arduino to do PWN and to read the input. Look up analogRead and analogWrite.


    Reply 2 years ago

    @fasaxc : I have managed to build up the circuit for a 19v input, 48v output circuit with current and voltage measurement. Could you get on a Skype call sometime since I need some clarifications on understanding how the PWM and duty cycle settings vary in the MPPT algorithm...


    3 years ago

    what did you use to upload the code to the microcontroller. Will the usbasp programmer work?


    3 years ago

    Hi, this is a great project! But I have a confusion, how do you do the PWM frequency at 65kHz? Are you using any code or hardware to do that? I want to know how do you do that... Sorry if it is a silly question. I am doing a project and want to output a PWM but it is only 32kHz. I want to make it higher.

    1 reply

    Reply 3 years ago

    Step 4 explains how to set the hardware PWM in fast PWM mode. The full code is on github. Note: you'll need to use the same chip and fuse settings to use my code or the register settings may be different.


    This is an extremely useful project you have completed. Good Work. I am interested integrating this into a project of my own. Would you be willing to help me adjust the code to work with a standard Arduino (UNO)? I need additional functionality beyond the ATtiny and sketch writing is already a weak area for me.

    2 replies

    Reply 3 years ago on Introduction

    Thank you for responding so quickly. It is appreciated. I feel that the boost converter is the best solution. The project is portable, (wearable in fact) and charging via USB is really the only practical solution. The only other option I have considered is developing a circuit that will break a series battery pack into parallel cells for charging and then back into series to drive the load. This solution is less elegant. Higher weight, more parts, more power loss, and the danger of shorting LiPos is simply unacceptable for a wearable project. I think keeping the batteries in their typical configuration is best while finding a method to charge them via USB. Thank you for your time and consideration.


    Reply 3 years ago on Introduction

    Inductors are usually rated by maximum current. You need an inductor that can handle the current you calculate.


    Thank you very much for replying in such a short time and considering my request. I have opened the spreadsheet and plugged in the values of my supply voltage and calculated the values and now I am going to simulate it and see whether output is desired or not.

    I'll request you to give me your email id so that I can contact you via email. I have a serious need of the help because I have a project pending in which I need this converter. So, please give me your email id. My email id is

    I again appreciate you for your help. Thank you very much Sir !
    Have a nice day !


    I tried entering the values in a spreadsheet but the TI link seems to have expired and hence I am not getting the values. Would you please help me to design such converter for the input voltage of 3 volts and the output voltage of 5V and 500 mA ?

    I am asking you to help me which inductor and capacitor values should I choose in order to get the regulated supply of 5V. My demands are Vmin 2.8 Volt and Vmax 3.2 volts for input and output voltage, as I mentioned, is 5V and output current is 500mA.

    1 reply
    fasaxcMayur Balwani

    Reply 4 years ago on Introduction

    Try this new spreadsheet link: