Fixing the Arduino’s PWM

The LED Node presented a few days ago, with the software to drive it, has exposed a nasty little problem…

The light has a slight periodic flicker.

Not good, in fact this gets pretty irritating fairly quickly. But how can this be? Each of the RGB colors is dimmed using the ATmega’s hardware PWM, after all – and well above the 50 Hz rate which our eyes could detect!

Luckily, I recently borrowed a oscilloscope from a friend which allowed me investigate this further. This is a Rigol DS5062CA, a predecessor of the popular DS1052E.

So let’s dive in, shall we?

Channel 1 is tied to the PWM output driving the MOSFET for the green LEDs, and likewise channel 2 is for blue. There is little point in connecting to the PWM for the red LEDs, because these were driven 100%, i.e. not pulsed. The output color is sort-of-warm-white for the PWM ratios used for this test.

The first surprise was the PWM cycle frequency, which turns out to differ for these two PWM channels. The blue LED’s PWM pulse cycles at twice the rate of the green LED’s PWM (shown as yellow trace).

Ah, but wait… it’s not an exact multiple!

This is very easy to see while the scope is auto-triggering, because no matter how I set it up, I can only get one of the channels to stabilize. The other one always keeps moving, meaning that its phase is constantly changing.

The scope has some measurement options, and as you can see the PWM frequencies are not exact multiples (actually, this readout was a bit erratic – sometimes the frequency did get reported as exact multiple).

So what’s happening, is that there is sort of a Moiré effect between the different LED colors, and the difference is small enough that it manifests itself as a slight but very annoying flickering of 1 or 2 Hz, roughly.

I’ve been using analogWrite() to set these PWM values, but it now looks like I’ll have to change the setup and configure the timers and PWM outputs myself. Surely there’s a way to make all the timers count at the same rate?

Here’s another check I did:

In this snapshot, channel 1 is the same as before, i.e. the PWM output for the green LEDs, while channel 2 is the power supply voltage (AC-coupled, i.e. only showing the fluctuations). You can see how the green LEDs pull the 12V down when turned on, with the blue LEDs presumably pulling it down further twice as often.

Again, the scope’s measurement capabilities come in handy to see the scale of these variations. Nothing extreme really, although I might add a fat capacitor to try and dampen them. I suspect that the combination of the out-of-sync PWMs and these slight power level fluctuations are what’s causing the visible flicker.

As you can see, a Digital Storage Oscilloscope (DSO) – even a basic one! – can be a fantastic diagnostic tool.

There is one more issue with these RGB LED strips:

If you look closely, you can see that the left side is slightly more yellow and the right side slightly more red. Which is odd, because both strips are driven from the same LED Node, for a total of 5 meter. My explanation for this is that the ≈ 1000 Hz PWM rate, especially the short blue pulses, are being dampened by the strip’s inductance while traveling from the LED Node’s MOSFETs through the left strip to the right strip.

I haven’t tried it, but one way to verify this would be to compare the power signal of the blue LED at the start and at the end of the LED strip. If my theory is correct, then the pulses should look different.

It’s a small effect, but it shows, and I don’t like it at all. I’ve got two ways to solve it, I think: 1) feed the PWM power signals separately to both LED strips, or 2) use two LED Nodes, each directly feeding their own LEDs.

Maybe it’s just the +12V supply line, in which case it’d be enough to connect +12V to the end as well. We’ll see.

Finicky things, them RGB LED strips!

Update – I’ve placed the LED Node between both strips. Color differences are now almost gone, but there’s still a shift-to-red towards the ends, i.e. the high PWM frequency is hampered by signal propagation.

I’m working on a similar RGB LED project. Haven’t built the thing yet (apart from 3 LEDs stuck in JeeNode ports), but I did modify wiring.c (defined as a separate board in the IDE) to put the involved timers in phase correct PWM at ~122Hz (less inductance/capacitance), and put the clock (millis() and friends) on timer 2 (where it should have been in the first place).

I still have to build it to see if it actually works :) (clock works fine though).

Don’t take the frequency too low, below ~100Hz sensible persons might ‘recognize’ the flicker because of the missing ‘inertia’ compared to the ‘old’ light bulb with wire filament (which shows 100Hz light amplitude variations). This becomes much more apparent when moving the LED in front of the eyes (or just moving the head). I would really try to keep the frequency >200Hz.

I also think that inductance issues can be completely neglected at these frequencies and with this installation. Resistance is a completely different story due to the highly non-linear voltage/current characteristic of the LEDs.

