ArduinoLibs
LCD.cpp
00001 /*
00002  * Copyright (C) 2012 Southern Storm Software, Pty Ltd.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00019  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00020  * DEALINGS IN THE SOFTWARE.
00021  */
00022 
00023 #include "LCD.h"
00024 #include <avr/pgmspace.h>
00025 #if defined(ARDUINO) && ARDUINO >= 100
00026 #include <Arduino.h>
00027 #else
00028 #include <WProgram.h>
00029 #endif
00030 
00031 #define LCD_BACK_LIGHT          3        // LCD backlight is on D3
00032 #define LCD_BUTTON_PIN          A0       // Button state is on A0
00033 
00034 #define DEBOUNCE_DELAY          10      // Delay in ms to debounce buttons
00035 
00115 void LCD::init()
00116 {
00117     // The Freetronics display is 16x2.
00118     begin(16, 2);
00119 
00120     // Set the LCD back light to be initially on.
00121     pinMode(LCD_BACK_LIGHT, OUTPUT);
00122     digitalWrite(LCD_BACK_LIGHT, HIGH);
00123 
00124     // Initialise button input.
00125     pinMode(LCD_BUTTON_PIN, INPUT);
00126     digitalWrite(LCD_BUTTON_PIN, LOW);
00127     prevButton = LCD_BUTTON_NONE;
00128     debounceButton = LCD_BUTTON_NONE;
00129     lastDebounce = 0;
00130     eatRelease = false;
00131 
00132     // Initialize screen saver.
00133     timeout = 0;
00134     lastRestore = millis();
00135     screenSaved = false;
00136     mode = DisplayOff;
00137 }
00138 
00148 void LCD::display()
00149 {
00150     LiquidCrystal::display();
00151     digitalWrite(LCD_BACK_LIGHT, HIGH);
00152     screenSaved = false;
00153     lastRestore = millis();
00154 }
00155 
00163 void LCD::noDisplay()
00164 {
00165     if (mode == DisplayOff)
00166         LiquidCrystal::noDisplay();
00167     digitalWrite(LCD_BACK_LIGHT, LOW);
00168     screenSaved = true;
00169 }
00170 
00206 void LCD::setScreenSaverMode(ScreenSaverMode mode)
00207 {
00208     if (this->mode != mode) {
00209         this->mode = mode;
00210         if (screenSaved)
00211             noDisplay();
00212         else
00213             display();
00214     }
00215 }
00216 
00232 void LCD::enableScreenSaver(int timeoutSecs)
00233 {
00234     if (timeoutSecs < 0)
00235         timeout = 0;
00236     else
00237         timeout = ((unsigned long)timeoutSecs) * 1000;
00238     display();
00239 }
00240 
00246 void LCD::disableScreenSaver()
00247 {
00248     timeout = 0;
00249     display();
00250 }
00251 
00259 // Button mapping table generated by genlookup.c
00260 static prog_uint8_t const buttonMappings[] PROGMEM = {
00261     2, 0, 0, 0, 3, 0, 0, 0, 0, 4, 4, 0, 0, 0, 0, 1,
00262     1, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0
00263 };
00264 #define mapButton(value) (pgm_read_byte(&(buttonMappings[(value) >> 5])))
00265 
00291 int LCD::getButton()
00292 {
00293     // Read the currently pressed button.
00294     int button = mapButton(analogRead(LCD_BUTTON_PIN));
00295 
00296     // Debounce the button state.
00297     unsigned long currentTime = millis();
00298     if (button != debounceButton)
00299         lastDebounce = currentTime;
00300     debounceButton = button;
00301     if ((currentTime - lastDebounce) < DEBOUNCE_DELAY)
00302         button = prevButton;
00303 
00304     // Process the button event if the state has changed.
00305     if (prevButton == LCD_BUTTON_NONE && button != LCD_BUTTON_NONE) {
00306         prevButton = button;
00307         if (screenSaved) {
00308             // Button pressed when screen saver active.
00309             if (mode == BacklightOnSelect) {
00310                 // Turn on the back light only if Select was pressed.
00311                 if (button == LCD_BUTTON_SELECT) {
00312                     digitalWrite(LCD_BACK_LIGHT, HIGH);
00313                     screenSaved = false;
00314                 }
00315             } else if (mode == DisplayOff) {
00316                 display();
00317                 eatRelease = true;
00318                 return LCD_BUTTON_NONE;
00319             } else {
00320                 display();
00321             }
00322         } else if (mode == BacklightOnSelect && button != LCD_BUTTON_SELECT) {
00323             eatRelease = false;
00324             return button;
00325         }
00326         eatRelease = false;
00327         lastRestore = currentTime;
00328         return button;
00329     } else if (prevButton != LCD_BUTTON_NONE && button == LCD_BUTTON_NONE) {
00330         button = -prevButton;
00331         prevButton = LCD_BUTTON_NONE;
00332         lastRestore = currentTime;
00333         if (eatRelease) {
00334             eatRelease = false;
00335             return LCD_BUTTON_NONE;
00336         }
00337         return button;
00338     } else {
00339         if (!screenSaved && prevButton == LCD_BUTTON_NONE &&
00340                 timeout != 0 && (currentTime - lastRestore) >= timeout)
00341             noDisplay();    // Activate screen saver.
00342         return LCD_BUTTON_NONE;
00343     }
00344 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator