Warning to users of some vendors LCD keypad shields

We are in general agreement and I think both of us misunderstood each other. We have two different approaches for avoiding the D10 output HIGH issue when offering backlight on/off control. One method involves a hardware mod and s/w while the other is s/w only.

Your first explanation was not clear enough to me to be able to tell how you were intending to use the output pin since you didn't fully describe it. From your first description it appeared that you were just setting the pin to INPUT and nothing else. I now see that you intended to control the backlight on/off.

However, this approach and the s/w only approach from response #3 both have the same issue of a "short" when D10 is an output and driven HIGH. The reason is exactly the same whether the resistor is present or not. (No current limiting from D10 into the base).

i.e. if s/w is loaded into the board that programs D10 as output and drives it high BOOM... There is a problem - regardless of whether the resistor is removed.

So while either method can offer on/off backlight control, neither protects the hardware from damage and neither can support PWM because the first thing analogWrite() does is make the pin an output as it turns on PWM which will be driving the pin high.

The difference between the two is that one requires a hardware mod AND special/odd s/w and the other is only special/odd s/w.


The h/w and s/w method: - cut/remove resistor under LCD - possibly add weak pulldown resistor to D10

  • set D10 to INPUT
  • turn on pullup to turn on backlight (AVR m328 spec says 20k to 50k, worst case of 50k is that enough to turn on the transistor for backlight? .1ma ?)
  • turn off pullup to turn off backlight.

Alternatively with IDE 1.0.1 and beyond the s/w part reduces to be: (with no initial setting of D10 to any state or level)

pinMode(D10, INPUT); // turn off backlight
pinMode(D10, INPUT_PULLUP); //turn on backlight

The s/w only method: - set D10 to LOW (only once) - set D10 to OUTPUT for backlight off - set D10 to INPUT for backlight on

Alternatively, with any version of IDE this reduces to: (with no initial setting of D10 to any state or level)

pinMode(D10, OUTPUT); // turn off backlight
pinMode(D10, INPUT); // turn on backlight

This works because OUTPUT sets the output of the pin to LOW as well which will pull the transistor base down which will turn off the backlight. Since the pullup still in place on the LCD shield, there is no need to turn on the D10 pullup, just setting it to INPUT mode will allow the shield pullup to drive the transistor to turn on the backlight.


Given both methods have the same limitations and they both reduce down to very similar s/w operations to control the backlight, my preference would be for a s/w only solution.

I had talked to fm just after I started this thread about adding support for this s/w only method to the lcd library as an option but we came the conclusion that there is no guarantee that the user will provide the correct information to the constructor. And since you really can't tell things are broken, because it seems to work, when you are shorting out the D10 pin by driving it HIGH, we opted not to provide it. (Its also a strange and very narrow usage case as well)

--- bill

bperrybap: We are in general agreement and I think both of us misunderstood each other. We have two different approaches for avoiding the D10 output HIGH issue when offering backlight on/off control. One method involves a hardware mod and s/w while the other is s/w only.

Your first explanation was not clear enough to me to be able to tell how you were intending to use the output pin since you didn't fully describe it. From your first description it appeared that you were just setting the pin to INPUT and nothing else. I now see that you intended to control the backlight on/off.

However, this approach and the s/w only approach from response #3 both have the same issue of a "short" when D10 is an output and driven HIGH. The reason is exactly the same whether the resistor is present or not. (No current limiting from D10 into the base).

i.e. if s/w is loaded into the board that programs D10 as output and drives it high BOOM... There is a problem - regardless of whether the resistor is removed.

So while either method can offer on/off backlight control, neither protects the hardware from damage and neither can support PWM because the first thing analogWrite() does is make the pin an output as it turns on PWM which will be driving the pin high.

The difference between the two is that one requires a hardware mod AND special/odd s/w and the other is only special/odd s/w.


The h/w and s/w method: - cut/remove resistor under LCD - possibly add weak pulldown resistor to D10

  • set D10 to INPUT
  • turn on pullup to turn on backlight (AVR m328 spec says 20k to 50k, worst case of 50k is that enough to turn on the transistor for backlight? .1ma ?)So average LED run at 20mA, 10 typical. You need gain of 200+. Most of these small transistors have current gain of 200-500 on average. I think it is sufficient.
  • turn off pullup to turn off backlight.

Alternatively with IDE 1.0.1 and beyond the s/w part reduces to be: (with no initial setting of D10 to any state or level)

pinMode(D10, INPUT); // turn off backlight
pinMode(D10, INPUT_PULLUP); //turn on backlight