When the ‘scope is connected to the far end, I’d expect to see the off->on transition rising ‘lazily’, giving a shorter ‘on’ period compared with closer to the driver. The LED’s are just P-N junctions and show significant capacitance across the ‘on’ junction that is strongly dependent on the current flowing.

The multiple lumped capacitors and resistances between the devices are acting much like a ladder network and smearing the driving square wave. A few factors can reduce the effect -

Drive both ends of the strip

Reduce the drive frequency – the ‘slow’ leading edge becomes less of a % of the total ‘on’ time

Shape the leading edge to start off as a ramp – this will pass the ladder network with less distortion but at the cost of some extra power loss in the driving MOSFET. A larger R between the output pin and the MOSFET gate is enough since the gate pin also has a large effective capacitance value

Thanks – that clarifies it really well. I’m thinking of trying out 125 Hz or so, and if needed to hook up either just +12V (which carries most current) or all signals to both ends of the strip. That would reduce the color imbalance to the center of the strips. In this case probably fine, but perhaps still not good enough with 5 m of strips on end, or more.

Yes, I’m using switching power supplies of 2.5 and 4A. The usual bricks, I picked them for their low 0.2 W standby current. There will be 5..10 of these around the house once this all works as intended.

Is it possible to use extra power supplies to minimise voltage fluctuation?. This would hopefully eliminate one source of flicker.
(It’s annoying and usually fruitless trying to solve 2 problem sources at once. The process of elimination has always solved me well).

This is not really necessary. The 12V supply fluctuates around 0.2V, but these fluctuations are at 1000 Hz, which is not visible – and it’s in exact sync with the LED’s which are turned on and off at the same rate.

Quote: ‘The multiple lumped capacitors and resistances between the devices are acting much like a ladder network …’

The LED stripes driven with 12V that I know have up to three LEDs in series and a varying number of these in parallel (depending upon the length of the stripe). So there is effectively no ‘ladder network’.

Th problems resulting from unstable supply voltage show why LEDs are mostly driven with constant current (or significantly high series resistance) to avoid such effects.

There are good reasons to use constant current (the Current Source Plug is a switching type). But the strips I have use the common 3-LEDs-plus-a-resistor setup. This wastes energy, especially for the red LEDs which have a lower forward drop and usually are powered up more than the rest to get warm white. But I don’t feel like replacing all the resistors by jumpers (3 R’s per 5 cm!).

It;s a compromise.

BTW, the current setup is quite good already. I’m sure end-powered and/or 125 Hz will make them acceptable for the entire house (and the entire family). I don’t intend to use them for main lighting – just ambiance and sunset/sunrise shades. Long strips all along the ceiling, used mostly dimmed.

JB, my comments were directed to the apparent lack of “blue” luminance towards the end of the strip. A ‘scope shot of the far end pulse shape will help that diagnosis.

The flicker is some combination of “beat frequency” between the two unlocked PWM clocks and the induced ripple on the supply as you suggest. Subharmonics of 2*Freq(1) – Freq(2) are well within the “flicker” range.

Jc, probes can extend within reason at the loss of high frequency response. The better divider probes have an adjustable C in the probe body to compensate for the cable capacitance. You set it up to get clean edges without ringing on a known fast rise time pulse train. You will run out of C range if you stretch the cable too far and then start to see integration on the edges.

If you are more in logic analyzer mode than waveform mode, a little rounding won’t matter. The larger diameter coax cables tend to have lower capacitance/meter. With good quality BNC crimp connectors, the impedance discontinuity is minor and doesn’t usually cause problems with reflected signals in the frequency range of the midrange sampling scopes.

High end scopes put the sampling in the probe head and differentially drive out a pulse stream that is reconstructed in the scope front end – but at a price !

Thanks. Oh, I know about price, I assure you. I’ve recently ordered an HMO2024 Hameg scope. It’s called “mid-range” – hah! Options add a lot to the cost. The scope will support active probes, but that’s too pricey (and luckily also unnecessary) for me. I did order an isolated differential probe from a third party – for 220V use.

Perhaps adding series inductance and a freewheeling (fast recovery) diode will help. This will effectively change the setup to a current-limited chopper, which will increase efficiency because the losses in the resistors are reduced with the square of the current.
Changing the PWM frequency to 100 Hz will introduce visible strobing (when moving your head, for example). Some people get headaches after a time from a room blinking at 100 Hz at low duty cycles (Fortunately, just a few people :) TL lighting also does this).

That sounds like an interesting option. Basically a switching regulator without the feedback loop! Just to make sure I get it right: a schottky diode in blocking direction over the MOSFET and then the series inductance?

