$10 ATA Part 4 – Building a DC-DC converter with a microcontroller

For the $10 ATA I want to design a DC-DC converter using a micro-controller and a few discrete components. However, this means some sort of control system, i.e. a feedback loop that includes the “the plant” (the thing we want to control):

control system

I admit I am intimidated by control system design. I studied this at University, I think I even scored a B for the subject. But I have no idea how to build one, either analog or discrete time. It was one of those subjects I never really internalised, and 25 years of not using the theory hasn’t helped. Time to bite the bullet.

I want to engineer the design, using some sort of simulation. I did some Googling, but couldn’t find a nice How-To on simple discrete time control system design and simulation for micro-controllers. Actually I didn’t look that hard. I think the engineer in me took over – I wanted to work this out myself. However if anyone has a good on-line resource for micro-controller based DC-DC converter design please post it to the comments below.

I didn’t feel like reading a text book or repeating my control system course. So I had a go at working it out from first principles, and have documented the story here.

DC-DC Converter

Here is the DC-DC converter hardware I am using. I started with the DC-DC converter circuit for the Silicon Labs FXS chipset. That’s why it has some odd component values. We use this chipset for the Mesh Potato (and IP0X) FXS port.

Q3 and Q4 drive the switching transistor Q5, ensuring it gets switched off and on quickly to avoid switching losses. C19 and C18 prevent Q5 staying on if the uC software crashes and the PWM IO gets stuck high. R33 and R34 sample Vbatt for the control loop in the uC, shifting -Vbatt into the 0 to 5V range for the uC ADC. R35 and D5 prevents a large negative voltage and current getting to the ADC input should Vbatt get very negative.

The VBATT_SENSE node is connected to a ADC input on the micro-controller, and the PWM comes from a micro-controller PWM output. The idea is that the micro-controller software implements a control system that keeps Vbatt at a specific set point, for example -24 or -48V. If we make the set point a 20Hz 100Vpp sine wave, we can modulate the DC-DC converter output, and make the phone ring.

DC-DC converter control system

The DC-DC converter hardware needs to be simplified to use garden variety components, in line with the rest of the $10 ATA. But I’ll worry about that later. First, lets get the control system software working.

Impulse Response

The first thing I want to do is simulate the DC-DC converter in Octave. This means I need a “model” of the DC-DC converter analog hardware that I can run inside an Octave simulation. The DC-DC converter has a PWM value between 0 and 255 as it’s input, and generates a negative DC voltage (Vbatt) as it’s output. I thought about this for a few days then hit on the idea of trying to sample the DC-DC converter impulse response. I could then plug the sampled impulse response into my Octave model.

An impulse response is what happens to a real-world system when you hit it hard and quickly. For example click you fingers, our knock you knuckles on your desk. What you hear is the impulse response of the room you are in, or your desk. A bell or a wine glass is a good example, flick it and it will ring for a while.

In the case of the DC-DC converter hardware, we will “hit it” with a single PWM pulse and watch what happens.

So I wrote my impulse response program, fired it up, and observed the DC-DC converter output on my oscilloscope. Here is what I saw for a PWM register value of 255:

DC-DC converter impulse response

OK so this looks like simple exponential decay. A first order system. I was expecting something more weird and wonderful, e.g. with ringing and damped sinusoids. I measured the time constant (time to decay by 63%) as about 28ms. Hmmm, in the DC-DC converter I have a 10uF capacitor at the output and a 3300 ohm load. So the measured time constant is a good match to the theoretical time constant of RC = (1E-5)(3300)= 33 ms.

Wow. Engineering in action. Theoretical meets calculated. This rarely happens to me! Actually it didn’t happen quite like that. Over the years I had forgotten the formula for time constants, got my 63% mixed with my 37% and had a dud 10uF capacitor. So I spent two days of going around in circles, brushing up on analog electronics and repeating measurements. Eventually I sorted it out. Theoretical eventually met calculated – after two days of debugging!

Engineering is never linear. When I start a new project I feel like there are a bunch of pieces whizzing about my head. Over time I pull them out of the air one by one, gain some understanding, and after a few mistakes start to slot them into place.

DC-DC Converter Discrete Time Model

The impulse response above suggests we can model the DC-DC converter as a linear gain driving a parallel RC circuit. That’s pretty cool, a lot easier than I thought. Thinking about it some more (these things are always obvious afterwards), the current flowing in the inductor acts like a current source, charging the capacitor on each PWM cycle. The amount of energy stored in the inductor is based on the PWM “on time”. If we have a longer PWM “on time”, the capacitor gets more charge, so the voltage across it is higher. The load resistor then discharges the capacitor. The higher the capacitor voltage, the more discharge current flows.

