Warning to users of some vendors LCD keypad shields

HaplessDIY: OK, I understand that was "fake news" :confused: Anyway, if it has the design flaw does the display still work at all, should I be able to see some characters? Does that bad design keep the screen from showing characters? If the answer is that it only affects backlighting then there's no point in me trying test code.

Fake news? I have no clue what you were tying to say.

With these comments it sounds like you didn't read the initial post in this thread. It describes the issue. It is a backlight control issue. If the Arduino drives the pin connected to the backlight circuit on the shield, there is the potential to damage the AVR processor since the backlight circuit is pulling way over the allowed current that an AVR pin can safely supply. (and other processors too)

--- bill

bperrybap: Fake news? I have no clue what you were tying to say.

With these comments it sounds like you didn't read the initial post in this thread. It describes the issue. It is a backlight control issue. If the Arduino drives the pin connected to the backlight circuit on the shield, there is the potential to damage the AVR processor since the backlight circuit is pulling way over the allowed current that an AVR pin can safely supply. (and other processors too)

--- bill

Sorry Bill, I was trying to be funny about "fake news". I suppose you don't follow politics much. Good for you.

I did go back to the original post, download, and ran the code, sure enough BL Circuit BAD. So now I have many answers if not all. I just need to sort out the details. In the meantime I will enjoy the flashing bad message.

If I can be so humble as to suggest, your original post should be in a "sticky" with no responses allowed. My problem was that I read your post and I decided, well, I better read all the next posts because there is obviously more to the story. The more I read the more confused I got. I am an EE and I have a garage full of 1n34 to schottky diodes maybe even gaas its just that I got tangled up in a long thread of suggestions and counter suggestions and I couldn't tell who or what to believe.

I think I read somewhere in the threads that a workaround can be had by just not connecting pin10. I'll look into that one. Somewhere I saw mention of a schematic but then it wasn't clear that it was an accurate schematic.

The only other comment I would make is that while it is a "backlight control" problem it will make it look like the LCD doesn't work at all.

Thanks for writing that code. Its a nice piece of work. I will dig into it.

The LCD should be working. The images that you posted looked like an LCD that was not initalized properly. Perhaps you were not initializing what ever library you were using correctly. i.e. if you used the HelloWorld sketch from the LiquidCrystal library "as shipped" it will not work with that shield as it uses different pins to control the LCD than the shield uses.

The backlight issue is actually a simple error in the design. They did not put a current limiting resistor in series with the Arduino pin driving the base of the transistor to limit the current being fed into the transistor. The transistor acts like a short to ground and allows more current to pass through it than the AVR pin is rated for.

The solution would be simple if you could get to the PCB area to add a resistor but on most shields the area you need to get to is underneath the LCD panel and desoldering it is pretty difficult.

There are several options in both s/w and h/w to deal with it. You could use the hd44780 library instead of LiquidCrystal as it will check for the issue and work around it in s/w. Or you could do a h/w mod to actually fix the h/w. Or you could just make sure to never drive pin 10 high and let the backlight remain in its default state which is on when the Arduino pin is an input.

--- bill

.e. if you used the HelloWorld sketch from the LiquidCrystal library "as shipped" it will not work with that shield as it uses different pins to control the LCD than the shield uses.

you are correct I was using the library "as shipped" so your code fixed that problem. I would have never figured this out unless I would have dragged out a logic analyzer and captured the data and then studied the controller spec etc. or I suppose followed all those circuit traces. No way would I have spent that much effort.

Who figured out that the pin assignments were wrong? Was that in the Shield information from these different suppliers?

HaplessDIY: Was that in the Shield information from these different suppliers?

A schematic... ;)

Antonior: And a drawing...

A schematic is a drawing. No fancy tools are needed to see the pin connections. Just look at the schematic. It was attached in the very first post of this thread. And even if a schematic wasn't available, it would only take a few minutes to figure out the Arduino pins being used to control the LCD by using an ohm meter.

--- bill

Hello, Thank you for sharing :)