Yes, w.r.t. the PWM rate I wasn’t planning on going below 250 Hz – strobing can indeed be very annoying. I also always wonder to what extent cats suffer from that sort of thing.

This sort of thing lends itself well for simulation in a SPICE program. I’m not sure whether the coil keeps the current linear with PWM duty cycle with a nonlinear (LED) load. If it’s not, you can introduce feedback and create your own current-controlled switching regulator :)

JC, your differential probe is a good choice for looking at those waveforms sitting on a “mains” potential. Please be aware though that the probe Vmax/CMR rating is from anything happening at the probe tips – viz. ~325 peak from the a/c mains plus any spikes. Some noisy loads (e.g. a drill motor with brushes) have substantial “hash” added to the waveform. Even the “off” spike from say a refrigerator compressor can reach surprising levels, depending on when/how the thermostat contacts arc open.

It is well worth considering a test fixture that includes at least one VDR-type clamp (L-N, or better L-E, N-E if you have the luxury of a three-wire connection). They don’t load the circuit significantly below the trigger voltage and turn on above fast enough to clamp the overvoltage well, protecting the expensive probe.

BTW – depending on the design, this probe may be easier to extend the lead length on since the output stage may deal with the extra cable capacitance better. Indeed, for high end buffered probes, the output stage is designed to drive the cable at the characteristic (50Ohm) impedance and the scope front end switches from 1MOhm to 50Ohm also. Cable distortions are then dominated by transit time effects, not length loading.

Its taken us a while to understand transmission lines. When the first transatlantic telegraph cable was laid, the waveform distortion was so bad, the first message of congratulations took several hours to send in Morse code.

Probe is rated “1kV RMS (differental)” and “600 RMS (common)”. Would it help to use a surge-protected power strip? Hm, in fact would it help to just create a mains plug with 2 VDR’s to gnd and plug it in? Seems to me that such a plug near my workbench could protect from any spikes coming through the mains? Last thing I want (apart from first of all keeping myself safe) is to damage expensive equipment.

PS. I see in the email that you’re using html tags (which get stripped, I think) – use ** and * around words for bold and italics (it’s all Markdown formatting).

JC, that’s a good spec on the differential probe, it should handle most spikes on its own. Yes, it is still worth a “local” spike lopper that will protect downstream and to a lesser extent, parallel loads. If you make one inside a plug, remember a local fuse in series with the MOV (L – N) and a NE2 style neon indicator across the fuse as an ‘inoperative’ warning. MOV’s can stand amazing abuse, but eventually fail short if they handle many high energy events.

This is exactly what I have on one workbench. UK style plugs come with integral fuse and neon indicator – a little wiring shuffling and you have a good, portable protection device. I expect you can find similar indicating plugs in your format and add the fuse. Additionally, I use a commercial device at the incoming mains distribution board – it is essentially the same principal with L1-E, L2-E MOV’s and a telltale green led showing ‘active’. Mains distribution here is american style, wires and transformers on poles with frequent lightning storms….

P.S. Not sure where the html tags are coming from – I just type into the box provided, under Safari

If I may pick your brain a bit more… sounds like it might be interesting to track spikes and graph them. I’d like to confirm my hunch that the power line here is fairly clean (suburban). Is there a way to easily detect such spikes? Then a variant of the AC current monitor could count ‘em and send the count out as a packet. Perhaps a divider + zener, feeding a cap to retain the charge until the ADC picks it up? Sort of a little line-health monitor (and while I’m at it, I could also add a 50 Hz monitor – like this one).

Yes, can be done. Depends on what is of most interest. At first glance, detecting any spike above say Vpk*1.2 as an event to count sounds interesting, then maybe characterising by how “big”. Fuzzy parameter – absolute value reached is of interest, that’s what will punch through insulation, but energy content ( more like the integral of the spike ) is important too. That is what determines the size of any protection devices required.

Commercial “mains analysers” do both – basically a fast ADC with plenty of headroom, ~1Kv input protection and a crystal clock. The rest is all comparing actual against ideal, then saving events for later filtering/display.

A useful tool, if only in a negative sense. Really handy at sites where the myth of “spikes on the mains” was supposedly responsible for mysterious system crashes. Logging for several days usually showed no correlation between crash and mains event – not surprising, since the logic was decoupled by considerable energy storage in the conservative power supplies. Patience with the dump analysis usually pointed at the offending code/component.

Is your “current sensor node” heading to a minimal component/minimal PSU design? Just counting an event in the sampling window seems a good match. I can suggest a peak store and hold circuit for this if you like.