PWM Dimmer for LED Lighting

20160119_Projekte_046
Finished LED dimmer

I have recently moved to a new apartment and was looking for a PWM dimmer to control some 12V LED strips. I thought that should be easy enough nowadays but it proved more difficult than I thought. All I found either didn’t meet my requirements, were uggly or expensive. So I decided to build my own, tailor-made to my needs.

20160119_Projekte_044
Finished PCB mounted below a shelf

 The requirements

  • Handle 100W @ 12Volts comfortably
  • Controlled by a simple on-board pot (no remote control or the like)
  • Affordable
  • No acoustic noise
  • Fine-grained control down to very low brightness levels

I’ll go through these requirements one-by-one.

20160119_Projekte_040
Two LED strips below the shelf give a nice lighting on the desk

Handle 100W @ 12Volts comfortably

My LED strips suck up a bit more than 20 Watts per meter and there is a maximum of 4-5 meters of LED strips per dimmer so I need a power rating of around 100W. If you do the math you’ll find that there will be a maximum current of about 8.3 amps.

I don’t want this thing to get hot nor do I want to put a heat sink on it. So the total power dissipation in the dimmer should stay below, say, 1 watt. So if we use a single FET, we need a Rds-on of 14.5 milliohms. Thats not a lot but there are inexpensive MOSFETs that meet this requirement. And we can always parallel two or more of them if necessary.

And yes, there will also be some switching losses but they should be low given the modest switching frequency of an application like this.

20160119_Projekte_048
PIC microcontroller with its power supply

 Controlled by a simple on-board pot

This is most likely the simplest way of controlling a dimmer but it’s surprisingly hard to find. A lot of commercially available dimmers come with IR remote controls nowadays. And some of the higher quality models expect a 0-10V control signal which means that you have to use an external pot which you have to mechanically attach somewhere. I would like everything on a single PCB to keep things simple.

Affordable

I needed 3 of these things so cost was a factor, too. All the nicely-made dimmers I could find were priced at $50 and uppwards. Not that bad but I figured that I could make my own for a small fraction of this, perhaps $10.

No acoustic noise

We all know those dimmers that produce audible humming. Especially when dimmed somewhere half-way down. I hate it. Drives me crazy.

This proved to be more difficult to archieve than I thought. More on this later.

20160119_Projekte_054
Since the power supply has 4 output leads, my dimmer has a 8x connector at its input

 Fine-grained control down to very low brightness levels

This is where most products fail miserably. Most of those remote-controlled things only have 8 brightness levels. And just about everything I found works linearly which makes very little sense if you ask me. We humans perceive brightness logarithmically, rather than linearly. So going from 1% to 2% seems the same as going from 50% to 100%.

20160119_Projekte_050
Beefy mosfet and capacitor

Linear control will not give you fine control at the lower end. Ideally, you want to have an exponential transfer function from pot position to PWM duty cycle to compensate for the logarithmic nature of the human vision. I found the easiest way to do this was using a microcontroller. Furthermore, the ability to do all of this in software enables you to play around with it and find a transfer function that you’re happy with.

High granularity at the lower end also means that we need quite a bit of PWM resolution. The common 8-bit resolution translates to about 0.25% per step. Going from 0.5% (wich is about what I mean by very low brightness) to 0.75% is already quite a step. Many microcontrollers are capable of 10 bits which is 4 times better and probably good enough.

20160119_Projekte_045
Yet another view

The design

At the center of my design is a 8-bit PIC microcontroller, a PIC16F1936. There’s not much special about this particular model, it’s just a type I’ve used several times before and still had some on stock.

A LM2931 provides the PIC with 5 volts from the 12 volts input voltage. I use the LM2931 as my standard 5V regulator. It’s pin compatible with the legendary 7805 but survives input voltages in the range of -50 to +60 volts making it very robust against transients.

20160119_Projekte_051
A LM2931 generates 5V from 12V

The PIC controls a LM5111 dual FET driver that provides a powerful 12V gate drive to a pair of Infineon IPB136N08N3 N-channel MOSFETs. This is the same transistor that I’ve recently used for my Arduino Solar Charger Shield. Its an inexpensive (< $1), large SMD type with an exellent Rds-on of 11.5 mOhms.

There are several variants of the LM5111. It comes in inverting and non-inverting configurations as well as combinations of inverting and non-inverting. At Farnell, the the inverting ones were by far the cheapest so that’s what I’m using here. It doesn’t really matter since you can change the polarity in software as needed.

20160119_Projekte_053
Pot and one of the output drivers

Why am I using two FETs despite the fact that one could easily handle the entire current? First, I’m driving two LED strips with this dimmer and using two transistors simplifies the layout so I have two outputs exactly where I need them. Secondly, the LM5111 is a dual FET driver anyway so I get the second gate drive for free.

20160119_Projekte_049
Nice 2kOhm pot

I’ve provided each output with a generous 1.5mF capacitor in order to shield the supply from the ripple that is inevitably produced by the PWM. I’ve also taken care to use a cap with low serial resistance (ESR) and a high current rating. The Panasonic FR series fulfills both of these requirements while being good value for money. I thought this should be enough to avoid excessive ripple and therefore also acoustic noise.

20151129_Projekte_012
Top side of the long version

The input to the PIC comes from a quite nice 2 kOhms pot that I’ve recovered from some scrap. There is also a voltage divider to measure the 12V input voltage. The idea was to only enable the output once the input voltage has stabilized but I found this to be a quite unnecessary feature when programming the PIC.