Here is a simplified DC-DC converter model:

DC-DC converter model

So I forgot about the original idea of sampling the impulse response in software. Instead I decided to build up a discrete-time model of the DC-DC converter hardware from first principles:

The capacitor integrates current coming from the inductor, we can model this as:
Vbatt(n) = Vbatt(n-1) + k * pwm(n)

where Vbatt(n) is the output of the DC-DC converter in volts, and pwm(n) is the PWM input value (between 0 and 255). The constant k maps the PWM duty cycle (an 8 bit number between 0 and 255) to the output voltage. As the current enters the capacitor, it charges, and Vbatt gets “pumped” up.

Now at the same time the resistance of the load is discharging the capacitor. It draws off current proportional to Vbatt. Due to Ohms law as Vbatt increases, so does the discharge current. We can add that to the discrete time model:
Vbatt(n) = Vbatt(n-1) + k * pwm(n) - c * Vbatt(n-1)

OK, but how to choose the constant c? We know this should work out to a time constant of about 30ms. This will make the impulse response of the discrete time model match the real-world analog DC-DC converter hardware. Now c will also be affected by the sample rate of out discrete time system, Fs. With a faster sample rate we would expect a smaller c.

Now the time constant is related to the frequency response. The system above is a low pass filter with -3dB cut off frequency of 1/(2*pi*tau), where tau is the time constant. Through some z-plane maths which I am too lazy to type up here I found that a good approximation for c is:
c = 1/(tau * Fs)

where Fs is the sampling rate. When plugged into an Octave model for the DC-DC converter this gives a simulated impulse response like this:

simulated DC-DC converter impulse response

You can see it dips down to -5.6V and has a time constant of around 30ms, just like the oscilloscope plot above. The model also matches the real world hardware for steady state PWM signals. So I am on the right track.

Closed Loop Simulation

Now we have a discrete time model of the DC-DC converter hardware we can simulate the entire closed loop control system with a little more Octave code. The idea is we tell the software we want an output voltage (say -48V) and it uses a closed loop to zero in on that voltage.

Here is the closed loop DC-DC converter Octave simulation, and here is the plot of the steady state ouput for a -48V set point:

Octave simulation steady state output

The only extra parameter I added was a gain, which was set experimentally to 8. The higher the gain, the faster it converges.

Fixed point Simulation

The AVR micro-controller C code needs to be fixed point. So after I was happy with the Octave simulation I built this fixed point C simulation. It includes models of the DC-DC converter and ADC. The ADC model includes the voltage divider formed by R33 and R34. I ported the control loop to fixed point in small steps, checking against the Octave simulation results. One useful measure was the standard deviation (RMS noise voltage) of the steady state voltage. This jumped up from zero in the floating point simulation to 0.2V when I modelled the quantisation of the ADC.

This amount of noise makes sense. The ADC range (256 levels) is scaled to represent 0 to -100V. That’s about 0.5V/bit or a maximum error of 0.25V. If the ADC can’t measure Vbatt very accurately we have to expect some noise in the output.

Here are some plots of the steady sate output (top) and the noise in the steady state output (below):

Fixed point simulation steady state output

Fixed point simulation steady state output noise

This output noise might limit the usefulness of a micro-controller controlled DC-DC converter for some applications. For applications that only require steady state regulation it may be possible to smooth the noise further using analog filtering or a low bandwidth filter in the control system. As I want to modulate the power supply at 20Hz for ringing I need a fairly wide bandwidth.

Smoke Testing

Time to integrate the code and hardware and see if this puppy actually works! I wanted to bring it up carefully. The hardware can develop very high voltages (a few 100V), and I blew up my AVR last time I worked on this.

Here is the DC-DC converter software for the target hardware. It uses exactly the same control loop C code as the fixed point C simulation so I can quickly switch between the simulation and real time code.

OK, lets get started. First step is to power up the Arduino alone, and see if it does something sensible with no power to the DC-DC converter. The AVR software is programmed to toggle a few I/Os as it executes. This lets me know when various events occur, for example PWM cycles and each time the control loop code is executed. So I can tell when various parts of the code run, and measure statistics like the sample rate and execution time of the control loop function.

With no power connected to the DC-DC converter, Vbatt will be zero. The control loop should respond with maximum PWM width (maximum on time). Oops – the PWM width was all off (minimum). After some head scratching I eventually worked out I had the ADC scaling back to front. The R33/R34 voltage divider is trickier than it looks as it has one end at Vbatt, the other at 5V. This shifts and and scales the large negative voltage Vbatt to a voltage in the range of 0 to 5V for the ADC. Twenty minutes with pencil, paper, and voltage division formulas sorted that out.