Correct. Or after initial setup as input just do regular digital write (but not PWM!).


The s/w only method: - set D10 to LOW (only once) - set D10 to OUTPUT for backlight off - set D10 to INPUT for backlight on

Alternatively, with any version of IDE this reduces to: (with no initial setting of D10 to any state or level)

pinMode(D10, OUTPUT); // turn off backlight
pinMode(D10, INPUT); // turn on backlight

Correct. But you have to be careful and assure not to set output High.

This works because OUTPUT sets the output of the pin to LOW as well which will pull the transistor base down which will turn off the backlight. Since the pullup still in place on the LCD shield, there is no need to turn on the D10 pullup, just setting it to INPUT mode will allow the shield pullup to drive the transistor to turn on the backlight.


Given both methods have the same limitations and they both reduce down to very similar s/w operations to control the backlight, my preference would be for a s/w only solution.

I had talked to fm just after I started this thread about adding support for this s/w only method to the lcd library as an option but we came the conclusion that there is no guarantee that the user will provide the correct information to the constructor. And since you really can't tell things are broken, because it seems to work, when you are shorting out the D10 pin by driving it HIGH, we opted not to provide it. (Its also a strange and very narrow usage case as well)

--- bill

Bill,

Good points, no other arguments. It is good drill for crowd to understand all options. And yes, software only fix is better, or rather more convenient but it is still short of full functionality and compatibility. I believe, and this is why I did implement my option 2 - removing transistor. It is safe, no additional parts required, full functionality preserved, tho some software adaptations of existing code might be necessary.

Best regards!

Sal

As I came to this thread, I was most concerned because I had been running a shield for some weeks, just to see how high the seconds counter would go. In the event, the thunderstorm came first (and we had more today).

I was not quite sure how to determine whether this was a faulty or “fixed” board, so to test it I used the “Diode Test” range on the meter to test between D10 and ground on the shield - sure enough, it read 0.7V.

OK, I’m not happy. My solution? Well, I note that the holes on the LCD panel itself are unusually big, and it is relatively easy to suck out the solder on the top side (partially as it turns out that there is only solder on the top side anyway, it has not fully filled the holes). Where pins were still “tacked” to the sides of the holes after a second suck (it is often useful to put more solder on the connection for a second suck, so that it is all liquefied by adequate contact with the iron), they could generally be released by warping or twisting the pin with tweezers (that is a pair of epilation tweezers in the photo!).

Now revealed is R7 and the transistor. I don’t know about the original, but R7 on this specimen (note all the spelling mistakes) is not 10k, it is actually 1k! What I did was to shave out the track between R7 and the transistor and move it over this gap - the pads already suited the purpose.

Many other alterations are possible but I did not fancy finding my SMD stocks, so now D10 connects to the transistor via 1k and nothing else.

Next I mounted the shield and plugged in power. Nothing appeared. Until at least, I looked closer. In fact, the test sketch was running as before, but no light. No voltage (at all!) on D10 either, unless I put the multimeter on low volts between D10 and Vcc, when I saw some light.

Had I fried a pin on a Mega2560? Well, no. The sketch is Mark Bramwell’s July 2010 LCD panel test which uses the six-argument LiquidCrystal lcd constructor which makes no reference to port 10, thus it remains an input. Adding the lines

pinMode(10, OUTPUT);
digitalWrite(10, HIGH); // set the LED on

brings up the LED illumination and in fact, commenting out the first so that port 10 remains an input, makes virtually no difference though the voltage on D10 is only about 0.8V rather than near Vcc.

So I have a shield which is (now) safe, but expects D10 to be activated, if only using the internal pull-up.

A thought - if the digitalRead() call actually reads the pin state, then it would be possible to set it high as an output, then immediately test it to see if it is actually high, and if not, deem it to be shorted and alter the sketch behaviour accordingly.

RIMG1701a.jpg

RIMG1701b.jpg

Paul_B, I really like the idea of testing/reading the D10 pin state after setting the pin HIGH. Luckily the digitalRead() code reads the PINx register vs the PORTx register so this is possible. What I'm not sure of is how much the output pin droops. If it droops enough to be read as a LOW (which I'm assuming that it does given the "short"), then it could be used to make a great little test sketch to tell people if their shield has this issue.


On an actual "fix" A better alternative to moving the resistor would be to replace the transistor with an FET like a 2n7000. That way you can still leve the pullup resistor in place to ensure the backlight is on by default and there is no issue of shorting out D10 like with a NPN transistor since the FET gate doesn't draw/sink current like the NPN base does.

--- bill