20151129_Projekte_011
Bottom side of the long version

 The Layout

20151129_Projekte_008
Top side of the short version

I’ve built the two different versions of this dimmer. The schematic is exactly identical for both of them, they only differ in their physical layout and board dimensions. I’ve just tailor-made them to their specific application so the pots are located in a handy position and the outputs are exactly where I need them.

20151129_Projekte_009
Bottom side of the short verison

 Software and Testing

My first version of the software measured the voltage from the pot using the on-chip ADC and outputed an identical 2kHz PWM signal on both outputs. 2kHz should be enough to avoid visible flicker and seemed a reasonable choice. Everything worked but the power supply made quite a bit of noise over most of the brightness range. Worse than any commercial design. Even worse, there was an awful lot of flicker. Ouch.

Dimmer_2kHz_firstTry
Too much ripple producing lots of audible noise

Looking at the power supply output / dimmer input voltage on a scope if became clear that the two 1.5mF caps still allow too much ripple at this frequency.

The first thing I tried was running the two outputs out-of-phase. Since I’m using two FETs I have two independent outputs. So I can run them 180 degrees out-of-phase. Now, at  duty cycles below 50% it looks like I’m only driving a load half the size with a frequency and duty cycle twice as high. At precisely 50% duty the supply even sees a constant load at its output since exacly one LED strip is on at any point in time. At duty cycles above 50% the on-times overlap so the load only varies from 50% to 100% and with twice the frequency. As you can see from the scope screenshot below, this already helped a great deal but the problem was not yet resolved. So the natural thing to do was to increase the PWM frequency.

Dimmer_2kHz_phaseShift
Running the outputs out-of-phase helps

At 8kHz, things already looked (and sounded) much better. Ripple and acoustic noise were much reduced but the supply was still audible at least in a quiet environment.

Dimmer_8kHz
Increasing the PWM frequency to 8kHz almost solves the problem

So I moved the PWM frequency up as far as i could. Given the PIC’s 32MHz clock and a 10 bit resolution this was 31.25kHz. Now every last bit of audible noise was gone. Finally.

Dimmer_31kHz
At 31.25kHz all the noise is finally gone

I then noticed that the phase shift was 176 degrees as opposed to the intended 180 degrees.

Dimmer_PhaseShift_before
Phase shift is 4 degrees off

Not that this makes much of a difference in practice but I solved it anyway. I’ve implemented this phase shift by starting one PWM module at 128 and the other at 0 (we’re only talking about the 4 most-significant bits here, so the maximum is 255). The two instructions are on successive lines in my C code but 3 clock cycles are needed to process each of them so they are not enabled at the precisely same time. Starting the first PWM module at 131 has solved the problem as you can see below.

Dimmer_PhaseShift_after
Now the phase shift is fixed

With these changes in place the flicker mentioned previously was also much reduced but had not yet disappeared. Looking at the voltages on a scope for a while the problem became clear. I was measuring the voltage from the pot at fixed intervals that had no connection with the switching frequency. So I was effectively measuring at random points in time.

I said that the input voltage now showed much less ripple but some ripple is inivitable. Some of that ripple is likely to somehow feed through to the voltage from the pot. That introduced noise in the value measured by the ADC which lead to variations in the duty cycle which was noticable as flicker.

I did two things to resolve this. First, I’m generating an interrupt signal (from the same timer as I use for the PWM) every 64 PWM cycles. In the corresponding interrup service routine (ISR) I read (and save) the ADC value and start a new conversion. This way I’m always measuring at the same point during the PWM cycle. So the effect of the ripple should be similar every time. I’m also averaging 32 measurements which further helps to smooth the value I’m using to calculate the duty cycle. So flicker is gone as well as you can see below.

Dimmer_DutyCycle_stable
After averaging the ADC readings, the duty cycle stays rock solid

Now for the transfer function. My first try was exponential. The problem with that was that it gave away too much of the pot range for very low brightness levels. I played around with this for quite some time and finally settled for a combination of linear (at the very low end of the range) and exponential (for everything above that). Also, two of my dimmers can be fully turned off by turning the dimmer all the way to the left. Their power supply is always on and the light is only controlled by the pot so I need to be able to really turn them off (not only down). The third one has a slightly different transfer function that only allows to turn it down to 2% or so. That one has its power supply controlled by a conventional light switch so I don’t want the pot to completely turn it off.

Dimmer_DutyCycle_stable2
Same at lower duty cycles

 The result

After all, I’m very happy with the result. There is no noticable power dissipation on the board. There certainly is a bit of dissipation but the board doesn’t heat up noticably so I’d say its clearly below a watt.

The components have cost me around $10 per board. Some stuff like the connectors I have bought a flea markets, they can be surprisingly expensive through regular retail channels. The PCBs are home-made so they have cost me a considerable amount of time but not much in terms of cash.

20160119_Projekte_052
LM5111-2M is the inverting variant

They are, furthermore, controlled by a simple pot, produce no audible noise and can be finely dimmed just as planned. So I can proudly state that all the requirements have been met.

If you’re in need of a dimmer and have a soldering iron and a bit of spare time I can only encourage you to build your own. It’s not too hard, needs only few components and is very doable on a prototyping board if you don’t want to etch or mill your own board.

As always, attached is a zip file with all the eagle files, board layouts, schematic as well as the software.

Arduino MPPT Solar Charger Shield – Software

There have been two previous posts on this project: one on the concept and the hardware and one on hardware testing. You probably want to check them out first if you’re not yet familiar with this project. Or even better: Click here for an overview over this project.