My shield in duinotech XC-4454 2x16.
I’ve attached it to a Sainsmart UNO with the sketch below and it worked fine with good brightness.
Then, because I want to be using the Arduino without the shield actually pressed on, to free access to other pins, I reconnected it with jumpers, eyeballing the matching connections. I initially connected just D4-9 plus 5v, gnd and A0. I also experimentally connected other (matching I believe) pin with jumpers.
The display still works, i.e. gives the correct output w.r.t. button presses but the screen is very dim. I’m not sure the backlight is on at all.
I pressed the shield back onto the UNO and still dim. I connected a 9v supply - no change. I uploaded the sketch to a genuine Mega 2650 R3, pressed on the shield, and get the same result.

Is it possible/ likely I damaged the LCD (there is a transistor I read can be damaged?) by manually connecting pins?

// sketch 09-01 USB Message Board

#include <LiquidCrystal.h>

// lcd(RS, E, D4, D5, D6, D7)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int numRows = 2;
int numCols = 16;
int sensorPin = A0;
int boo = 0;



void setup()
{

  Serial.begin(9600);
  lcd.begin(numRows, numCols);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Arduino");
  lcd.setCursor(0,1);
  lcd.print("Rules");
}

void loop()
{
  if (Serial.available() > 0) 
  {
    char ch = Serial.read();
    if (ch == '#')
    {
      lcd.clear();
    }
    else if (ch == '/')
    {
      // new line
      lcd.setCursor(0, 1);
    }
    else
    {
      lcd.write(ch);
    }
  }
  testfunction();
}

//======

void testfunction()
{
boo = analogRead (sensorPin);
lcd.clear();
   lcd.setCursor(0, 0);
lcd.print (boo);
Serial.println (boo);
 delay (5000);
}

So, using the hd44780.h library and this sketch:

// LCDKeypadCheck - LCD keypad shield backlight circuitry test // Copyright 2013-2016 Bill Perry

I get "BL circuit bad" so I guess something has happened to damage the LCD circuits. I've got another LCD 2 x 16 on order, this time not a shield (I don't want it clamped to the other board), and with the I2C backpack. So think I'll just move on.

EDIT: Does "BL circuit bad" refer only to the LCD shield itself or can it mean a damaged i/o pin on the AVR?

bumblepom: EDIT: Does "BL circuit bad" refer only to the LCD shield itself or can it mean a damaged i/o pin on the AVR?

It means the BL circuit on the shield is a bad design and has the short circuit issue on digital pin 10. Which means that you need to be careful not to set D10 to HIGH as the high current draw could potentially damage the AVR.

I'll update the message to be a little clearer. It will be in the next release of the code.

--- bill

bperrybap:
It means the BL circuit on the shield is a bad design and has the short circuit issue on digital pin 10.
Which means that you need to be careful not to set D10 to HIGH as the high current draw could potentially damage the AVR.

I’ll update the message to be a little clearer.
It will be in the next release of the code.

— bill

Thanks Bill
Pin 10 seems still OK (led flash output OK). Is there an alternative pin-to-pin I can jump to turn on the backlight or is it likely to be permanently dead?

The message display on the LCD by LCDKeypadCheck was left alone. The comments in the sketch were updated to better explain what "BL circuit bad" means. It will be in the next release of the library. --- bill

bumblepom: Thanks Bill Pin 10 seems still OK (led flash output OK). Is there an alternative pin-to-pin I can jump to turn on the backlight or is it likely to be permanently dead?

Not sure what you mean by "led flash output OK". The led on the Arduino board is pin 13.

If you use the hd44780 library, you don't have to worry about it. You can use the backlight control API functions to turn the backlight on/off as the library auto detects the issue and works around it to protect the Arduino. If you try to use dimming [ the setBacklight() ] function, the library will disable dimming and revert to safe on/off only as dimming can't be done safely with that backlight circuit.

If you don't use the hd44780 library, don't manually control the backlight using digital pin 10 or attempt to use PWM on digital pin 10. While it may appear to work, it can potentially damage the Arduino processor.

And no matter which library you use, don't ever set D10 to high unless you hardware modify your shield.

--- bill

bperrybap: Not sure what you mean by "led flash output OK". The led on the Arduino board is pin 13.

If you use the hd44780 library, you don't have to worry about it. You can use the backlight control API functions to turn the backlight on/off as the library auto detects the issue and works around it to protect the Arduino. If you try to use dimming [ the setBacklight() ] function, the library will disable dimming and revert to safe on/off only as dimming can't be done safely with that backlight circuit.