bperrybap: What I'm not sure of is how much the output pin droops. If it droops enough to be read as a LOW (which I'm assuming that it does given the "short")

With the base-emitter junction of a transistor pulling it down, it will droop, make no mistake! The technique would not be so useful to detect for example, being connected to the backlight LED with no series resistor.

bperrybap: A better alternative to moving the resistor would be to replace the transistor with a FET like a 2n7000.

Presupposing you have a drawer full of surface-mount FETs. I do not, and being late at night, I did not feel like exhuming my SMD resistor stock from the garage either. XD


I asked Nick to make this a "sticky" as the matter is to my mind, just so important (with the clear risk of damage to MCU boards).

The backlight pin output does seem to droop low enough on an unmodified shield
when attempting to turn on the backlight.
I created a sketch that will automatically detect if the shield
has a backlight circuit issue.
It will display results on the LCD.
See the sketch for full details.
It is attached.

— bill

LCDKeypadCheck.pde.zip (2.22 KB)

I decided to bite the bullet and separate the LCD module from the LCD/keypad shield I have. Unsoldering 16 pins simultaneously is a challenge but it can be done if most of the solder is sucked out of the holes and then you wiggle the two boards relative to each other and also wiggle each pin in each hole for a while to break loose any solder that does remain. I found an SOT-23-3 transistor labeled AM1 (like this one http://www.digikey.com/product-detail/en/SMMBT3904LT1G/SMMBT3904LT1GOSTR-ND/3062754 ) installed on the lower board. I got this 2N7002 FET as a replacement for the transistor: http://www.digikey.com/product-detail/en/2N7002,215/568-1369-1-ND/763366. Soldering something that is as tiny as one of these is also a challenge and you need to have a good soldering iron with a needle tip to attempt it. After connecting everything back together it works.

I found that the following code could be used to turn the backlight on or off or any value in between.

pinMode ( BACKLIGHT_PIN, OUTPUT ); analogWrite ( BACKLIGHT_PIN, 64); // a value of 000 (off) to 255 (on) controls PWM% //digitalWrite ( BACKLIGHT_PIN, HIGH ); // turn on backlight //digitalWrite ( BACKLIGHT_PIN, LOW ); // turn off backlight

lcd.begin(16, 2); // start the lcd object

Hi All,

Just discovered this issue in my LCD shield.

[edit: I just replaced the transistor with a 2n7002 (marked 702 3d salvaged from a random PCB), since I shorted the transistor that was in there trying one of the earlier suggestions. Whew!]

[edit2: that lasted a few minutes. I had a simple timer to turn off the backlight after 60 seconds. After a few cycles, instead of going off, the backlight flickered and then went off permanently. I've now cut the trace to D10, the gate voltage is 0.34V, 2.4V on LCD pin 15. I can jump the gate voltage to 5V and measure about 40mA, and the backlight will then go on. So the mosfet seems to be working. Seems like the 4.7K resistor is open or maybe there is not enough to drive the mosfet?]

I have these small signal diodes: PMBD914 datasheet: http://www.nxp.com/documents/data_sheet/PMBD914.pdf

Will that diode work here?

If so, I can cut the trace from arduino pin 10 on the shield. Do I solder pin 3 of the diode to arduino side pin 10?

Thanks!

Is there any supplier in INDIA

I bought an OSEPP 16x2 LCD display shield today (16X2SHD-01) and found it has the same issue. The test sketch posted here reports it as "BAD". There is a 1K pullup resistor and no base resistor (schematic from OSEPP). Intriguingly, I can just barely see an empty SMD outline next to the 1K resistor. I tried removing the display to see how easy it would be to add a base resistor, but failed: my only desoldering tool is a solder sucker and some pads were starting to lift. So I'll live with it for now: I don't really need to control the brightness for the simple projects I have in mind.

dahlbert, I'd recommend reporting the issue to them. Maybe post a thread on their support forum.

--- bill

bperrybap: I'd recommend reporting the issue to them. Maybe post a thread on their support forum.

Will do. I am now awaiting registration approval on their forum.

Hi All, This is my first post and I hope I have not broken any rules unknown to me. Thank you for the heads up on the backlight D10 NPN issue and the work-arounds. Well done to all. In my case I am using the PCF8574 Remote 8-bit I/O expander for I2C-bus LCD ‘backpacks’ and am wondering if the same issue is at hand when the 8574 drives the J3Y S8050 NPN transistor on those particular boards. They seem to have the same LED circuit as the LCD shields. See attached. Kind Regards to all.

I2C LCD Backpack schematic.pdf (39.7 KB)

Good catch and great question. Slightly off topic, but still a bit relevant. The PCF8574 uses quasi bi-directional i/o pins. This is done by using the data in the port register as the direction bits. If the bits are a 0, the pin is an output as driven low. If the bits are 1, then the pin is an input and a pullup is turned on. The result is that PCF8574 can only sink current or drive pins low. When the bit is 1, then the pin becomes an input with a pullup resistor so it can't source much current.

The "short" issue in this circuit is when the base of the transistor is high. Since the PCF8574 can't really drive current with a high output signal, (it only turns on a pullup), it doesn't create an issue since there is no "short". Essentially the circuit is taking advantage of the internal design of the PCF8574. That said, do I think the designers of this board intentionally did this? Probably not, I think more than likely they got lucky.

--- bill

Dear Bill, Your explanation regarding the I2C PCF8574 backpack is well put indeed. The PCF8574 datasheet mentions 'Latched outputs with high current drive capability for directly driving LEDs.' But closer reading reveals that this relates to current sink of 25mA and current source of up to 300uA with a 1mA transient pull-up current for one clock pulse only. I was worried as I have a system in the tropics that uses both the LCD shield and I2C backpacks. My concern was that the operating temperature peaks around 58degC (136degF) and I was worried that I may cook the D10 pin at elevated operating temps. Luckily, the PWM LED dimming function has not been selected yet...

May I say this entire thread has been most helpful and I thank all who have contributed. I do hope I will be able to provide some assistance with regard to aspects of my arduino system applications in the future.

F.Y.I. my LCD shields (varying designs old and new) all fail the backlight test, and on pcb inspection reveal direct connection to D10. I will be installing FETs on all shields. Bill, thank you for your time to respond so quickly.

  • Gary

Thanks bperrybap for the test program and the heads up. I have the Sainsmart LCD keypad shield that I just purchased on Ebay and it lists as dimmable. I don’t think the builders are going to correct the boards considering the time frame of this issue. This thread is needed. Despite the earlier programming cautions, I don’t recommend any software fix as Arduinos are used for testing and a preexisting sketch may have set pin 10 high. If the shield is then put on before connecting to the computer, the USB port will be overloaded before reprogramming and hopefully just disconnect. This however would be frustrating to figure out if this issue is not known. A hardware fix is the only good option. I had some old radio shack 1N34A germanium diodes and completed your repair. Found that the diode can easily brake if the leads are not carefully bent. Thanks again.

My DFrobot keypad LCD purchased Jan2013 also has a 1K resistor for R7. (you can measure it between pin10 and the Vcc pin) The board matches the pic posted by Rocketeer503. Unfortunately this means that neither a 500R resistor or a 1N34 diode from the transistor base to pin 10 will turn off the transistor. I tried both and they only drop a couple of mV from the nominal 0.8v base voltage - not enough to turn off the transistor. My bare board draws 8 mA with pin 10 grounded and the LCD backlight off or 25 mA with the light on. I think I’ll just leave the pin 10 trace cut and soldier on without dimming capability.

Reb9, An alternative is use a resistor between D10 and the base AND cut the connection of R7 to VCC You might even be able to re-use R7 by cutting the D10 to base connection and re-connect it to the other side of R7 where VCC was so R7 now connects to D10 on one side and the base on the other. This allows D10 to have full control of the transistor. The draw back is that by default the backlight will be off since there is no pullup on the base. This can eaasily be fixed in s/w. An easy remedy is to simply switch to using fm's LiquidCrystal library replacement: https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home If you fill in the constructor with the backlight control information, then lcd.begin() will turn the backlight for you. You will also be able to use lcd.backlight() to turn it on, lcd.noBacklight() to turn it off and lcd.setBacklight(dimvalue) for dimming.

Note: Do not use the deprecated setBacklightPin() call, just fill in the constructor with the backlight pin and polarity. After that, every thing will work just like with the LiquidCrystal that comes with the IDE other than you now have backlight control.

--- bill

Bill Doesn't look like I can do that on this shield without removing the LCD sub panel. I may eventually pluck the transistor and dead bug a new one. I'll keep your suggestions in mind. thanks for keeping this thread going

I am new to Arduino and am almost wholly incompetent with PCB's. I bought the Sainsmart 1602 on Ebay, used the test program and found my LCD to fail. I am interested in the software fixes, but am unsure where to put the code and what specific code I should use.

Am I modifying the library or each individual sketch? Does this short fry the pin when the backlight is bright or dimmed? And if it is one of these, can I just leave the LCD in one setting.

The shield seems to be working now. Does it dry the pin gradually or immediately?

Thanks.