20160212_Projekte_045
Maintaining an input voltage of 17 volts even if that means a lower-than-desirable voltage at the output

Now that we know that we have a functioning MPPT solar charger we are ready to talk about the software (or the sketch as the Arduino folks call it). It’s quite simple, really. So this will be a short post. And yes, you can download the sketch. There is a link at the end of this post. As always, I appreciate any feedback, comments and the like.

There is a number of basic tasks the arduino needs to perform in order for this shield to be useful. I’ll go through them one by one.

Controlling the DC-DC converter

At the heart of this project there is a synchronous step-down (or buck) DC-DC converter that is controlled by a PWM signal from the arduino. So one of the tasks is to set the frequency and duty cycle of that PWM signal.

We let the PWM signal run at the maximum frequency the arduino allows with an 8 bit resulution. Thats simply 16MHz (the Arduino’s frequency) divided by 256 (the 8 bit resolution), or 62.5 kHz. So the prescaler will be 1.

As you can see from the shields’s schematic, we need to output the PWM signal from Pin 6 (by the Arduino’s pin numbering, not Atmel’s). In order to do this kind of low-level stuff you’ll have to read the Atmega328’s data sheet. There is usually no Arduino-ish shortcut if you really need to controll what’s going on.

Luckily it’s just a few lines of code to set things up. All in the function buck_setup(). There are three more little functions to control the DC-DC controller once it’s set up:

buck_enable() and buck_disable() are very simple and just turn it on  and off, respectively. buck_duty(uint8_t duty) is only slightly more involved. It changes the duty cycle to the value you pass to it. Besides that it ensures that the duty cycle stays within certain limits.

20160212_Projekte_042
Test setup with resistor-based dummy load

You don’t want it to go to 100% since in order to keep the bootstrap capacitor C6 charged you need a little bit of off-time. In order to drive the upper FET you need a voltage higher than the panel’s voltage and that’s exactly what C6 is for. So we enforce an upper limit on the duty cycle.

Likewise, you don’t want your duty cycle to go below 50% because in that case you would be pumping energy from the battery to the pannel. A synchronous step-down converter is basically the same thing as a synchronous step-up (aka boost) converter with input and output confused. So we also want to enforce a lower limit on the duty cycle.

The upper and lower limits are set through the #defines DUTY_CYCLE_MINIMUM and DUTY_CYCLE_MAXIMUM.

Measuring voltage and current

The shield has all the hardware necessary to measure both voltage and current both at the input as well as on the output. We’ll just need to write some simple software to make good use of that hardware.

Unlike with the PWM singal where we had to do some low-level bit fiddling ourselfs we can just rely on convenient Arduino library functions to do the job. Basically, analogRead() is all we need here.

20160212_Projekte_043
Nicely regulating so that the input stays at 17 volts

I’ve written a function called read_values() that uses analogRead() to read all 4 values (input voltage, output voltage, input current and output current) 16 times each, averages the results and converts the ADC reading to proper voltages and currents.

The necessary multipliers are defined as floats in VIN_MULTIPLIER, VOUT_MULTIPLIER, IIN_MULTIPLIER and IOUT_MULTIPLIER. I’m doing all the voltage and current measurements in floating math. Yes, this is not at all efficient but we don’t need the Arduino’s computational power for anything else most of the time so this is fine here. Just keep in mind that you can save a lot of resources here if you ever need to do so.

Displaying voltage and current on the LCD

Our hardware also involves a 2 lines x 16 characters LCD so we can show the world what we are measuring. Again, we can rely on standard Arduino functionality to do the job. There is an LCD library that does everything we need.

So my function write_display() can focus entirely on formatting. The upper line shows the voltages in Volts, the lower line shows the currents in Milliamps. The input is on the left hand side of the display, the output on the right.

Deciding what to do

In the first section we’ve discussed the functions necessary to controll the DC-DC converter. But in order to use those functions, the Arduino needs to first decide what to do.

Vin21
66% duty cycle at 21V input voltage gives the desired 13.8V at the output

This is where the function buck_update() comes into play. You could consider this the heart of this sketch. This is where all the relevant decisions are made. When to turn the converter on, when to turn it off, when to increase the duty cycle, when to decrease it… You get the idea.

The behaviour of buck_update() is controlled by 8 #defines. I list them here together with the values I have used:

#define ENABLE_VOLTAGE 18.0
#define DISABLE_VOLTAGE 15.0
#define INPUT_TARGET_VOLTAGE 17.0
#define OUTPUT_TARGET_VOLTAGE_LOW 13.8
#define OUTPUT_TARGET_VOLTAGE_HIGH 13.9
#define INPUT_CURRENT_LIMIT 2000.0
#define OUTPUT_CURRENT_LIMIT 3000.0
#define INPUT_CURRENT_MINIMUM 0.0

I think they are quite self-explanatory, especially if you look at how they are used inside buck_update. It’s quite simple: If the panel’s voltage rises above 18V, turn the converter on. Once the converter is on, try to archieve a panel voltage of 17V without exceeding 13.9V at the output. If the panel’s voltage drops below 15V turn the converter off again.

Vin17
At 55% duty cycle with a 16.9V input voltage we’re getting only around 9.2V at the output

Besides that the function is also looking at the input and output current and makes sure certain limits are not exceeded. But with a 30W panel it should never be possible to reach those limits anyway.

Putting it all together

Now all we need to do in the loop() function is calling read_values(), buck_update() and write_display(). Since writing to the LCD is quite slow we are only doing it every 32nd time we read the values and update the PWM signal.

