PWM chopped backlight confuses LCD

To control LCD module backlight (LED) brightness, I use analogWrite on an Arduino pin connected to the gate of a 2n7000 mosfet to switch the LED cathode to ground. The idea works well to control brightness, but.... the LCD will scramble within a minute whenever brightness is not turned full on, or full off. It seems the frequency is creating noise and within a minute... the LCD display is taking a trip somewhere I didn't send it!

The module rates the backlight at 150mA, and came with simple dropping resistors for an anticipated 5 volt backlight supply. I didn't want this 150mA load on the Arduino voltage regulator, so I changed the backlight resistance (increased it) to use Vin (12 volts) instead. My resistance choice keeps LED current to about 150mA.

So 12 volts runs up the standard 16 pin ribbon cable to the 2x8 layout connector at the LCD module. The module drops the current with resistors there, runs through the LED backlight and back down the ribbon to the mosfet mounted back at the Arduino.

What's a better layout?

Im not sure i understand what you have without a schematic, but it seems you have the chopping transistor before the supply of the arduino and LCD and it could be making a lot of noise. maybe a capacitor 100-220uf between +5v and ground next to the LCD may help.

it could also be that the chopped 12v signal is going to the LED on the Backlight through some traces on the LCD next to data lines and introducing noise. (2 close traces= capacitor, which can pass high frequency) maybe just putting the dropping resistor on the positive side might help.

What is the frequency of standard PWM (analogWrite) on a 16Mhz board?

About 490Hz or around 1kHz.

You need some decoupling on the supply to the LCD electronics.
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

If I were troubleshooting this I would try the following to see how it affects:-

  1. Separate the PWM signal from the ribbon cable. Not sure what LCD you are using, but the timing on some of them can be critical. I know it's the unloaded 5v PWM signal running up there, but you never know.

  2. Some LCD's allow connection to the backlighting at the SIL connector as well as at the end of the LCD itself. Try either/or.

  3. Add +5v & +12v supply de-coupling capacitors.

  4. Add a reversed biased diode at the source of the FET to ground just incase you are getting any negative voltage spikes. Not likely with LED backlighting but you never know.

Ian.

Thanks all...

1 kHz is not exactly RF range... but 150mA is a fair whop of juice so I guess it could be inductive coupling in the ribbon cable throwing in false bits on neighboring data lines.

Separating the backlight lines from the data cable would probably help, maybe run the backlight power up a shielded cable? There are A & K points to solder right at the backlight instead of running current through the module board traces and ribbon cable.

I like the idea of adding more decoupling caps at the module. There are already a couple pretty hefty caps on the module, as far as SMT parts go... but adding 47uF to 100uF at the power input points near the DIL connector on the LCD module couldn't hurt.

I wouldn't have thought to add a flyback diode over the transistor for an LED load, but maybe the cabling / length is acting as an inductor that is creating sharp spikes after the edges of the PWM square wave.

Thanks

Well, I tried a couple things... and the behaviour changed.

First I added a 47uF and 0.1uF cap at the LCD module power pins.
This got rid of one kind of error... the LCD would occasionally "splat" within a minute and instantly show garbage all over... that doesn't happen any more. Now it never splats. So stiffening the power at the module has helped, and removed the problem of power glitching its CPU.

But it still exhibits the other error it was showing: using the hello world LCD example occasionally the "seconds counter" prints twice, it duplicates the number on the same row. For example, if it's on 42 seconds, it might print 4242 on the second line. This is hit or miss.. it can count normally for a while incrementing as it should, then boom I get a double.

Sometimes the 2nd number appears almost simultaneously, as if to "roll over together". Sometimes, the second printing of the number is delayed, so "89" comes and a fraction of a second later I get the second 89 is printed (resulting in "8989" on the display). The second number sticks in its position while normal counting resumes... until it's overwritten by another duplicate.