If you don't use the hd44780 library, don't manually control the backlight using digital pin 10 or attempt to use PWM on digital pin 10. While it may appear to work, it can potentially damage the Arduino processor.

And no matter which library you use, don't ever set D10 to high unless you hardware modify your shield.

--- bill

I connected LEDS to pins D8 -13 (a clip-on mini shield) and No 10 functioned normally.

I added " setBacklight (255); " within the setup of LCDlibTest but got "'setBacklight' was not declared in this scope". I'll be talking to an experienced user later today so will try to sort it out with him. But I'm still trying to understand: If it is most likely the circuitry within the shield is damaged, maybe it is impossible to turn on the backlight regardless of the SW.

It doesn't sound like anything is broken. The shield you have has a design flaw. To really fix it requires a h/w modification. hd44780 can detect it and work around it but you will loose dimming capability as dimming requires using the pin in way that could damage it with the shield you have.

The API functions are methods within the lcd object. So if your lcd object is named "lcd", you would use lcd.backlight() or lcd.noBacklight() to turn the display on/off.

setBacklight(dimvalue) is for dimming, and while you could use that, dimming won't work if the shield has the BL circuit issue. If the BL circuit is detected by hd44780, all values other than setBacklight(0) will turn on the backlight with no dimming supported.

--- bill

Ok thanks. So I added lcd.backlight(); as shown below (I temporarily stripped out a lot of text). Now, the backlight has turned off completely. It must have been on very dim before - I’m new to these displays so did not know. But it was certainly a lot brighter the first time I tried it.

//
// vi:ts=4
// ----------------------------------------------------------------------------
// LCDKeypadCheck - LCD keypad shield backlight circuitry test
// Copyright 2013-2016 Bill Perry
// bperrybap@opensource.billsworld.billandterrie.com
// ---------------------------------------------------------------------------
//
// 2016.11.08 bperrybap  - updated for inclusion in hd44780 library
// 2013.10.29 bperrybap  - Original creation
//
// ---------------------------------------------------------------------------

#include <hd44780.h>
#include <hd44780ioClass/hd44780_pinIO.h> // Arduino pin i/o class header

// initialize the library with the numbers of the interface pins
// note that ESP8266 based arduinos must use the Dn defines rather than
// raw pin numbers.
#if defined (ARDUINO_ARCH_ESP8266)
const int rs=D8, en=D9, db4=D4, db5=D5, db6=D6, db7=D7; // for esp8266 devices
const int pin_BL = D10; // arduino pin wired to LCD backlight circuit
#else
const int rs = 8; // arduino pin wired to LCD RS
const int en = 9; // arduino pin wired to LCD EN
const int db4 = 4;// arduino pin wired to LCD db4
const int db5 = 5;// arduino pin wired to LCD db5
const int db6 = 6;// arduino pin wired to LCD db6
const int db7 = 7;// arduino pin wired to LCD db7
const int pin_BL = 10; // arduino pin wired to LCD backlight circuit
#endif

hd44780_pinIO lcd( rs, en, db4,  db5,  db6, db7);


/*
 * Macros to safely turn on the backlight even with back BL hardware
 * These assume that the BL pin is not touched or used after RESET other
 * than by these macros.
 */

#define SafeBLon(pin) pinMode(pin, INPUT)
#define SafeBLoff(pin) pinMode(pin, OUTPUT)

int status;

void setup()
{
	// set up the LCD's number of columns and rows: 
	lcd.begin(16, 2);
  lcd.backlight();         //I ADDED THIS   
	status = pinTest(pin_BL); // only run the actual test once

}

void loop()
{

	lcd.clear();
	if(status)
	{
		/*
		 * Shield has BL circuit issue
	 	 */
		lcd.print("BL Circuit BAD");
		safeBlink(pin_BL, 5); // safely blink the backlight
	}
	else
	{
		/*
		 * Shield is OK (no BL circuit issue)
	 	 */
		lcd.print("BL Circuit GOOD");
		softBlink(pin_BL, 2); // soft blink the backlight (uses PWM)
	}

	delay(1000);
}

/*
 * Function to test a backlight pin
 * Returns non-zero if test fails (bad circuit design)
 */