With this sketch I’ve hooked the MPPT Solar Charger up to my lab power supply. (a Keysight E3645A, my newest toy *g*) and my extremely simple but occasionally useful resistor-based dummy load.

The enable and disable voltages are simple and work as expected. Maximum output volage is also not tricky. If the voltage at the output goes too high, the duty cycle is decreased and everything is fine again.

20160212_Projekte_041
There’s not much to photograph when you’re writing and testing software

More interesting was to see how the shield would regulate when faced with a limited current budget at the input. For that the supply was set to a voltage of 21V (about a 12V solar panel’s open-circuit voltage) with a current limit of 100mA to 500mA. That’s quite a nasty supply, quite a bit trickier to handle than a real solar panel. Try to pull just a bit too much current and the voltage will drop to zero…

Also, the resistors at the output are not a realistic load for the converter. A car battery will pull no current at 12 volts or so (unless overly discharged) but will quickly start to sink large currents when the voltage goes just a bit higher and the battery is charging.

But I think the setup is good enough to test the sketch. And it handles the challenge quite well. With all resistors on (i.e a 100/6 ohms load) and a 300mA current limit, the input voltage sits at 17V (our target input voltage) while 9.25V appear at the output. At 400mA, the output voltage rises to 10.7V with the input still at 17V. At 600mA the input is still at 17V but with the output now at 13.15V. If I take the current limit even higher, the output voltage rises to 13.82V but not any higher, just as we want. The input voltage rises to 21V (since this is a lab supply and not a panel) with a corresponding drop in current to 530mA.

20160212_Projekte_044
Quite realistic: The charger is pulling as much current as it can with the current limit at 530mA and reaches an output voltage just above 12 volts

I’m honestly quite happy with the project as it is now. The idea definitely works and I’m motivated to design a new, deployable version with some fancy features that will use much less power at the same time. I’ve already done quite some work on that new version but it will take another few weeks until I get to describe that project here.

Until then I will show you some other, smaller projects that I’ve already finished but didn’t have time to document yet. So you will first see a number of smaller, simpler projects over the next few weeks.

Before I forget: There’s the Arduino sketch for download. And click here for an overview over this project.

Arduino MPPT Solar Charger Shield – Testing

20160203_Projekte_004
First tests are being performed on the Solar Charger Shield

In my last post I’ve introduced a proof-of-concept Arduino solar charger shield. I went through the hardware as well as the way it works – or at least is intended to work. It was prominently linked on dangerousprototypes.com as well as some other sites and got quite a bit of publicity as a result. Thank you all for sharing this post.

By the way: here’s an overview over all posts on this project.

20160203_Projekte_001
DUT hooked up to my Constant Current Dummy Load

This time I’ll show you some results of the testing that I’ve done. The basic test setup is shown above: The solar charger is hooked up to my home-brew constant current dummy load, together with a pair of DMMs at the output in order to precisely monitor output voltage and current. For the input I’m relying on the lab supply to provide these measurements. And yes, the shield does its own measurements of both input and output currents and voltages. Once calibrated they are even quite accurate but I won’t rely on them for things as calculating the converter’s efficiency.

no_load_overview
Vin=17V, no load

But first we need to see if our converter works at all. As the scope screenshot above demonstrates – it does. For all the tests shown in this post, the input voltage was provided by a lab supply set to 17 volts. So we’re not yet testing the software and its capability to draw just the right amount of current.

no_load_closeup
Vin=17V, no load

As you can see, since the converter can draw any (reasonable) current at the input, it provides the maximum voltage (set in software) of 13.8V at its output. In order to do that, the upper FET is on approximately 80% of the time. The signals all seem nice an clean and there is no noticable ripple at the output at 1V/div and no load. And the switching frequency is 62.5kHz (16MHz / 256) as expected.

1Amp_closeup
Vin=17V, Iout=1A

At 1 Amp output current, the software has to increase the duty cycle somewhat to 82% (above) and even further to 84% at 2A (below). Besides that, everything still looks very similar under load conditions.

2A_closeup
Vin=17V, Iout=2A

In my last post I’ve raised the question if the FET driver’s dead time of 540ns according to the datasheet is not a bit excessive. Well, let’s look at the dead time on the scope. First of all we can observe that the dead time of the IR2104 is in line with the data sheet. I don’t have it in front of me right now to check the min/max specs but the measured 522ns seem reasonably close to the theoretical 540ns.

deadtime
The IR2104 has a built-in dead time of 540ns according to the data sheet. We’re measuring 522ns here – close enough.

From looking at the screen shot above, the dead time does seem a bit long. The reason dead time is introduced is to prevent shoot-through. If both FETs are on there is a short-circuit from the input to ground. Together with the input capacity and the FETs low Rds-on, very large currents could flow, possibly destroying the FETs and at least detoriating efficiency. So introducing a bit of time when both transistors are off seems reasonable. But too much of it also costs efficiency since current has to flow through the diode instead of the lower FET. The main reason for using a synchronous topology is to prevent this in order to gain efficiency. So obviously one has to find a balance. I think here we’re a bit far on the conservative side but never mind for now.

20160203_Projekte_005
Let some current flow

So now that our converter is working, let’s take a look at efficiency. I’ve measured the efficiency at output currents ranging from 100mA to 2.6A in 100mA steps with the input voltage at 17V. I didn’t use the sense-wires connections on the lab supply so I had to compensate for the voltage drop on the input leads manually.

