Go Down

Topic: Warning to users of some vendors LCD keypad shields. (Read 280000 times) previous topic - next topic

bumblepom

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.

Code: [Select]
//
// 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);
}
}
}

bumblepom

#196
Sep 19, 2018, 11:15 am Last Edit: Sep 19, 2018, 11:39 am by bumblepom
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.

bperrybap

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

bumblepom

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.

Code: [Select]
// 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() {}

bperrybap

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.

bumblepom

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.

bperrybap

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.

Quote
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




bumblepom

...

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

bperrybap

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

nielyay

Quote
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?




bperrybap

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

nielyay

Quote
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.

Go Up