int pinTest(int pin)
{
int val;

	/*
	 * Check to see if there
	 * is a problem in the backlight circuit
	 * So far, the "broken" designs connected D10
	 * directly to the base of a NPN transistor,
	 * this will cause a short when D10 is set to HIGH
	 * as there is no current limiting resistor in the path
	 * between D10 to the base and the emitter to ground.
	 */

	/*
	 * Set the  pin to an input with pullup disabled.
	 * This should be safe on all shields.
	 * The reason for the digitalWrite() first is that
	 * only the newer Arduino cores disable the pullup
	 * when setting the pin to INPUT.
	 * On boards that have a pullup on the transistor base,
	 * this should cause the backlight to be on.
	 */
	digitalWrite(pin, LOW);
	pinMode(pin, INPUT);

	/*
	 * Set the backlight pin to an output.
	 * since the pullup was turned off above by
	 * setting the pin to input mode,
	 * it should drive the pin LOW which should
	 * be safe given the known design flaw.
	 */
	pinMode(pin, OUTPUT);


	/*
 	 * Set the backlight pin to HIGH
	 * NOTE: This is NOT a safe thing to do
	 * on the broken designs. The code will minimize
	 * the time this is done to prevent any potential damage.
	 */

	digitalWrite(pin, HIGH);

	
	/*
	 * Now read back the pin value to
	 * See if a short is pulling down the HIGH output.
	 */

	delayMicroseconds(5); // give some time for the signal to droop

	val = digitalRead(pin); // read the level on the pin

	/*
 	 * Restore the pin to a safe state
	 * Input with pullup turned off
	 */
	digitalWrite(pin, LOW);
	pinMode(pin, INPUT);

	/*
	 * If the level read back is not HIGH
	 * Then there is a problem because the pin is
	 * being driven HIGH by the AVR.
	 */
	if (val != HIGH)
		return(-1); // test failed
	else
		return(0); // all is ok.
}

void safeBlink(int pin, int count)
{
	/*
	 * Safely blink the backlight on LCD shields that have
	 * broken BL hardware
	 * Uses the SafeBL macros defined above.
	 */

	while(count--)
	{
		delay(200);
		SafeBLoff(pin); // turn on the backlight (safe to use for all shields)
		delay(50);
		SafeBLon(pin); // turn off the backlight (safe to use for all shields)
	}
}

/*
 * soft blink the backlight.
 * NOTE: this should not be used on a shield
 * with a bad backlight circuit
 */
void softBlink(int pin, int count)
{
	// soft blink the backlight by ramping down then back up
	pinMode(pin, OUTPUT);
	for(int times = 0; times < count; times++)
	{
		for(int x = 1; x < 16; x++)
		{
			analogWrite(pin, 256-x * 16);
			delay(50);
		}
		for(int x = 1; x < 16; x++)
		{
			analogWrite(pin, x * 16);
			delay(50);
		}
	}
}

Ha... With the LCD shield in place over the UNO, I tried shorting the solder terminal labelled "K" (next to "A" at the end of the row on top of the LCD board) to ground (next to 5v on the other lower shield surface) and the back light comes on with full brightness. This is while the above sketch is running (i.e. displaying "BL circuit BAD"). So, the back light itself is not destroyed.

Edit: And it draws 20 mA "K" to ground.

bumblepom, What you have done will not work. The diagnostic sketch is doing lots of things that are not typical/normal. Do not try to use that code as an example of how to do things. The diagnostic code tells the library that there is no backlight but then tries to control the backlight circuitry directly rather than let the hd44780 library code handle it. It must do it this way to get access to the information it needs to check and report about the backlight circuit.

You can't just try to throw in a backlight control call. You are attempting to bypass certain things so it will not work.

You should run the diagnostic sketch "as is" to detect if there is an issue. If there is an issue, the normal hd44780_pinIO code will detect it and work around it if you have told it you have backlight circuitry. You do that by the information you put in the constructor. See the HelloWorld sketch included in the hd44780_pinIO examples. It shows an example of using backlight control.

Now that hd44780_pinIO works around the h/w issue. You really don't have to worry about the h/w issue. Just configure your lcd object constructor to include backlight parameters and all backlight API calls will work. If the h/w has issues, the backlight will still work, but dimming will not work as you will get either full on or full off with no dimming.

--- bill

Bill: Is this “configur(ing) your lcd object constructor to include backlight parameters”?
I just added and removed some // to expose the BL control lines. BL remains off.