20160203_Projekte_007
There was a drop of up to 220mV on the input leads so the voltage reading of the lab supply is not quite accurate

The results are quite impressive:

  • 95.5% @ 100mA (worst)
  • 96.9% @ 200mA
  • 97.9% @ 400mA
  • 98.1% @ 800mA (best)
  • 97.1% @ 1600mA
  • 95.7% at 2600mA

So the efficiency is constantly at a very high 95.5% and better over the entire current range of interest.

20160203_Projekte_008
This little dummy load is really useful

The resulting loss is less than 1.6 Watts @ 2.6A out. As a result, the shield never gets hot, even when running at this power level for a while.

Note that this is quite a bit more power than the converter was designed for. 37W as opposed to the 30W I designed it for. The FETs could even handle much more. The limiting factor would likely be the coil reaching saturation. Unfortunately my lab supply doesn’t supply any more than 2.2A so I can’t push it any further.

20160203_Projekte_006
Shield performs well even beyond 30W spec

 

One thing to note is that these efficiency figures don’t take into account the power consumed by the arduino, the display, the fet driver, current monitoring ICs and so on. This brings us to the last topic for now: The current consumed by the various components. I did these measurements mainly in order to understand how to limit power consumption in a later version. To me, this shield is only a proof of concept and so reducing power consumption was never an issue.

20160203_Projekte_002
Basic test setup

Here are the results:

  • Arduino: 48.7mA
  • LCD backlight: 8.9mA
  • LCD excluding backlight: 1.148mA
  • FET driver (standby): 106.56uA
  • FET driver (62.5kHz, Iout=0): 2847uA
  • FET driver (62.5kHz, Iout=2.5A): 2937uA
  • Current sensors (each): 48.6uA

So the arduino itself is using up the lion’s share of current. Next comes the LCD backlight. Nothing unexpected so far. The LCD without backlight still consumes a considerable 1.15mA, no matter if it’s on or off. The FET driver uses around 2.9mA when on and only about 0.1mA when off. Output current only has a minor impact. The current sensors don’t use up much – less than 0.1mA for both.

Check out my next post for a closer look at the software or here for an overview over this project.

Arduino MPPT Solar Charger Shield

20160119_Projekte_028

A friend has approached me regarding his solar project. He wants to install a solar panel together with a battery and an inverter in order to have power at his allotment garden. He had looked at a hobbyist project where an arduino was used to build a MPPT (maximum point of power tracking) charge controller. I took a look at the design, liked a lot of what I saw and decided to build something similar.

20160119_Projekte_032

The basic idea behind an MPPT solar charger is simple. A solar panel has a certain voltage (in the region of 17 to 18 volts for a 12 volts pannel, somwhat dependent on temperature) at which it provides most power. So as long as the battery needs charging, you want to pull just as much current to reach this voltage. But once the battery is full you need to avoid overcharging the battery. So you want to maintain a maximum voltage for your battery (somewhere around 13.8 volts for a 12 volt lead acid battery) and no longer care about the pannel’s voltage.

20160119_Projekte_029

So the charger needs to convert an input voltage of 17-18V to an output voltage of 12-14V as efficiently as possible. Obviously, a step-down (aka buck) switching converter is ideally suited for the job. However, a typical DC-DC converter is designed to maintain a stable voltage at it’s output, independent of it’s input voltage. As described above, our requirements here are different.

20160119_Projekte_038

Switching converters are controlled by the duty cycle of a (typically) fixed-frequency PWM signal. So a microcontroller could be used to do the job. In most applications, this wouldn’t work that well because a microcontroller would be too slow to react to sudden changes in load or input voltage. But this is not much of a concern in our solar application: Sun intensity changes within seconds at best and the battery will absorb any sudden changes in load. So if we adjust our duty cycle a few times per second we’ll be more than fine. And that’s easy to do with a microcontroller.

20160119_Projekte_030

The next step was to figure out at which frequency to run our converter. An arduino runns at 16MHz. At a 8-bit resolution, this gives us a maximum PWM frequency of 62.5kHz. That’s a pretty slow speed for a switching DC-DC converter nowadays. Most modern designs run in the hundreds of kHz to a few MHz. The main reason of using higher and higher switching frequencies is size. The higher the frequency, the smaller the inductor can be. For us, using a somewhat bigger inductor is totally acceptable. And in terms of efficiency, a lower frequency is even preferable since it reduces switching losses.

20160119_Projekte_037

The project here is intended mainly as a proof on concept. I expect it to be fully functional but it will consume quite a bit of power while sitting idle. The display (including backlight) is always on, the same goes for all the other components. But the main drain on the battery will be the Arduino itself which consumes around 50mA when running at 16MHz. That might not sound like much but it will add up during the many hours the solar panel doesn’t produce any power. The system will be installed in Zürich, Switzerland so you can’t count on having 8 hours of sunshine every day. In winter, there might be snow on the panel, preventing it from producing anything for weeks in an extreme case. So a productive system should draw hardly any current (say <1mA) when not doing anything useful.

20160119_Projekte_031

At least for now, the we’ll be using a 30W 12V monocrystaline panel and a 45Ah car battery. So I’ve scaled this converter to comfortably handle 30W input power which translates to about 1.8 amps at the input and 2.5 amps at the output.

As deba168’s design, I’m using a synchronous buck topology. If you’re new to switchers, you might want to check out this wiki page. If you’re serious about designing your own you might want to read Sanjaya Maniktala’s ‘Switching Power Supplies A – Z’, it’s a great book. I’ve also read his other two books on the topic but this is the one I love the most, especially to start with. I’m also using the same half bridge driver (IR2104) even though I find the 540ns off time somewhat excessive. But I like the enable/pwm input signals as opposed to having to drive each fet individually and I found this feature to be somewhat rare.

