<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
  <head>
    <!-- this stylesheet will later on be added by lfparser automatically: -->
<style type="text/css">
<!--
  pre { font-family:monospace,Courier }
  p.code { width:80%; alignment:center; background-color:#aedbe8; border-style:no ne; border-width:medium; border-color:#aedbe8; padding:0.1cm ; text-align:left }

-->
</style>

    <title>A Microcontroller based DC power supply</title>
  </head>

  <body>
    <h1>A Microcontroller based DC power supply</h1>

    <h4>ArticleCategory: [Choose a category, do not translate
    this]</h4>
    Hardware 

    <h4>AuthorImage:[Here we need a little image from you]</h4>
    <img src="../../common/images/Guido-S.gif" alt=
    "[Photo of the Author]" height="164" width="173"> 

    <h4>TranslationInfo:[Author + translation history. mailto: or
    http://homepage]</h4>

    <p>original in en <a href="http://linuxfocus.org/~guido/">Guido
    Socher</a></p>

    <h4>AboutTheAuthor:[A small biography about the author]</h4>

    <p>Guido loves Linux not only because it is fun to discover the
    great possibilities of this systems but also because of the
    people involved in its design.</p>

    <h4>Abstract:[Here you write a little summary]</h4>
    This article is the 4th article in the Linux<font color=
    "#FF0000">Focus</font> AT90S4433 Microcontroller series. I
    suggest you to read the previous articles on Atmel
    Microcontrollers programming with regards to: 

    <ol>
      <li>How to install and use the Linux AVR development
      environment and how to build the programmer hardware:<br>
      <a href="../March2002/article231.shtml">March 2002,
      Programming the AVR Microcontroller with GCC</a></li>

      <li>How to make your own printed circuit board:<br>
      <a href="../May2002/article236.shtml">May 2002, A LCD control
      panel for your Linux server</a></li>

      <li>How to build the case/box for your power supply:<br>
      <a href="../September2002/article253.shtml">September 2002,
      Frequency counter 1Hz-100Mhz with LCD display and RS232
      interface</a></li>
    </ol>
    One of the most important devices for your workshop at home is
    a good, and reliable DC power supply. In this article we will
    build such a power supply. It will be Microcontroller
    controlled. It has a LCD display, and you can send it commands
    from your Linux computer via RS232 interface. It has a very
    robust design. <br>
    <br>
    This article shows also how versatile Microcontrollers are. It
    is however not the simplest circuit. <br>
    If you are just looking a simple DC power supply then take a
    look at the <a href=
    "../../common/src/article251/simpleDCpower/">"simple DC
    power"</a>. The simple DC is good if you just need a small
    power supply unit for the other electronic experiments in
    Linux<font color="#FF0000">Focus</font>. It has however nothing
    to do with Linux and software in general. <br>
    Even if you finally only build the "simple DC power" unit you
    can read on and learn many interessting aspects about
    Microcontrollers. 

    <h4>ArticleIllustration:[This is the title picture for your
    article]</h4>
    <img src="../../common/images/article251/dcpower-logo.gif"
    width="202" height="160" alt="[Illustration]" hspace="10"> 

    <h4>ArticleBody:[The article body]</h4>

    <h2>Introduction</h2>
    This Microcontroller bases DC power supply is not the simplest
    circuit but I can assure you that you will not regret the time
    needed to build it. It is very robust and reliable. It is also
    technically very interesting, because you will learn how to
    generate a analog DC voltage with a Microcontroller without
    using a DA-converter chip. <br>
    <br>
    You need a lot of parts for this article but those are only
    cheap standard parts. This power supply is not expensive. <br>
     

    <h2>What you need</h2>
    See this <a href=
    "../../common/src/article251/partlist.html">part list</a> for a
    listing of all the parts that you need. You can also see the
    needed parts with their values in the schematic below. <br>
    Our power supply comes in 3 variants. Except for the
    transformer and one resistor there is only a modification in
    the software required. All other parts are identical for all 3
    options: 

    <ol>
      <li>0-16V Imax=2.2A<br>
      buy a transformer with 15V 2.5A</li>

      <li>0-24V Imax=2.2A<br>
      buy a transformer with 24V 2.5A</li>

      <li>0-30V Imax=3A<br>
      buy a transformer with 30V 3A</li>
    </ol>
Note: In all three cases you need of course the additional 9V, 100mA transformer
for the power to the main board.

    <h2>Schematic and board</h2>
    I used <a href="http://www.cadsoftusa.com/">eagle</a> for Linux
    to design the schematic and board. The eagle files are also
    included in the tar.gz package together with the software. You
    can download it at the end of the article. <br>
     <br>
    The circuit is divided into 2 parts. One main part and one part
    that should be close to the power transistors. Below you see 2
    independent schematic diagramms for the two parts but they are
    finally to be connected via wires. <br>
     <br>
     The main schematic (click on it for a bigger picture):<br>
     <a href="../../common/images/article251/schematic.gif"><img
    src="../../common/images/article251/schematic_th.gif" width=
    "576" height="346" alt="[main schematic]"></a> <br>
     <br>
     The schematic for the high power part (click on it for a
    bigger picture):<br>
     <a href=
    "../../common/images/article251/schematic_powerpart.gif"><img
    src="../../common/images/article251/schematic_powerpart_th.gif"
    width="577" height="325" alt="[power part schematic]"></a> <br>
     How to connect the push buttons in a matrix (click on it for a
    bigger picture):<br>
     <a href=
    "../../common/images/article251/push_buttons_schematic.gif"><img
     src=
    "../../common/images/article251/push_buttons_schematic_th.gif"
    width="277" height="103" alt="[push buttons schematic]"></a>
    <br>
     <br>
     The main board, top view (click on it for a bigger
    picture):<br>
     <a href=
    "../../common/images/article251/linuxDCpower_board_white.gif"><img
     src=
    "../../common/images/article251/linuxDCpower_board_white_th.jpg"
     width="363" height="284" alt="[board]"></a> <br>
     <br>
     <br>
    The board is specifically designed for hobby electronic. Only
    the blue layer is meant to be etched as a printed circuit
    board. The red lines are wires. It's much easier and less
    accuracy is required to build a single sided printed circuit
    board. You can lay the wires (red) such that they have the
    shortest length. I could not do that in eagle. <br>
     <br>
    The few parts in the high power part of the power supply can be
    mounted on a standard prototyping boards (those boards with
    many holes). The main board and the power part is connected via
    wires (JP2 and JP3). You will notice that the ground wire from
    the main part connects plus DC out. This is correct and it is
    the reason why we need two separate transformers for (one for
    the power part and one for the logic part with Microcontroller
    and operational amplifiers). 

    <h2>How it works</h2>
    Looking at the main schematic you can see that it consists of 2
    logical parts. One is is marked in the schematic as "current
    control" and the other "voltage control". These are 2
    independent control loops. The one loop controls the output
    voltage and the other the voltage drop over the 0.275 Ohm
    resistor in the power part. The voltage drop is equivalent to
    the current. The two control parts are "combined" via diodes D2
    and D3. These diodes form and analog electrical OR-gate. That
    is if the current is too high then the current control part
    lowers the voltage until it is below the limit otherwise
    (current not too high) the voltage control part is in charge of
    regulating the output voltage. <br>
    <br>
    This logical OR works because the transistor T3 is connected
    via R19 to +5V. If there where no operational amplifiers
    connected behind D2 and D3 then you would get maximum output
    power. The operational amplifiers in the control loops control
    the output by taking away the +5V from T3 (pull it as much as
    needed to ground). <br>
    <br>
    The voltage control loop controls the output voltage according
    to the voltage level that it gets on pin 5 of IC6B. In other
    words the voltage on pin 5 is equivalent to the output
    multiplied by the amplification factor which is determined by
    the resistors R15, R10 and R16. The same goes for the current
    except that it is the voltage on resistor R30 which is
    equivalent to the max. output current. <br>
    <br>
    In order to set the max current or regulate the output of the
    power supply we just need to supply appropriate voltages on the
    two points (pin 5 of IC6B and resistor R30). This is what the
    Microcontroller does.... but how can a Microcontroller generate
    and regulate a reference DC voltage? Take a look at the
    following picture: <br>

    <center>
      <img src="../../common/images/article251/lowpass.gif" width=
      "475" height="309" alt="[pwm]">
    </center>
    <br>
    What you see in this picture is how a pulsed signal can be
    transformed into a DC signal. All you need to do is run it
    through a low pass filter with a cut off frequency a hundred
    (or more) times lower than the signal frequency. Since our
    Microcontroller runs at 4Mhz it is not so difficult to design
    such a low pass filter. Even if we implement the signal
    generation with software we will still get a few kHz and the
    filter will still be very small. <br>
    <br>
    The difference in the picture between the upper and the lower
    diagram is called pulse width modulation. By changing the
    length of the pulses we can change the DC voltage behind the
    filter. <br>
    <br>
    Cool, isn't it? We can generate a exact DC voltage from a
    digital signal! <br>
    <br>
    The AT90S4433 Microcontroller has two internal counters. One is
    16bit wide and one is 8bit wide. The 16bit counter has the
    possibility to use pulse width modulation (PWM) which is
    already implemented in hardware in the AT90S4433 chip with a
    resolution of 10bit. The 8bit counter does not have that but we
    can implement it in software. It is still fast enough. We use
    the 16bit counter for voltage regulation this gives us
    10bit=1023 steps of resolution for the voltage control. The
    output current is controlled with the 8bit wide counter and it
    gives us 255 steps to control 1-3000mA. That means we have an
    accuracy of about 12mA (or less). This is still sufficient for
    current control. <br>
    <br>
    All the other parts in the circuit are for power supply and
    reference voltage (the 7805 is our reference point) and for
    ensuring that the power supply does not behave unstable when
    switched on or off. 

    <h2>The software</h2>
    The software for the Microcontroller uses many aspects which
    you already know from the previous articles (uart for rs232,
    lcd display, counters in interrupt mode). You can take a look
    at it here:<br>
    <a href=
    "../../common/src/article251/linuxdcp_c.html">linuxdcp.c</a>.
    <br>
    <br>
    Interesting is perhaps the software PWM (Pulse Width
    Modulation). The variable ipwm_phase implements together with
    ipwm_h the PWM for the current. We just run the 8bit counter in
    interrupt mode and every time it generates an overflow the
    function "SIGNAL(SIG_OVERFLOW0)" is called. Here we check the
    ipwm_phase to check if we should generate a 1 or a 0 at the
    output and then we restart the timer. Easy.<br>
    <br>
    The software is not complicated at all but to understand it
    exactly you need to read the data sheet of the 4433 (see
    references). <br>
    <br>
    The 4433 is a 8bit Microcontroller and its mathematical
    capabilities are limited. The functions divXbyY and multiXbyY
    implement 24bit math which we need to accurately calculate the
    pulse width from a given voltage set be the user. <br>
    <br>
    Our power supply has 7 buttons. 6 buttons are available to step
    the current and voltage levels and one button is "standby".
    Using the standby button you can temporary switch off the power
    and still change the voltage and current limits. The state of
    the buttons is "pulled" in the main loop in the program. The
    ignorebutton variable is used to debounce the buttons. When you
    press a button with your finger it bounces up and down a bit.
    As a human you will not notice this but the Microcontroller is
    so fast that it would see on, off, on, off... The ignorebutton
    counter waits a bit after a button press to avoid this
    bouncing. 

    <h2>Making the printed circuit board</h2>

    <table align="right" width="250" border="2">
      <tr>
        <td>The main board:
        <br>
        <a href=
        "../../common/images/article251/dcpower-mainbrd.jpg"><img src=
        "../../common/images/article251/dcpower-mainbrd_th.jpg" width=
        "200" height="167" alt="[main board]"></a> </td>
      </tr>

      <tr>
        <td>The case for the power supply. Wood on the sides, sheet
        metal for bottom part, top and front:<br>
        <a href=
        "../../common/images/article251/dcpower-box.jpg"><img src=
        "../../common/images/article251/dcpower-box_th.jpg" width=
        "236" height="158" alt="[box]"></a> </td>
      </tr>

      <tr>
        <td>The front panel:<br>
        <a href=
        "../../common/images/article251/dcpower-frontpanel.jpg"><img
         src=
        "../../common/images/article251/dcpower-frontpanel_th.jpg"
        width="243" height="99" alt="[front]"></a> </td>
      </tr>
    </table>
    The software package contains a postscript file
    (linuxDCpower.ps) for the printed circuit board. Personally I
    find that the pads are always a bit too small. Therefore I
    strongly recommend to enlarge them a bit with a paint marker
    before you etch the board. The process how to make a board at
    home is described in: <a href="../May2002/article236.shtml">May
    2002, A LCD control panel for your Linux server</a>. <br>
    How to build a cheap but good looking case for your power
    supply is described in the <a href=
    "../September2002/article253.shtml">"September 2002, Frequency
    counter 1Hz-100Mhz with LCD display and RS232 interface"</a>
    article. You can see the case and front panel that I made on
    the right. Click on the images for bigger pictures. 

    <h2>Testing</h2>
    Like any circuit that you have soldered together it is a good
    idea to not directly connect it to full power supply but rather
    test it step wise. This is to find faults that you have made
    while building the circuit. <br>

    <ol>
      <li>Assemble the main board with all the parts but do not put
      the ICs into the sockets.</li>

      <li>Take a 9V battery and connect plus to the pin 2 and minus
      to pin 1 on the connector marked in the schematic with
      AC_POWER. Use a voltmeter and check that you have +5V on the
      max232 between pin 8 and 16 and on the Microcontroller pins 7
      and 8. On the operational amps you should have almost 9V on
      the positive power pin.</li>

      <li>Now turn the 9V battery (pin 1 to plus and pin 2 to
      minus) and check that you have around -9V on the negative
      power pins of the operational amps.</li>

      <li>If all the tests until here are passed then the power
      supply of the main board works and it is save to insert the
      max 232 and the Microcontroller into their sockets.</li>

      <li>Use again the 9V battery and connect is such that you
      have the +5V supply working (see above). Connect the
      programmer cable to the parallel port and the connector for
      programming the board.<br>
      Unpack the software package (for download see references
      chapter), "cd" into the directory that is created and
      type:<br>
      make avr_led_lcd_test.hex<br>
      make testload<br>
      make ttydevinit<br>
      <br>
      Now the test software should be loaded to the board. On the
      LCD display you should see "hello", the red LED should blink
      and if you connect your computer to the rs232 you should see
      "ok" being printed (initialize the rs232 line with
      ttydevinit, then type cat /dev/ttyS0, or cat /dev/ttyS1 for
      COM2).</li>

      <li>Now assemble the power part but do not connect the main
      transformer yet. Instead connect the 9V battery to the cables
      where the transformer would be connected. No matter in which
      direction the battery is connected the 4700uF capacitor
      should always charge up to around 9V. Check this with a
      voltmeter.</li>

      <li>When the last test step is passed do some final checking
      of the wires and then connect all the transformers and power
      on. With no operational amplifiers in the sockets you should
      get the max. output voltage out of the power supply. Measure
      this but take care to not cause any short circuit otherwise
      you blow up the power transistors since there is no current
      limitation yet.</li>

      <li>Power down insert all the operational amplifiers and
      connect again the programmer cable, power on and type:<br>
      make<br>
      make load<br>
      </li>

      <li>Now the power supply should be fully functional. Note
      that while the programmer cable is still connected the output
      is slightly off. Disconnect it to get accurate output voltage
      and current.</li>
    </ol>

    <h2>Here it is: Our own power supply</h2>
    You have seen above that there are 3 options available
    dependent on what transformer you use. The default software is
    for 16V, 2.2A output. To change this edit the file <a href=
    "../../common/src/article251/linuxdcp_c.html">linuxdcp.c</a>
    and search for:<br>
    MAX_U, IMINSTEP, MAX_I, and in the function set_i you need to
    change the calibration if you have 3A maximum output. The code
    is well commented and you will see what you need change. <br>
    <br>
    Finally here are a few pictures of the power supply as I have
    build it. It was quite some work but it really is a very good
    and robust power supply. The time was well invested since a
    lab-power supply is really one of the most used things. <br>
    <br>

    <center>
      <a href=
      "../../common/images/article251/dcpower-final_frontview.jpg"><img
       src=
      "../../common/images/article251/dcpower-final_frontview_th.jpg"
       width="324" height="151" alt="[front view]"></a><br>
      <br>
      <a href=
      "../../common/images/article251/dcpower-final_topview.jpg"><img
       src=
      "../../common/images/article251/dcpower-final_topview_th.jpg"
      width="250" height="212" alt="[top view]"></a>
    </center>

    <h2>Using the power supply</h2>
    It is probably almost obvious how you use the power supply. You
    have 4 buttons to set the output voltage. 2 buttons to step
    up/down by 1V and 2 buttons to step up/down by 0.1V. The
    current limit can be set also with 2 buttons. Here the stepping
    is not linear. For smaller values you can increment or
    decrement by 50mA. For values over 200mA you can step in 100mA
    units and above 1A in 200mA units. That way it is easy to step
    through the whole range with just 2 buttons. <br>
    The standby button can be used to temporary switch off the
    power without the need to set the values again when you switch
    on. <br>
    The red LED will go on when you reach the current limit and it
    will blink in standby mode. <br>
    The power supply can also be totally controlled via ascii
    commands over the rs232 serial line. The following commands are
    available: 

    <p class="code">u=X set the voltage (e.g u=105 set voltage to
    10.5V)<br>
    i=Xmax set the max current (e.g i=500 sets the current limit to
    500mA)<br>
    s=1 or s=0 set to standby<br>
    u=? or i=? or s=? print the current settings. This will produce
    a printout that looks e.g like this:<br>
    u: 50 s:0 i: 100 l:0<br>
    u: means voltage=50 =5V, s:0 means standby off, i: 100 is
    100mA, and l:0 means current limit is not reached.</p>
    Using this acsii command language you could also write a
    graphical user interface for the power supply. To use the rs232
    line you need to initialize it first with the command
    ttydevinit. ttydevinit is included in the software package. This is
    also described in the <a href=
    "../September2002/article253.shtml">September 2002, Frequency
    Counter article</a>. 
    <p>As you have seen in the schematic diagram above we use 2 transformers
and the ground plane of the control logic is connected to the positive DC
output. The two transformers separate the voltages and there is normally
no problem with this setup. We need to connect things like that to have
the right polarity for the feedback loops of the operational amplifiers.
<b>A word of waring</b>: This setup means also that the ground line of RS232 line
is connected to the positive DC output! In other words you can not use the
RS232 line if you want to use the power supply with other parts that are
connected somehow to the ground line of your computer. It might be an
idea to put a label on the case of the power supply saying "ground line of
RS232 connection is connected to positive DC output line".
If you want to make sure that there is no way to cause a short circuit
through the ground wire of the RS232 line then either 
use a battery powered laptop or make sure that the ciruit powered
by the power supply does not have any other connections or do not
use the RS232 command interface. Also don't be too shocked by this
warning. If do not go above 250mA with the current limitation of
the power supply then the red led will tell you when you made a mistake
and there is no danger for your computer even if you did something stupid.
</p>

    <h2>Security</h2>
This circuit contains a transformer which is connected to
then main power supply (230V or 110V dependent on your country). Please
ensure proper insulation. If you have never worked with power supplies
then ask an experienced person to check your
circuit with regards to insulation and security before you connect the
first time.

    <h2>Tuning</h2>
    The software for the power supply is already calibrated. Most
    likely you will not have to change anything there. Hardware
    wise the calibration depends only on the 7805, R15, R10, R16
    and R38, R30, R26. Only those parts influence the voltage and
    current levels. If you want to do fine tuning you can either
    change those resistor or you can modify the software. Note that
    a connected programmer cable influences the output. Before you
    make measurements you should disconnect the cable. In software
    you can do the changes in the functions set_u and set_i. It's
    commented in the code of <a href=
    "../../common/src/article251/linuxdcp_c.html">linuxdcp.c</a> 

    <h2>References</h2>

    <ul>
      <li>The uisp AVR programmer software: <a href=
      "http://www.amelek.gda.pl/avr/">www.amelek.gda.pl/avr/</a><br>

       local copy: <a href=
      "../../common/src/article231/uisp-20011025.tar.gz">uisp-20011025.tar.gz</a></li>

      <li>How to build the programmer hardware and install the AVR
      compiler:<br>
      <a href="../March2002/article231.shtml">March 2002,
      Programming the AVR Microcontroller with GCC</a></li>

      <li>The source code for this article <a href=
      "../../common/src/article251/linuxdcpower-0.1.tar.gz">linuxdcpower-0.1.tar.gz,
      1201K</a> . The circuit diagram, the Eagle files and screen
      shoots are as well included.</li>

      <li>All software (updates will be listed here) and documents
      :<a href=
      "../../common/src/article251/">software/datasheets</a></li>

      <li>Datasheet for bd379 <a href=
      "../../common/src/article251/bd379.pdf">bd379.pdf
      44K</a></li>

      <li>Datasheet for TL082 <a href=
      "../../common/src/article251/TL071.pdf">TL082.pdf
      110K</a></li>

      <li>Datasheet for TL071 <a href=
      "../../common/src/article251/TL071.pdf">TL071.pdf
      268K</a></li>

      <li>Datasheet for 2n3055 <a href=
      "../../common/src/article251/2n3055.pdf">2n3055.pdf
      64K</a></li>

      <li>Datasheet for MAX232 <a href=
      "../../common/src/article236/MAX220-MAX249.pdf">MAX220-MAX249.pdf
      448K</a></li>

      <li>Datasheet for ST232, a cheap variant, often sold instead
      of the real MAX232 <a href=
      "../../common/src/article236/st232.pdf">st232.pdf
      100K</a></li>

      <li>Datasheet for Atmel AT90S4433 <a href=
      "../../common/src/article231/avr4433.pdf">avr4433.pdf
      2356K</a></li>

      <li>The atmel website: <a href=
      "http://www.atmel.com/">www.atmel.com/</a></li>

      <li>Eagle for Linux <a href=
      "http://www.cadsoftusa.com/">cadsoftusa.com</a></li>
    </ul>
    <!-- vim: set sw=2 ts=2 et tw=80: -->
  </body>
</html>