diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index 3792842b..14f48b4a 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -34,10 +34,10 @@ For more information on these libraries, to report bugs, or to suggest
improvements, please contact the author Rhys Weatherley via
email.
-\section main_LCD Freetronics LCD Shield
+\section main_LCD LCD Shield
\li LCD class to manage the extended features of the Freetronics
-LCD shield.
+and DFRobot LCD shields.
\li Form and Field classes to build simple property sheet UI's on LCD displays.
\li \ref lcd_hello_world "Hello World" example for the Freetronics LCD shield.
\li \ref lcd_form "Form" example for LCD displays.
diff --git a/libraries/LCD/LCD.cpp b/libraries/LCD/LCD.cpp
index 7582b2bf..b6d6b49c 100644
--- a/libraries/LCD/LCD.cpp
+++ b/libraries/LCD/LCD.cpp
@@ -28,7 +28,7 @@
#include
#endif
-#define LCD_BACK_LIGHT 3 // LCD backlight is on D3
+#define LCD_BACK_LIGHT 3 // Default LCD backlight is on D3
#define LCD_BUTTON_PIN A0 // Button state is on A0
#define DEBOUNCE_DELAY 10 // Delay in ms to debounce buttons
@@ -73,10 +73,25 @@
* generic button has been pressed with button > 0 and if a
* generic button has been released with button < 0.
*
- * See the \ref lcd_hello_world "Hello World" example for more
- * information on using the LCD class.
+ * \section lcd_dfrobot Support for DFRobot LCD Shield
*
- * \sa Form
+ * The DFRobot LCD Shield
+ * is almost identical to the Freetronics shield, except it uses pin 10 for
+ * the back light instead of pin 3. This can be specified in the
+ * application's setup() function:
+ *
+ * \code
+ * LCD lcd;
+ *
+ * void setup() {
+ * lcd.setBacklightPin(10);
+ * }
+ * \endcode
+ *
+ * The back light pin is configured for output the first time the
+ * application calls getButton().
+ *
+ * \sa Form, \ref lcd_hello_world "Hello World Example"
*/
/**
@@ -117,9 +132,11 @@ void LCD::init()
// The Freetronics display is 16x2.
begin(16, 2);
- // Set the LCD back light to be initially on.
- pinMode(LCD_BACK_LIGHT, OUTPUT);
- digitalWrite(LCD_BACK_LIGHT, HIGH);
+ // Configure the backlight pin, but don't activate it yet in
+ // case the application sets it to something else during setup().
+ // Initialization will be forced in the first call to getButton().
+ _backlightPin = LCD_BACK_LIGHT;
+ backlightInit = false;
// Initialise button input.
pinMode(LCD_BUTTON_PIN, INPUT);
@@ -136,6 +153,47 @@ void LCD::init()
mode = DisplayOff;
}
+/**
+ * \fn uint8_t LCD::backlightPin() const
+ * \brief Returns the pin that is being used to control the back light.
+ * The default is 3.
+ *
+ * \sa setBacklightPin()
+ */
+
+/**
+ * \brief Sets the back light \a pin for the LCD shield.
+ *
+ * The DFRobot LCD Shield uses pin 10 for the back light instead of pin 3:
+ *
+ * \code
+ * LCD lcd;
+ *
+ * void setup() {
+ * lcd.setBacklightPin(10);
+ * }
+ * \endcode
+ *
+ * The back light pin is configured for output the next time the
+ * application calls getButton().
+ *
+ * \sa backlightPin()
+ */
+void LCD::setBacklightPin(uint8_t pin)
+{
+ if (_backlightPin != pin) {
+ if (backlightInit) {
+ // Restore the previous backlight pin to input, floating.
+ pinMode(_backlightPin, INPUT);
+ digitalWrite(_backlightPin, LOW);
+
+ // Need to re-initialize the backlight at the earliest opportunity.
+ backlightInit = false;
+ }
+ _backlightPin = pin;
+ }
+}
+
/**
* \brief Turns on the display of text on the LCD and the back light.
*
@@ -148,8 +206,10 @@ void LCD::init()
void LCD::display()
{
LiquidCrystal::display();
- digitalWrite(LCD_BACK_LIGHT, HIGH);
+ pinMode(_backlightPin, OUTPUT);
+ digitalWrite(_backlightPin, HIGH);
screenSaved = false;
+ backlightInit = true;
lastRestore = millis();
}
@@ -164,8 +224,10 @@ void LCD::noDisplay()
{
if (mode == DisplayOff)
LiquidCrystal::noDisplay();
- digitalWrite(LCD_BACK_LIGHT, LOW);
+ pinMode(_backlightPin, OUTPUT);
+ digitalWrite(_backlightPin, LOW);
screenSaved = true;
+ backlightInit = true;
}
/**
@@ -290,6 +352,10 @@ static prog_uint8_t const buttonMappings[] PROGMEM = {
*/
int LCD::getButton()
{
+ // Initialize the backlight for the first time if necessary.
+ if (!backlightInit)
+ display();
+
// Read the currently pressed button.
int button = mapButton(analogRead(LCD_BUTTON_PIN));
@@ -309,8 +375,10 @@ int LCD::getButton()
if (mode == BacklightOnSelect) {
// Turn on the back light only if Select was pressed.
if (button == LCD_BUTTON_SELECT) {
- digitalWrite(LCD_BACK_LIGHT, HIGH);
+ pinMode(_backlightPin, OUTPUT);
+ digitalWrite(_backlightPin, HIGH);
screenSaved = false;
+ backlightInit = true;
}
} else if (mode == DisplayOff) {
display();
diff --git a/libraries/LCD/LCD.h b/libraries/LCD/LCD.h
index 7d02c312..fba683c3 100644
--- a/libraries/LCD/LCD.h
+++ b/libraries/LCD/LCD.h
@@ -50,6 +50,9 @@ public:
LCD() : LiquidCrystal(8, 9, 4, 5, 6, 7) { init(); }
LCD(uint8_t pin9) : LiquidCrystal(8, pin9, 4, 5, 6, 7) { init(); }
+ uint8_t backlightPin() const { return _backlightPin; }
+ void setBacklightPin(uint8_t pin);
+
void display();
void noDisplay();
@@ -70,6 +73,8 @@ public:
int getButton();
private:
+ uint8_t _backlightPin;
+ bool backlightInit;
int prevButton;
int debounceButton;
unsigned long timeout;