Warning to users of some vendors LCD keypad shields.

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 
#include  // 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.

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

But the BL stays off.

Is it not possible, regardless of the SW work-around, that there is no connection between the BL and the pins to the Arduino (e.g. due to blown transistor)? I can detect no continuity between terminal K and any of the pins that connect the shield to the Arduino.

Since I do not want to plug the Shield into the Arduino anyway (I didn't realise the shield blotted out all the pins before I bought it - yes I'm new to Arduino but have been coding off and on since 1970 and worked with Picaxe). I will be using a free-standing LCD display for my real project and in the meantime for learning I've soldered a jumper to LCD terminal K which when earthed on the Arduino board works just fine. I guess, despite pin D10 working OK as an LED output, there may have been some damage between when the BL worked and when it didn't. I'll see.

bumblepom: But the BL stays off.

Looks like you fixed the small coding error in the constructor. (blLevel misspelled - that will be fixed in next release) That should have turned on the backlight when begin() is called.

Is it not possible, regardless of the SW work-around, that there is no connection between the BL and the pins to the Arduino (e.g. due to blown transistor)? I can detect no continuity between terminal K and any of the pins that connect the shield to the Arduino.

If your shield is the same design as the other ones we have seen, then you won't see any continuity between the LCD K pin and any Arduino pin because it isn't wired up that way. The K pin is wired to the collector of an NPN transistor and D10 is wired to the base. The issue is there there is no series resistor between D10 and the base of the transistor. See the schematic in the 1st post. The datasheet from the product link you provided: https://www.jaycar.com.au/medias/sys_master/images/9133746290718/XC4454-dataSheetMain.pdf does not mention using D10.

However the LCDKeypadCheck test would seem to indicate otherwise. It sets D10 to HIGH and then reads the pin. If the shield has an issue, D10 will not be HIGH because of a short through the transistor and the D10 signal is being yanked back low even though the AVR is trying to drive the pin high. Reading a LOW instead of a HIGH is what causes the LCDksypadCheck sketch to report a bad BL circuit. This is because something is yanking the D10 pin down and that shouldn't be happening. This can damage the AVR. The output of bad BL circuit on the LCD means the sketch has determined there is a short on D10 and concluded that the BL circuit is bad, not that any of damage has necessarily occurred.

Does the backlight blink when the diag test is run when the shield is plugged directly into the Arduino? If it reports a bad BL circuit but the backlight does not blink you have some other kind of actual h/w issue - beyond just the shield backlight circuit design issue.

It isn't clear how you have wired things up or if there were any temporary miswirings. It is possible that something done has damaged something. It is possible that the transistor has been blown by shorting K to ground. While shorting K to ground will light the backlight, it also puts a hard ground to the transistor collector since the K signal of the LCD is connected directly to the collector of the transistor.

D10 is connected directly to the base. If you shorted K to ground while D10 was high, then the transistor would be 100% on due to the short from D10 into the base through the transistor to the emitter. With K grounded which also grounds the collector you now have an infinite current load flowing through collector to the emitter. This might blow the transistor or perhaps even a trace on the PCB.

Unfortunately, that transistor is in a location under the LCD so you can't get to it without removing the LCD.

Now if you have measured the current when K is grounded and you are sure it is 30ma or less, and you don't intend to ever plug the shield into the Arduino, you could cheat and wire D10 directly to the K pin of the LCD instead of grounding K. That would give you backlight control and allow PWM dimming.

These days for a text LCD display, especially one that isn't going to be on a shield plugged into an Arduino, I'd use an I2C backpack. It only uses the 2 i2c pins. You can get them off ebay for about $1 USD shipped to your door.

--- bill

bperrybap: ...

Now if you have measured the current when K is grounded and you are sure it is 30ma or less, and you don't intend to ever plug the shield into the Arduino, you could cheat and wire D10 directly to the K pin of the LCD instead of grounding K. That would give you backlight control and allow PWM dimming.

These days for a text LCD display, especially one that isn't going to be on a shield plugged into an Arduino, I'd use an I2C backpack. It only uses the 2 i2c pins. You can get them off ebay for about $1 USD shipped to your door.

--- bill

I did measure the K to ground at 20 mA.. So I connected K directly to D10 --> BL off But when I reversed the code to < const int ... blLevel=LOW; > instead of HIGH, then the BL comes on.

And yes I will be moving to i2C and have a plain LCD and backpack in transit.

Thanks for your help.

Nelson

bumblepom: I did measure the K to ground at 20 mA.. So I connected K directly to D10 --> BL off But when I reversed the code to < const int ... blLevel=LOW; > instead of HIGH, then the BL comes on.

Ah oops. My mistake. Since the bl pin (D10) is connected to K, the backlight comes on when it is low vs high. So yes active level must be set to low, which tells the library to set the backlight pin low to turn on the backlight and high to turn it off.

With that correction, you should now be able to control the backlight with backlight()/noBacklight() and even do backlight dimming using setBacklight(dimlevel)

--- bill

Emartee: http://emartee.com/product/42054/Keypad%20LCD%20Shield%20V2.0%20%20Arduino%20Compatible http://emartee.com/product/41909/Keypad%20LCD%20Shield%20%20Arduino%20Compatible

Hello, Sorry for asking. Iam have the Keypad LCD Shield V2.0 and i have learn some tutorial page about it, but i need more learning this LCD, any suggestion program or links?

nielyay:
Hello,
Sorry for asking.
Iam have the Keypad LCD Shield V2.0 and i have learn some tutorial page about it, but i need more learning this LCD, any suggestion program or links?

That is outside the scope of this thread.
Those pages in the links you provided have the basic information on how the LCD, buttons, and headers are wired up to the shield.
I’d suggest for any further assistance to start a new thread.

— bill

Those pages in the links you provided have the basic information on how the LCD, buttons, and headers are wired up to the shield.

hello bill,

yes, i mean did you have any suggestion program for the LCD? i have try some program on the website.

I have a clone D1 ROBOT which doesn't have or at least I can not find a revison number. I run Bill's back light sketch and it report BL Bad.

The total current of the Arduino with LCD board mount is 70mA which doesn't seem excessive.

What was the original issue that has raised all this concern and suggested modifications? Nothing appears to be running hot after hours of running. So what was the flag that went up?