20160119_Projekte_035

Apart from that I’ve really done my own design, mainly using parts I’ve still had from previous projects. As most stuff I build, it’s entirely SMD, except for the input and output capacitors. Not only are SMS designs smaller in size. The parts are much easier to source (and often cheaper) than conventional through-hole components nowadays. And contrary to popular belief, with a bit of practice I find them easier and faster to solder.

The FETs are IPB136N08N3, a quite large surface-mount type that I use quite frequently. They have a 11mOhms Rds-on resistance which will be great for efficiency. They are also easy to drive in terms of gate capacitance. Probably a bit oversized for the 2.5 amps we’re trying to switch here but I still have some here and they’re not expensive, around 70 cents each. The inductor is a 100uH Coilcraft MSS1583 with a resistance of 0.103 ohms and a 2.8A current rating. 100uH is a bit much at full load, 68uH would easily do. But the system will spend most time at moderate loads (remember, this is not California). I’ve ordered a 68uH as well and intend to use it for a later design or maybe to see what difference it makes. Input and output caps are quite a bit oversized as well, 680uF 35V at the input and 820uH 25V at the output. They are from the Panasonic FR series which I like using for my switchers since they work well at frequencies up to a few hundred kHz while being afordable and having very high ripple current ratings.

20160119_Projekte_034

I’m doing voltage and current sensing at both input and output. I’ve decided to use conventional high-side, shunt resistor based current sensing. The Texas INA213 are fairly precise, work up to 26 volts and have a fixed gain of 50. Also here, I still had some left over from my dummy load project. Most components are much cheaper if you buy 10 in stead of just one or two so I tend to buy 10 😉

I’ve also added a standard 2×16 characters LCD display so I can see what’s going on. And you may have noticed that I’ve put a zero ohms resistor at several places. This will enable me to easily measure current consumption of the respective sub-circuit. As mentioned before, current consumption will play a major role in the final design so I’m interested to see how much juice is used by certain components under real-life conditions.

Besided the connectors for the panel and the battery, I have added a separate connector for the power supply. This is handy for early testing and programming. Just connecting this supply will power up the entire system. The arduino, the display, the converter and all. But there is not yet any load at the converter’s output and no supply at it’s input. So I can start programming the Arduino, start measuring and displaying voltages and currents and even turn on the converter to see if everything behaves as expected. And since there is nothing at the converter’s input and output, not much can go wrong. I don’t risk blowing up the FETs due to a bug in the program or a problem with the board. Only once I’m confident that everything works as expected I will connect a panel and a battery. At that point, the 12V input can just be connected to the battery as well.

20160119_Projekte_039

I’ve written a simple sketch for the Arduino that measures voltage and current at the input and output and displays the result on the LCD. Once the input voltage exceeds a certain threshold, it will enable the half bridge driver and start switching. It starts at a duty cycle that will produce an output voltage equal to the current battery voltage. That means that no current will flow to the battery yet so the converter can start up with no load. Once the switcher is turned on, the Arduino will adjust the duty cycle about 4 times a second. If the input voltage is above its optimum and the battery has not yet reached its maximum voltage, the duty cycle will be increased by 1/255. If either the battery voltage is too high or the input voltage is below its optimum, the duty cycle is decreased by 1/255. There are also some checks for overcurrent at the input and output.

20160119_Projekte_036

The switcher is turned off when the input voltage or the output current falls below a pre-defined threshold. This is a synchronous converter so current can flow back from the battery to the panel. We can’t just wait for the input voltage to fall. As long as the switcher is on, the input will never fall because energy is pumped from the battery to the panel. A synchronous buck converter is just the same as a synchronous boost converter with its inputs and outputs inverted. So we need to make sure current is actually flowing to the battery. Luckily, a car battery will always draw a clearly non-zero current at 13.8 volts, even when fully charged. So when current stops flowing to the battery, we know the panel is no longer able to provide any power and we can or rather must turn the converter off.

20160119_Projekte_033

This post ist getting rather long so I’ll stop here and will write another post later about how the circuit has been performing and what I have learned so far. I guess this project will turn into a little series, maybe with further (and hopefully improved) versions being developped. Looking forward to that.

Before I forget: Here’s the eagle files as well as schematic and layout PDFs as a zip file: SolarCharger_Rev1.

Update: Click here to see how the shield performs or here for an overview over this project.

USB Boost Converter

_MG_1042
Finished 5V to 12V USB boost converter

I frequently need a low-power supply to run a microcontroller system. Typically, one uses a lab power for such purposes. But at least on the desk where I do the programming I don’t have one. Since these systems typically consume little current it would be handy to be able to power them from USB. Most of my devices have on-board regulators so the voltage is rather uncritical. For 3.3 volt devices, the 5V from USB is just right. But others have a 5V regulator so they need a higher supply voltage. And even others might even need 12 volts.

_MG_1035
Fully assembled PCB

So I decided to build a small low-power boost converter with a USB plug on its input. The output voltage is set by a pair of resistors. So once built the output voltage is fix but my idea is to build several of them anyway. So some will produce 12V while others will produce 7.5V. The latter is intended to power all those systems with on-board 5V regulators. Of course, you could use a trimmer or pot if you wanted a variable voltage version. However, the feedback loop requires a capacitor for stability and its value also depends on output voltage. You might well find a value that results in stable operation over a say 6 – 12V range, but I haven’t tried that.

