ArduinoLibs
|
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 }