Files
Arduino/libraries/hd44780/examples/ioClass/hd44780_pinIO/LCDKeypadCheck/LCDKeypadCheck.ino
Jérôme Delacotte 7b30d6e298 first commit
2025-03-06 11:15:32 +01:00

264 lines
8.0 KiB
C++

//
// vi:ts=4
// ----------------------------------------------------------------------------
// LCDKeypadCheck - LCD keypad shield backlight circuitry test
// Copyright 2013-2020 Bill Perry
// bperrybap@opensource.billsworld.billandterrie.com
// ---------------------------------------------------------------------------
//
// LCDKeypadCheck is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation version 3 of the License.
//
// LCDKeypadCheck is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with LCDKeypadCheck. If not, see <http://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------------
//
// sketch to test lcd keypad shields for bad backlight circuitry
//
// See this Arduino forum thread for a discussion about the isue:
// http://forum.arduino.cc//index.php?topic=96747
//
// NOTE:
// As of 2016-11-12 in release 0.8.1 the hd44780_pinIO class now
// automatically detects broken backlight circuits and will use backlight
// control methods to protect the Arduino processor. The sketch can simply
// use all the backlight API functions setbacklight(), backlight(), and
// noBacklight() without concern.
//
// To use this sketch, fill in the proper pin assignements if they are
// different from below.
//
// upload the sketch.
// The LCD display will show whether the backlight circuit is good/bad.
//
// If the LCD shows that the backlight circuit is bad,
// it means that the backlight control circuit on the shield is a bad design
// and has a short circuit issue on the Arduino pin that controls the
// backlight circuit. (usually digital pin 10)
// This means that you need to be careful not to ever set the backlight control
// pin (D10) to HIGH as the high current draw could damage the Arduino processor.
//
// All is not lost, the shield can still be used and the backlight can still
// be controlled. Just keep in mind that unless the hardware is
// modified, some precautions must be taken when controlling the backlight.
// The main thing is that backlight control pin (digital pin 10) should
// never be set to HIGH.
// This means that PWM or analogWrite() cannot be used to dim the backlight.
//
// If you are happy with the backlight on all the time, then nothing needs to
// be done and you can use the LCD without backlight control.
//
// A simple software only solution for backlight on/off control
// is to set the backlight pin to INPUT to turn on the backlight and set the
// backlight pin to OUTPUT mode to turn the backlight off.
// If using hd44780 library 0.8.1 or newer the library will automatically
// do this for the sketch when the backlight API functions are used.
//
// History
// 2018.09.18 bperrybap - updated comments to clarify what
// "BL Circuit BAD" means
// 2017.01.07 bperrybap - updated comments to reflect that library now
// automatically detects bad backlight circuits
// 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
#elif defined(ARDUINO_ARCH_ESP32)
// esp32 espduino32 D1 R32 (uno form factor)
// note: GPIO12 needs a pulldown resistor
const int rs=12, en=13, db4=17, db5=16, db6=27, db7=14;
const int pin_BL=5; // gpio 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);
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 Arduino processor.
*/
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)
{
// note: esp32 core does not support analogWrite()
#if !defined(ARDUINO_ARCH_ESP32)
// 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);
}
}
#endif
}