Now, unless the Arduino is sending all that data up twice (I doubt it), there is some signaling combination appearing at the module that is causing it to repeat the last thing it did. Not just the last digit it got, it's whole last number string getting printed twice.

2nd thing I tried was putting a reverse diode over the LED array, in case there was an inductive spike shooting back up to the module and had nowhere to go. Now, any such spike is routed back down the cable to Vin rail.

The diode didn't change the duplicate printing thing.

Again, this only happens when PWM is being used to change brightness of backlight LED to something between the extremes.

In case it matters: I am using a 6 wire connection for LCD: data4-7, RS and E connect to Arduino I/O pins. RW is grounded at the Arduino side of the ribbon. Data0-3, and pin3 contrast pins are essentially floating at the module. They have ribbon cable attached all the way down to Arduino but are N/C there . (The module has its own on-board pot for contrast adjusted just fine.) The ribbon is about 4 feet long, flat not twisted pair, common2-row header connectors on each end.

..time to try some more things.

OK, I added another flyback diode this time over the mosfet drain and source. And I changed the the path of the dropping resistor on the module itself. Still got the duplicates displayed.

I'm becoming pretty sure its ribbon cable related, and I've even found a sweet spot of holding the ribbon behind the LCD module in such a way that it almost guarantees duplicates - depending on the code! :o Read on...

Looking at the hello world sample code there are lots of numbers being sent to the LCD, so I'm pretty sure the dups were being generated by the Arduino, not buffered and simply being reprinted by the LCD. Each one comes from the Arduino.

So what's causing the dup's to appear... it has to be related to the setCursor command not getting through to the LCD. It's not setting the cursor back to column 0, so a second number follows from where the LCD has last left off with its cursor. A dup appears!

With this code:

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(0, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
}

Now, here's the bizarre part. I changed one line of code, the location of the cursor to column one:

void loop() {
// set the cursor to column 0, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(1, 1);
// print the number of seconds since reset:
lcd.print(millis()/1000);
}

When I run this code.... I don't get duplicates on the LCD. Numbers count up normally (in column 1 of course). But no dups. Even when I hold the ribbon cable in the sweet spot behind the LCD.

:-? There's something more robust about the command that moves a cursor over to position 1 rather than 0?

Anyway, I need to put focus on the cable, obviously. I will separate the backlight lines from the LCD/data lines. I'm also thinking I should do something about removing the wires from unused pins and no run dead lines to the Arduino if not needed. I think I'll ground RW right at the module, and save a wire there. Wonder if I should connect pullups or pulldowns for the unused data lines d0-3 at the module?

I tried simply turning the backlight on and off with pin D10
pinMode(10, OUTPUT); //remember to enable it as an output

digitalWrite(10, LOW);
digitalWrite(10, HIGH);

When it went low the backlight went off fine, however when it went high it caused a lot random flickering in the display. It didn't really mess up the display but it flickered and blinked. It was a lot different than when it was simply tri-stated when pin 10 was not set to an output. So, I checked the schematic to discover a bad design. D10 is directly driving the base of an NPN transistor with the emiter to ground! So, no wonder it is acting all crazy. I beleive that is too much of a current load on the output pin. The pull up resistor in the schematic is 4.7K so I think a 4.7K in series with D10 would make it work better. You would have to cut the connector stacking pin or bend it out of the way then add the resistor in series. I bet the PWM would work for you with a 4.7K resistor in series. the schematic is here: robotshop (dot) com/content/PDF/dfrobot-lcd-keypad-shield-schematic.pdf

oops I was thinking so much about turning the backlight on that I didn't even think about turning it off. Forget that 4.7K resistor in series. It will never turn off! Use a diode in series polarized with the cathode toward the arduino board. That way it can ground the base of the NPN transitor and turn it off, but it can't try to power it and overload itself. Here is the schematic:
http://www.robotshop.com/content/PDF/dfrobot-lcd-keypad-shield-schematic.pdf