// vi:ts=4
// ----------------------------------------------------------------------------
// HelloWorld - simple demonstration of lcd
// Created by Bill Perry 2016-07-02
// bperrybap@opensource.billsworld.billandterrie.com
//
// This example code is unlicensed and is released into the public domain
// ----------------------------------------------------------------------------
// 
// This sketch is for LCDs that are directly controlled with Arduino pins.
//
// Sketch prints "Hello, World!" on the lcd
//
// See below for configuring the Arduino pins used.
//
// While not all hd44780 use the same pinout, here is the one that most use:
// pin 1 is the pin closest to the edge of the PCB
//  1 - LCD gnd
//  2 - VCC (5v)
//  3 - Vo Contrast Voltage
//  4 - RS Register Select (rs)
//  5 - Read/Write
//  6 - Enable (en)
//  7 - Data 0 (db0) ----
//  8 - Data 1 (db1)     |-------- Not used in 4 bit mode
//  9 - Data 2 (db2)     |
// 10 - Data 3 (db3) ----
// 11 - Data 4 (db4)
// 12 - Data 5 (db5)
// 13 - Data 6 (db6)
// 14 - Data 7 (db7)
// 15 - Backlight Anode (+5v)
// 16 - Backlight Cathode (Gnd)
//
// ----------------------------------------------------------------------------
// LiquidCrystal compability:
// Since hd44780 is LiquidCrystal API compatible, most existing LiquidCrystal
// sketches should work with hd44780 hd44780_pinIO i/o class once the
// includes are changed to use hd44780 and the lcd object constructor is
// changed to use the hd44780_pinIO class.

#include <hd44780.h>
#include <hd44780ioClass/hd44780_pinIO.h> // Arduino pin i/o class header

// declare Arduino pins used for LCD functions
// and the lcd object

// Note: this can be with or without backlight control:

// without backlight control:
// The parameters used by hd44780_pinIO are the same as those used by
// the IDE bundled LiquidCrystal library
// note that ESP8266 based arduinos must use the Dn defines rather than
// raw pin numbers.
//#if defined (ARDUINO_ARCH_ESP8266)
//const int rs=D8, en=D9, db4=D4, db5=D5, db6=D6, db7=D7; // for esp8266 devices
//#else
//const int rs=8, en=9, db4=4, db5=5, db6=6, db7=7;       // for all other devices
//#endif
//hd44780_pinIO lcd(rs, en, db4, db5, db6, db7);

//with backlight control:
//	backlight control requires two additional parameters
//	- an additional pin to control the backlight
//	- backlight active level which tells the library the level
//		needed to turn on the backlight.
//		note: If the backlight control pin supports PWM, dimming can be done
//			using setBacklight(dimvalue);
//
//	WARNING: some lcd keypads have a broken backlight circuit
//		If you have a lcd keypad, it is recommended that you first run the
//		LCDKeypadCheck sketch to verify that the backlight circuitry
//		is ok before enabling backlight control.
//		However, the hd44780_PinIO class will autodetect the issue and
//		work around it in s/w. If the backlight circuitry is broken,
//		dimming will not be possible even if the backlight pin supports PWM.
//
      #if defined (ARDUINO_ARCH_ESP8266)
      const int rs=D8, en=D9, db4=D4, db5=D5, db6=D6, db7=D7, bl=D10, blLevel=HIGH;
      #else
      const int rs=8, en=9, db4=4, db5=5, db6=6, db7=7, bl=10, blLevel=HIGH;
      #endif
    hd44780_pinIO lcd(rs, en, db4, db5, db6, db7, bl, blLevel);

// LCD geometry
const int LCD_COLS = 16;
const int LCD_ROWS = 2;

void setup()
{
	// initialize LCD with number of columns and rows: 
	//
	// note:
	//	begin() will automatically turn on the backlight if backlight
	// 	control is specified in the lcd object constructor
	//
	lcd.begin(LCD_COLS, LCD_ROWS);
	// if backlight control was specified, the backlight should be on now 

	// Print a message to the LCD
	lcd.print("Hello, World!");
}

void loop() {}

bumblepom: Bill: Is this "configur(ing) your lcd object constructor to include backlight parameters"?

Yes See the extra two parameters in the constructor? The back light pin and the active level.