The second bug was handling the maximum PWM width. The DC-DC converter doesn’t work too well with high PWM on-times. For example a value of 255 means it stays on all the time. This doesn’t work as the transistor Q5 never switches off. We need some cycling at the PWM frequency for D5 to conduct and C20 to charge. For my configuration, it turns out the maximum useful PWM value is 192. So I hard limit the maximum PWM value to 192 in the control loop software.

After that – the DC-DC converter burst into life! It holds Vbatt at around -46 to -48V for various loads. Good enough for my application. I can see the PWM duty cycle (on time) adjusting with different loads. The -46V output for the 3300 ohm load is close to the fixed point C simulation (-45.6V). Wow, my very first control system and DC-DC converter. Cool.

Rload Vbatt Power Out Power In Efficiency
3300 -46.1 0.64 0.85 76%
1000 -43.9 1.21 1.92 76%
no load -48.4 0 0 n/a

The DC-DC converter is about 76% efficient. This is quite respectable, similar to commonly used switch mode regulator chips. A finger test showed that nothing was getting hot, except the load resistors. Better regulation could be achieved with a more sophisticated control loop. However it’s fine for my application of a telephony power supply.

Here is the DC-DC converter doing it’s thing with a 3300 ohm load. Extreme sophistication and care was taken in the construction of the prototype circuit:

DC-DC converter prototype

I even smoked up some quarter watt resistors (they don’t like dissipating 2W).

1000 ohm resistor

Further Work

Next I need to see if the DC-DC converter can be used to generate 100Vpp ring voltages. More on that in the next post.

Some ideas for further work and other applications:

  • This design (micro-controller plus a few discretes) could be used for many other DC-DC converter applications. For example a solar panel maximum power point trackers or lead-acid battery charger. This approach is very flexible. It is very easy to modify, experiment, and add special features as it is based on a micro-controller software rather than a hardware switcher chip.
  • I would like to see how simple we can make the hardware, for example a simpler drive arrangement and a more commonly available transistor/diode for Q5/D5.
  • Ken Boak made the great suggestion of using a positive Vbatt rail, he writes:

    All phones are fitted with a front end bridge rectifier, and no reference to ground, so it makes no difference if your battery is +48V or -48V. Working with a battery voltage which is positive makes referencing to other circuit measurement points easier – eg line current sensing, less opportunity for damage to ICs, and generally uses NPN transistors and N channel mosfets which are often cheaper and easier to drive than P type.

    Great idea Ken. I will do this. I started with a negative Vbatt as that is the convention for telephony. Actually designing everything for negative voltages was an interesting puzzle and really made me think. But it’s much more in line with the minimalist philosophy of the $10 ATA to use a positive Vbatt rail.

  • Outside of the $10 ATA application, simpler, cheaper micro-controllers could be used.
  • The DC-DC converter software uses only a small fraction of the micro-controller CPU. So it could be implemented “for free” in designs that already have a micro-controller. For example the Mesh Potato uses an AVR for FXS port interfacing. We could add a solar charger or battery backup charger to the Mesh Potato for nearly zero cost.
  • It could be combined with other gadgets like WISPCAR as part of solar power Wifi repeater system.


  1. $10 ATA SVN, circuits, source code, Makefiles, notes on downloading to Arduinos.
  2. Project Google Group Mailing List. I’ll answer questions on it or via comments on this blog post.
  3. Gyrator DC Characteristic
  4. How echo cancellers work
  5. $10 ATA Part 1
  6. $10 ATA Part 2
  7. $10 ATA Part 3 – Hybrid
  8. Fixed Point Scaling – Low Pass Filter example, another example of a simple low pass filter.

7 thoughts on “$10 ATA Part 4 – Building a DC-DC converter with a microcontroller”

  1. This is great, David! Congratulations! You may find this oscilloscope shot useful:
    It was measured at the collector of Q7 (that would be Q5 in your design) back when I was debugging Open USB FXS’s DC-DC converter and trying to figure out how it works. Your explanation and Octave simulations do a terrific job in this aspect!

    From experience, it seems that the 3210 which you use as a starting point has also another (call it) control loop: if the output voltage drops too low w.r.t. the driving PWM signal (can happen if you e.g. short-circuit Tip and Ring), it shuts down the PWM for a short period, then restarts it shortly after (this results in an audible click BTW). I guess this is a protection measure, mainly for Q5.

    Keep up the good work!


    1. Thanks Angelos … yes a good idea is an analog signal path that shuts down the PWM under overload, or at least stops anything blowing up. Could be as simple as a larger R27/R28 in the collector of Q5. The power supply can have a relatively high output impedance – it’s desirable for Vbatt to drop down to say 12V when the phone is off hook.

Comments are closed.