_MG_1015
Bottom side

I had a look for a suitable integrated switcher IC and found the Texas Instruments LMR62014. It comes in a small SOT23-5 package. It switches at a high frequency of 1.6MHz which will keep the other components small, too. It switches up to 1.4 amps. It’s easy to use. And even afordable, around 1.50 a piece. The datasheet is very helpful when it comes to PCB layout. It includes a two-layer sample layout that works even with hobbyist-sized components (0805, 1206 for the input and output capacitors).

20141115_173315
Not a bad heat sink

Generally, layout is important with switch-mode DC-DC converters. Their operation requires switching square-wave power signals (as opposed to just logical-level signals where little current flows). And that requires careful layout in order to minimize stray inductance, mainly. Things are more forgiving when you work with relatively slow (say 100kHz) switchers but get much more demanding when switching at higher frequencies. There has been a steady trend to ever-higher frequencies and 1.6MHz is fairly high even by 2015 standards. So I was very happy to have a nice layout example to start with.

_MG_1014
Top side

As you can see from the photo above, the thing is small, only 26 x 14mm. Also note how the layout makes the components magically fit together without any long traces and few vias.

20141115_173232
Home brew constant current dummy load in action

So far, I’ve built two units, one running at 12V, the other at 7.5V. Theoretically, one should be able to pull 580mA and 930mA from them, respectively. Of course, these are theoretical figures assuming no losses. Also, the 1.4A rating on the IC is likely the current limit at the top of the switching cycle (the datasheet will tell you or course but I don’t have the PDF open right now), not an average. And thermal considerations might also put limits on continuous currents. More on that later. And don’t expect to be able to pull 1.4A from a random USB port (which would violate the USB specifications anyway). But given my use-case for these things I’m entirely happy if I can pull a 100mA or so. And that should work comfortably.

20141116_144615
Switcher IC: 70 degrees @ 200mA
20141116_144627
Diode: 58 degrees @ 200mA
20141116_144553
Coil: 50 degrees @ 200mA

I’ve pushed both versions to their respective limits on the bench, using a stiff 5V supply and my home-brew constant current dummy load (link). With case temperatures approaching 100 degrees centigrade I was able to pull around 250mA of continuous current from the 12V version. The ICs include thermal limiting so you don’t need to worry too much about damaging them when performing this kind of tests. As you can see on the photos, I did these tests with the naked PCBs sitting in a vise which probabely made a not-so-bad heatsink for the board as a whole.

20141116_144738
Output voltage folds back when the switcher gets too hot

I’ve encountered slight stability problems with the 12V version (but not with the 7.5V one). There is some oscillation at currents above 200mA or so. Changing the value of the compensation capacitor changed the frequency and amplitude but I haven’t managed to get rid of it entirely. But anyway, I won’t run them at 200mA so I haven’t put much more effort into this.

_MG_1045
Close up of the final product

The finished units have a USB wire on the input and a arduino-compatible plug on the output. To protect against short-circuits I’ve put them in a piece of shrinking hose which is a bit of a themal nightmare of course. There is also a voltage drop over the USB cable which means the input voltage seen by the converter is below 5V even with a perfectly stiff USB port. Which in turn means more work for our converter, making things worse.

_MG_1040
Shrinking hose doesn’t help in keeping it cool

I have frequently used the 7.5V version to power my Ultrasonic Anemometer which pulls around 60mA. That’s the kind of application that I had in mind for this little device and it works well for that. It hardly gets warm at all and provides reliable power on my desk without the need for a lab power supply.

Attached the Eagle files as well as a PDF of the schematic and layout: USB_BoostConverter

The Art of Electronics – Third Edition

20150407_211427

The world has been waiting since 1989, now it’s finally here. The 3rd edition of the classic book The Art of Electronics by Paul Horowitz and Winfield Hill is finally out. My (Amazon.de pre-ordered) copy just arrived today.

20150407_211501

It’s slightly disappointing in size. It quite matches the 2nd edition and grew only about 50 pages in volume. Haven’t really had time to read any of it or compare the table of content.

20150407_211405

Feel free to leave any of your impressions on this or the last edition in the comments below.

Update as of August 4th, 2015

I’ve finally found the time to read the first 300 or so pages of the 3rd edition. Some of the material is very familiar to readers of the 2nd edition. But there is plenty of stuff that was not yet part of the 2nd edition. Such as a very comprehensive coverage of JFET amplifiers. Other chapters have disapeared entirely such as the one on high frequency / RF circuits. In my opinion it makes perfectly sense to own and read (!) both editions. And there is a second volume (called the AoE x-chapters) to be released at some time in the future (another 30 years?) . I’m looking forward to it.

Arduino Ultrasionic Anemometer Part 14: Wind Tunnel Testing

It’s been a while since I posted the last update on the anemometer project. The reason for this is that I’m struggling with the aerodynamical design.

By the way: Click here for an overview over the ultrasonic anemometer project: http://soldernerd.com/arduino-ultrasonic-anemometer/

For my very first tests I had misappropriated my wife’s hair dryer to generate some wind. Of course the results wereneither reliable nor repeatable so I built myself this ghetto wind tunnel:

_MG_1235

It’s basically a 120x120mm square tube, made of cardboard and about 1.4m in lenght.

_MG_1239

It’s powered by a powerful 120mm size brushless fan drawing some 2.25 amps at 12 volts. I don’t know about the air throughput but it generates a loooot of wind for a fan this size.

_MG_1240

The legs put it at the right height for the anemometer prototype. There are two holes at the bottom through which the anemometer’s arms can be inserted. The transducers are then nicely centered inside the cardboard tube.

_MG_1242

I can regulate the fan speed using a simple LM317-based regulator. It might look familiar to some of you, it has it’s own post here: http://soldernerd.com/2014/11/10/variable-voltage-power-supply-using-a-lm317/

Unfortunately, the LM317 is only good up to 1.5A so I have to connect the fan directly to my 12V supply in order to run the fan at maximum speed.

As you know, the main indicator of wind speed is the phase shift between the transmitted and received signal. The distance is 0.21m and speed of sound is approximately 340m/s so with no wind, the signal travels about 618us. Signal frequency is 40kHz so one full wave corresponds to 25us. So a full wave (or a phase shift of 360 degrees) translates to a wind speed of around 14m/s or 50km/h.

Note that we usually calculate the difference in phase shift measured forth and back.In that case, the signal already repeats at half that wind speed or 7m/s.

Now my impression was that I don’t get nearly as much phase shift as I should. What makes this difficult is that I don’t know the true wind speed so maybe the wind is just not as strong as I think it is.

I went back and checked my code but didn’t find any bugs there. So I attached the scope to the transducers and looked at the signals directly. And the scope confirmed what I saw on the LCD display. So if there’s a good news it’s that both the electronics as well as the code seem to do what they should: They faithfully report what they get from the ultrasonic transducers. So maybe it’s just the physical design of my prototype that poses too much resistance to the wind and therefore causing too much of a dead wind effect.

I have done some more testing and will follow up on this shortly. Maybe some of you have a piece of advise for me…

Free Inductance Meter PCB – first come, first served

_MG_1211

When I made the PCB for the stand-alone inductance meter, I erroneously used a  SSOP footprint for the microcontroller (instead of the desired SOIC). The PIC is available in a SSOP package (PIC16F1963-I/SS instead of PIC16F1936-I/SO) but I didn’t have any at hand so I simply made a new board with a SOIC footprint.

_MG_1205

Apart from the footprint, the SSOP board is identical to what I’ve finally used and is fully functional. If anyone is interested I’m happy to give it away for free – first come, first served.

_MG_1213

By the way, I’m building a second inductance meter for my father who has asked me if he could get one, too. It’s technically identical but this time the 3D-printer had orange PLA in it so I used just that.

_MG_1218

_MG_1216

_MG_1219

By pure coincident, the color just about matches the newer Agilent / Keysight multimeters 😉

_MG_1223

Stand-alone Incuctance Meter Finished

If you’ve read my last post you’re already familiar with my Inductance Meter project: http://soldernerd.com/2015/01/14/stand-alone-inductance-meter/. At that time the hardware was ready but there was no software yet. That’s been corrected, the inductance meter is now fully functional.

_MG_1183

From a high-level point of view the new software is very similar to the Arduino sketch I wrote for the Inductance Meter Shield (http://soldernerd.com/2014/12/14/arduino-based-inductance-meter/). If you look a bit closer, you’ll notice some differences for several reasons:

  • This project uses an entirely different microcontroller: A PIC 16F1936* instead of the Atmel Atmega328
  • This code is written in C (for the MikroC for PIC compiler by Mikroelektronika), not Arduino-style C++
  • The display I’m using here comes with a I2C interface rather than the familiar Hitachi interface

*: In an earlier version I wrote 16F1932 instead of 1936. Thanks to Ralph Doncaster for pointing this out to me. By the way, Ralph has his own blog at http://nerdralph.blogspot.ca which I regularly enjoy reading.

_MG_1190

I’ve noticed that the MikroC compiler is not very popular among hobbyists but I like using it. It’s entirely free as long as your compiled code does not exceed a certain size. You can use any features, any library, just anything for free when you’re getting started. Yes, once your projects get bigger you’ll run into the limit and will have to buy a license but it was worth the price to me.

_MG_1193

As expected, the I2C display took me some time to get used to. It’s a MIDAS MCCOG21605B6W-BNMLWI (Farnell:    2063209). It seems to use a Hitachi-compatible controller with a I2C interface built on top of it. I like the concept and will probabely use one of these again. If there is a downside, it’s the data sheet. I had to do quite a bit of guessing and trial-and-error to get it working. I had used Hitachi-compatible MIDAS displays before so I had some idea what might work otherwise I might have given up. Examples?

  • No page numbering. Yes, this is a minor thing but have you ever seen a data sheet without page numbers?
  • There is a reset pin. As many reset pins, it’s active-low. But the data sheet never says so. Not explicitly, not with a bar accross the RST, not with a ~RST. Absolutely nothing.
  • It explains some of the Hitachi-functionality in great detail but does not really tell you that this functionality is not accessible over the I2C interface.
  • Like Hitachi-compatible types, this display needs some start-up time before you configure it. Otherwise it will just not work. But the data sheet doesn’t mention that with a single word.

_MG_1188

But it’s all working fine now. The PIC16F1936 has more than enough ROM, RAM and processing power for this meter so don’t expect the code to be optimized in any way. It was just not necessary. It does most of the math in floating-point which bloats the (compiled) code size and is dead-slow on this kind of architecture but it’s still more than fast enough and only uses around half of the available RAM and ROM.

_MG_1202

I think the code itself is quite readable but don’t hesitate to ask if you have any questions. Here’s the code as zip: LMeter _MG_1192

DIY Electronics