diff --git a/ATtiny85_Serial2LCD/ATtiny85_Serial2LCD.ino b/ATtiny85_Serial2LCD/ATtiny85_Serial2LCD.ino new file mode 100644 index 0000000..d084220 --- /dev/null +++ b/ATtiny85_Serial2LCD/ATtiny85_Serial2LCD.ino @@ -0,0 +1,371 @@ +//Import libraries that are being used +#include "LiquidCrystal595.h" //LCD controlled with sift register +#include //Control the lcd from a serial device +#include //Read and write settings that persist + +// --- EEPROM ADDRESS DEFINITIONS +#define LCD_BACKLIGHT_ADDRESS 1 // EEPROM address for backlight setting +#define BAUD_ADDRESS 2 // EEPROM address for Baud rate setting +#define SPLASH_SCREEN_ADDRESS 3 // EEPROM address for splash screen on/off +#define ROWS_ADDRESS 4 // EEPROM address for number of rows +#define COLUMNS_ADDRESS 5 // EEPROM address for number of columns + +// --- SPECIAL COMMAND DEFINITIONS +#define BACKLIGHT_COMMAND 128 // 0x80 +#define SPECIAL_COMMAND 254 // 0xFE +#define BAUD_COMMAND 129 // 0x81 + +// --- ARDUINO PIN DEFINITIONS +uint8_t dataPin = 0; +uint8_t latchPin = 1; +uint8_t clockPin = 2; + +char inKey; // Character received from serial input +uint8_t Cursor = 0; // Position of cursor, 0 is top left, (rows*columns)-1 is bottom right +uint8_t LCDOnOff = 1; // 0 if LCD is off +uint8_t blinky = 0; // Is 1 if blinky cursor is on +uint8_t underline = 0; // Is 1 if underline cursor is on +uint8_t splashScreenEnable = 1; // 1 means splash screen is enabled +uint8_t rows = 2; // Number rows, will be either 2 or 4 +uint8_t columns = 16; // Number of columns, will be 16 or 20 +uint8_t characters; // rows * columns + +// initialize the LCD at pins defined above +LiquidCrystal595 lcd(dataPin, latchPin, clockPin); + +// initialize the Serial port using the software serial library +SoftwareSerial input(3,4); //RX,TX + +/* ---------------------------------------------------------- + In the setup() function, we'll read the previous baud, + screen size, backlight brightness, and splash screen state + from EEPROM. Serial will be started at the proper baud, the + LCD will be initialized, backlight turned on, and splash + screen displayed (or not) according to the EEPROM states. + ----------------------------------------------------------*/ +void setup(){ + // initialize the serial communications: + setBaudRate(EEPROM.read(BAUD_ADDRESS)); + + // Read rows and columns from EEPROM + // Will default to 2x16, if not previously set + rows = EEPROM.read(ROWS_ADDRESS); + if (rows != 4) + rows = 2; + columns = EEPROM.read(COLUMNS_ADDRESS); + if (columns != 20) + columns = 16; + + // set up the LCD's number of rows and columns: + lcd.begin(columns, rows); + + // Set up the backlight + //EEPROM.write(LCD_BACKLIGHT_ADDRESS, true); + //setBacklight(EEPROM.read(LCD_BACKLIGHT_ADDRESS)); + setBacklight(true); + + // Do splashscreen if set + splashScreenEnable = EEPROM.read(SPLASH_SCREEN_ADDRESS); + if (splashScreenEnable!=0) + { + if (columns == 16) + { + lcd.setCursor(0, 0); + lcd.print("Arduino Phone"); + delay(800); + lcd.setCursor(0, 1); + lcd.print("Booting"); + delay(400); + lcd.setCursor(0, 1); + lcd.print("Booting."); + delay(400); + lcd.setCursor(0, 1); + lcd.print("Booting.."); + delay(400); + lcd.setCursor(0, 1); + lcd.print("Booting..."); + delay(1000); + lcd.clear(); + } + else + { + lcd.setCursor(0, 1); + lcd.print(" www.SparkFun.com "); + lcd.setCursor(0, 2); + lcd.print(" Serial LCD Kit "); + delay(2000); + lcd.clear(); + } + } +} + +/*---------------------------------------------------------- + In loop(), we wait for a serial character to be + received. Once received, the character is checked against + all the special commands if it's not a special command the + character (or tab, line feed, etc.) is displayed. If it is + a special command another loop will be entered and we'll + again wait for any further characters that are needed to + finish the command. + ----------------------------------------------------------*/ +void loop() +{ + while (input.available() > 0) { + inKey = input.read(); + // Check for special LCD command + if ((inKey&0xFF) == SPECIAL_COMMAND) + SpecialCommands(); + // Backlight control + else if ((inKey&0xFF) == BACKLIGHT_COMMAND) + { + // Wait for the next character + while(input.available() == 0) + ; + setBacklight(input.read()); + } + // baud rate control + else if ((inKey&0xFF) == BAUD_COMMAND) + { + // Wait for the next character + while(input.available() == 0) + ; + setBaudRate(input.read()); + } + // backspace + else if (inKey == 8) + { + Cursor--; + LCDDisplay(0x20); + Cursor--; + } + // horizontal tab + else if (inKey == 9) + Cursor += 5; + // line feed + else if (inKey == 10) + Cursor += columns - Cursor%columns; + // carriage return + else if (inKey == 13) + Cursor += columns; + // finally (since no special commad received), just display the received character + else + LCDDisplay(inKey); + } +} + +/* ---------------------------------------------------------- + SpecialCommands() is reached if SPECIAL_COMMAND is received. + This function will wait for another character from the serial + input and then perform the desired command. If a command is + not recognized, nothing further happens and we jump back into + loop(). + ----------------------------------------------------------*/ +void SpecialCommands() +{ + // Wait for the next character + while(input.available() == 0); + + inKey = input.read(); + // Clear Display + if (inKey == 1) + { + Cursor = 0; + lcd.clear(); + } + // Move cursor right one + else if (inKey == 20) + Cursor++; + // Move cursor left one + else if (inKey == 16) + Cursor--; + // Scroll right + else if (inKey == 28) + lcd.scrollDisplayRight(); + // Scroll left + else if (inKey == 24) + lcd.scrollDisplayLeft(); + // Turn display on + else if ((inKey == 12)&&(LCDOnOff==0)) + { + LCDOnOff = 1; + lcd.display(); + } + // Turn display off + else if (inKey == 8) + { + LCDOnOff = 0; + lcd.noDisplay(); + } + // Underline Cursor on + else if (inKey == 14) + { + underline = 1; + blinky = 0; + lcd.noBlink(); + lcd.cursor(); + } + // Underline Cursor off + else if ((inKey == 12)&&(underline==1)) + { + underline = 0; + lcd.noCursor(); + } + // Blinking box cursor on + else if (inKey == 13) + { + lcd.noCursor(); + lcd.blink(); + blinky = 1; + underline = 0; + } + // Blinking box cursor off + else if ((inKey == 12)&&(blinky=1)) + { + blinky = 0; + lcd.noBlink(); + } + // Set Cursor position + else if ((inKey&0xFF) == 128) + { + // Wait for the next character + while(input.available() == 0) + ; + inKey = input.read(); + Cursor = inKey; + } + else if (inKey == 30) + { + if (splashScreenEnable) + splashScreenEnable = 0; + else + splashScreenEnable = 1; + EEPROM.write(SPLASH_SCREEN_ADDRESS, splashScreenEnable); + } + else if (inKey == 3) + { + // 20 columns + columns = 20; + EEPROM.write(COLUMNS_ADDRESS, columns); + lcd.begin(columns, rows); + Cursor = 0; + } + else if (inKey == 4) + { + // 16 columns + columns = 16; + EEPROM.write(COLUMNS_ADDRESS, columns); + lcd.begin(columns, rows); + Cursor = 0; + } + else if (inKey == 5) + { + // 4 lines + rows = 4; + EEPROM.write(ROWS_ADDRESS, rows); + lcd.begin(columns, rows); + Cursor = 0; + } + else if (inKey == 6) + { + // 2 lines + rows = 2; + EEPROM.write(ROWS_ADDRESS, rows); + lcd.begin(columns, rows); + Cursor = 0; + } +} + +/* ---------------------------------------------------------- + LCDDisplay() receives a single character and displays it + depending on what value is in Cursor. We also do a bit of + manipulation on Cursor, if it is beyond the screen size. + Finally the Cursor is advanced one value, before the function + is exited. + ----------------------------------------------------------*/ +void LCDDisplay(char character) +{ + int currentRow = 0; + characters = rows * columns; + + // If Cursor is beyond screen size, get it right + while (Cursor >= characters) + Cursor -= characters; + while (Cursor < 0) + Cursor += characters; + + if (Cursor >= columns) + currentRow = Cursor/columns; + + lcd.setCursor(Cursor%columns, currentRow); + lcd.write(character); + + Cursor++; +} + +/* ---------------------------------------------------------- + setBacklight() is called from SpecialCommands(). It receives + a backlight setting between 0 and 255. The backlight is set + accordingly (via analogWrite()). Before exit the new backlight + value is written to EEPROM. + ----------------------------------------------------------*/ +void setBacklight(boolean backlightSetting) +{ + lcd.setLED1Pin(backlightSetting); + lcd.print(" "); + EEPROM.write(LCD_BACKLIGHT_ADDRESS, backlightSetting); +} + +/* ---------------------------------------------------------- + setBaudRate() is called from SpecialCommands(). It receives + a baud rate setting balue that should be between 0 and 10. + The baud rate is then set accordingly, and the new value is + written to EEPROM. If the EEPROM value hasn't been written + before (255), this function will default to 9600. If the value + is out of bounds 10=0)&&(baudSetting<=10)) + EEPROM.write(BAUD_ADDRESS, baudSetting); +} + diff --git a/ATtiny85_Serial2LCD/LiquidCrystal595.cpp b/ATtiny85_Serial2LCD/LiquidCrystal595.cpp new file mode 100755 index 0000000..a9d05bb --- /dev/null +++ b/ATtiny85_Serial2LCD/LiquidCrystal595.cpp @@ -0,0 +1,454 @@ +/* ----------------------------------------------------------------------------------- + * $Author: robaby@gmail.com $ + * $Date: 2012-04-08 23:54:07 +0100 (Sun, 08 Apr 2012) $ + * $Revision: 4 $ + * ---------------------------------- + * + * Full Information: + * Code and Breadboarding: http://rowansimms.com/article.php/lcd-hookup-in-seconds + * Make your own Shield: http://rowansimms.com/article.php/lcd-hookup-in-seconds-shield + * + * Adaption of the LiquidCrystal library shipped with Arduino 22, + * now updated for Arduino 1.0. + * Code originally developed by Steve Hobley - February 2011 + * updates and maintenance by Rowan Simms code@rowansimms.com + * + * Changes Log: + * v1.0 + * - Now works with Arduino 1.0 (not backwards compatible) + * - Re-ordered Shift Register Pinouts to allow for better prototyping + * + * + * ---Shift Register 74HC595--- + * [SR Pin 14 (DS)] to Arduino pin - [datapin] + * [SR Pin 12 (ST_CP)] to Arduino pin - [latchpin] + * [SR Pin 11 (SH_CP)] to Arduino pin - [clockpin] + * Black wire to Ground + * Red wire to +5v + * + * -----Shift Reg to LCD-------- + * SR Pin 15 - ENABLE 10000000 + * SR Pin 1 - D7 00000010 + * SR Pin 2 - D6 00000100 + * SR Pin 3 - D5 00001000 + * SR Pin 4 - D4 00010000 + * SR Pin 5 - MOSFET / LED1 00100000 + * SR Pin 6 - LED 2 01000000 + * SR Pin 7 - RS 00000001 + * + * ----------------------------------------------------------------------------------- + */ +// 595 mappings - LED1 is also the backlight controller + +#define ENABLE_PIN B00000001 +#define RS_PIN B10000000 +#define LED1_PIN B00100000 +#define LED2_PIN B01000000 +#define DATABITS B00011110 +#define PIN_D4 B00010000 +#define PIN_D5 B00001000 +#define PIN_D6 B00000100 +#define PIN_D7 B00000010 + +#include "LiquidCrystal595.h" + +#include +#include +#include +#include "Arduino.h" + +// When the display powers up, it is configured as follows: +// +// 1. Display clear +// 2. Function set: +// DL = 1; 8-bit interface data +// N = 0; 1-line display +// F = 0; 5x8 dot character font +// 3. Display on/off control: +// D = 0; Display off +// C = 0; Cursor off +// B = 0; Blinking off +// 4. Entry mode set: +// I/D = 1; Increment by 1 +// S = 0; No shift +// +// Note, however, that resetting the Arduino doesn't reset the LCD, so we +// can't assume that its in that state when a sketch starts (and the +// LiquidCrystal constructor is called). + +LiquidCrystal595::LiquidCrystal595(uint8_t datapin, uint8_t latchpin, uint8_t clockpin) +{ + init(datapin, latchpin, clockpin); +} + +// Performs the shift, MSB first +void LiquidCrystal595::shift595() +{ + digitalWrite(_latchpin, LOW); + shiftOut(_datapin, _clockpin, MSBFIRST, _register); + digitalWrite(_latchpin, HIGH); +} + +void LiquidCrystal595::init(uint8_t datapin, uint8_t latchpin, uint8_t clockpin) +{ + _datapin = datapin; + _latchpin = latchpin; + _clockpin = clockpin; + + pinMode(_datapin, OUTPUT); + pinMode(_latchpin, OUTPUT); + pinMode(_clockpin, OUTPUT); + + _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS; + + begin(16, 1); +} + +void LiquidCrystal595::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) +{ + + if (lines > 1) + { + _displayfunction |= LCD_2LINE; + } + _numlines = lines; + _currline = 0; + + // for some 1 line displays you can select a 10 pixel high font + if ((dotsize != 0) && (lines == 1)) { + _displayfunction |= LCD_5x10DOTS; + } + + // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION! + // according to datasheet, we need at least 40ms after power rises above 2.7V + // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50 + delayMicroseconds(50000); + // Now we pull both RS and R/W low to begin commands + + setRSPin(LOW); + setEPin(LOW); + shift595(); + + //digitalWrite(_rs_pin, LOW); + //digitalWrite(_enable_pin, LOW); + + //if (_rw_pin != 255) { + // digitalWrite(_rw_pin, LOW); + //} + + //put the LCD into 4 bit or 8 bit mode + if (! (_displayfunction & LCD_8BITMODE)) + { + // this is according to the hitachi HD44780 datasheet + // figure 24, pg 46 + + // we start in 8bit mode, try to set 4 bit mode + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // second try + write4bits(0x03); + delayMicroseconds(4500); // wait min 4.1ms + + // third go! + write4bits(0x03); + delayMicroseconds(150); + + // finally, set to 4-bit interface + write4bits(0x02); + } else { + // this is according to the hitachi HD44780 datasheet + // page 45 figure 23 + + // Send function set command sequence + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(4500); // wait more than 4.1ms + + // second try + command(LCD_FUNCTIONSET | _displayfunction); + delayMicroseconds(150); + + // third go + command(LCD_FUNCTIONSET | _displayfunction); + } + + // finally, set # lines, font size, etc. + command(LCD_FUNCTIONSET | _displayfunction); + + // turn the display on with no cursor or blinking default + _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF; + display(); + + // clear it off + clear(); + + // Initialize to default text direction (for romance languages) + _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT; + // set the entry mode + command(LCD_ENTRYMODESET | _displaymode); + +} + +/********** high level commands, for the user! */ +void LiquidCrystal595::clear() +{ + command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal595::home() +{ + command(LCD_RETURNHOME); // set cursor position to zero + delayMicroseconds(2000); // this command takes a long time! +} + +void LiquidCrystal595::setCursor(uint8_t col, uint8_t row) +{ + int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 }; + if ( row > _numlines ) { + row = _numlines-1; // we count rows starting w/0 + } + + command(LCD_SETDDRAMADDR | (col + row_offsets[row])); +} + +// Turn the display on/off (quickly) +void LiquidCrystal595::noDisplay() { + _displaycontrol &= ~LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal595::display() { + _displaycontrol |= LCD_DISPLAYON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turns the underline cursor on/off +void LiquidCrystal595::noCursor() { + _displaycontrol &= ~LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal595::cursor() { + _displaycontrol |= LCD_CURSORON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// Turn on and off the blinking cursor +void LiquidCrystal595::noBlink() { + _displaycontrol &= ~LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} +void LiquidCrystal595::blink() { + _displaycontrol |= LCD_BLINKON; + command(LCD_DISPLAYCONTROL | _displaycontrol); +} + +// These commands scroll the display without changing the RAM +void LiquidCrystal595::scrollDisplayLeft(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT); +} +void LiquidCrystal595::scrollDisplayRight(void) { + command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT); +} + +// This is for text that flows Left to Right +void LiquidCrystal595::leftToRight(void) { + _displaymode |= LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This is for text that flows Right to Left +void LiquidCrystal595::rightToLeft(void) { + _displaymode &= ~LCD_ENTRYLEFT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'right justify' text from the cursor +void LiquidCrystal595::autoscroll(void) { + _displaymode |= LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// This will 'left justify' text from the cursor +void LiquidCrystal595::noAutoscroll(void) { + _displaymode &= ~LCD_ENTRYSHIFTINCREMENT; + command(LCD_ENTRYMODESET | _displaymode); +} + +// Allows us to fill the first 8 CGRAM locations +// with custom characters +void LiquidCrystal595::createChar(uint8_t location, uint8_t charmap[]) { + location &= 0x7; // we only have 8 locations 0-7 + command(LCD_SETCGRAMADDR | (location << 3)); + for (int i=0; i<8; i++) { + write(charmap[i]); + } +} + +/*********** mid level commands, for sending data/cmds */ + +inline void LiquidCrystal595::command(uint8_t value) { + send(value, LOW); +} + +inline size_t LiquidCrystal595::write(uint8_t value) { + send(value, HIGH); +} + +/************ low level data pushing commands **********/ + +// write either command or data, with automatic 4/8-bit selection +void LiquidCrystal595::send(uint8_t value, uint8_t mode) +{ + setRSPin(mode); + shift595(); + + //digitalWrite(_rs_pin, mode); + + // if there is a RW pin indicated, set it low to Write + //if (_rw_pin != 255) { + // digitalWrite(_rw_pin, LOW); + //} + + if (_displayfunction & LCD_8BITMODE) + { + write8bits(value); + } + else + { + write4bits(value>>4); + write4bits(value); + } +} + +void LiquidCrystal595::pulseEnable(void) +{ + // LOW / HIGH / LOW of ENABLE_PIN + setEPin(LOW); // LOW + shift595(); + + delayMicroseconds(1); + setEPin(HIGH); // HIGH + shift595(); + + delayMicroseconds(1); // enable pulse must be >450ns + + setEPin(LOW); // LOW + shift595(); + delayMicroseconds(100); // commands need > 37us to settle +} + +void LiquidCrystal595::write4bits(uint8_t value) +{ + int val_nibble= value & 0x0F; //clean the value. (unnecessary) + + setD4Pin(val_nibble & 01); + val_nibble >>= 1; + setD5Pin(val_nibble & 01); + val_nibble >>= 1; + setD6Pin(val_nibble & 01); + val_nibble >>= 1; + setD7Pin(val_nibble & 01); + + pulseEnable(); +} + +void LiquidCrystal595::write8bits(uint8_t value) +{ + return; + // Should not be used +} + +// Accessor functions -------------------------------------------------------- +void LiquidCrystal595::setLED1Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= LED1_PIN; // HIGH + } + else + { + _register &= ~LED1_PIN; // LOW + } +} + +void LiquidCrystal595::setLED2Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= LED2_PIN; // HIGH + } + else + { + _register &= ~LED2_PIN; // LOW + } +} + +void LiquidCrystal595::setEPin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= ENABLE_PIN; // HIGH + } + else + { + _register &= ~ENABLE_PIN; // LOW + } +} + +void LiquidCrystal595::setD4Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= PIN_D4; // HIGH + } + else + { + _register &= ~PIN_D4; // LOW + } +} + +void LiquidCrystal595::setD5Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= PIN_D5; // HIGH + } + else + { + _register &= ~PIN_D5; // LOW + } +} +void LiquidCrystal595::setD6Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= PIN_D6; // HIGH + } + else + { + _register &= ~PIN_D6; // LOW + } +} +void LiquidCrystal595::setD7Pin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= PIN_D7; // HIGH + } + else + { + _register &= ~PIN_D7; // LOW + } +} + +void LiquidCrystal595::setRSPin(uint8_t pinValue) +{ + if (pinValue == HIGH) + { + _register |= RS_PIN; // HIGH + } + else + { + _register &= ~RS_PIN; // LOW + } +} diff --git a/ATtiny85_Serial2LCD/LiquidCrystal595.h b/ATtiny85_Serial2LCD/LiquidCrystal595.h new file mode 100755 index 0000000..78136ec --- /dev/null +++ b/ATtiny85_Serial2LCD/LiquidCrystal595.h @@ -0,0 +1,145 @@ +/* ----------------------------------------------------------------------------------- + * $Author: robaby@gmail.com $ + * $Date: 2012-04-08 23:54:07 +0100 (Sun, 08 Apr 2012) $ + * $Revision: 4 $ + * ---------------------------------- + * + * Full Information: + * Code and Breadboarding: http://rowansimms.com/article.php/lcd-hookup-in-seconds + * Make your own Shield: http://rowansimms.com/article.php/lcd-hookup-in-seconds-shield + * + * Adaption of the LiquidCrystal library shipped with Arduino 22, + * now updated for Arduino 1.0. + * Code originally developed by Steve Hobley - February 2011 + * updates and maintenance by Rowan Simms code@rowansimms.com + * + * Changes Log: + * v1.0 + * - Now works with Arduino 1.0 (not backwards compatible) + * - Re-ordered Shift Register Pinouts to allow for better prototyping + * + * + * ---Shift Register 74HC595--- + * [SR Pin 14 (DS)] to Arduino pin - [datapin] + * [SR Pin 12 (ST_CP)] to Arduino pin - [latchpin] + * [SR Pin 11 (SH_CP)] to Arduino pin - [clockpin] + * Black wire to Ground + * Red wire to +5v + * + * -----Shift Reg to LCD-------- + * SR Pin 15 - ENABLE 10000000 + * SR Pin 1 - D7 00000010 + * SR Pin 2 - D6 00000100 + * SR Pin 3 - D5 00001000 + * SR Pin 4 - D4 00010000 + * SR Pin 5 - MOSFET / LED1 00100000 + * SR Pin 6 - LED 2 01000000 + * SR Pin 7 - RS 00000001 + * + * ----------------------------------------------------------------------------------- + */ +#ifndef LiquidCrystal595_h +#define LiquidCrystal595_h + +#include +#include "Print.h" + +// commands +#define LCD_CLEARDISPLAY 0x01 +#define LCD_RETURNHOME 0x02 +#define LCD_ENTRYMODESET 0x04 +#define LCD_DISPLAYCONTROL 0x08 +#define LCD_CURSORSHIFT 0x10 +#define LCD_FUNCTIONSET 0x20 +#define LCD_SETCGRAMADDR 0x40 +#define LCD_SETDDRAMADDR 0x80 + +// flags for display entry mode +#define LCD_ENTRYRIGHT 0x00 +#define LCD_ENTRYLEFT 0x02 +#define LCD_ENTRYSHIFTINCREMENT 0x01 +#define LCD_ENTRYSHIFTDECREMENT 0x00 + +// flags for display on/off control +#define LCD_DISPLAYON 0x04 +#define LCD_DISPLAYOFF 0x00 +#define LCD_CURSORON 0x02 +#define LCD_CURSOROFF 0x00 +#define LCD_BLINKON 0x01 +#define LCD_BLINKOFF 0x00 + +// flags for display/cursor shift +#define LCD_DISPLAYMOVE 0x08 +#define LCD_CURSORMOVE 0x00 +#define LCD_MOVERIGHT 0x04 +#define LCD_MOVELEFT 0x00 + +// flags for function set +#define LCD_8BITMODE 0x10 +#define LCD_4BITMODE 0x00 +#define LCD_2LINE 0x08 +#define LCD_1LINE 0x00 +#define LCD_5x10DOTS 0x04 +#define LCD_5x8DOTS 0x00 + +class LiquidCrystal595 : public Print { +public: + LiquidCrystal595(uint8_t datapin, uint8_t latchpin, uint8_t clockpin); + + void init(uint8_t datapin, uint8_t latchpin, uint8_t clockpin); + + void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); + + void clear(); + void home(); + + void noDisplay(); + void display(); + void noBlink(); + void blink(); + void noCursor(); + void cursor(); + void scrollDisplayLeft(); + void scrollDisplayRight(); + void leftToRight(); + void rightToLeft(); + void autoscroll(); + void noAutoscroll(); + + void createChar(uint8_t, uint8_t[]); + void setCursor(uint8_t, uint8_t); + virtual size_t write(uint8_t); + void command(uint8_t); + + // Moved to public - to aid with debugging, and other uses for the library etc... + void setRSPin(uint8_t pinValue); + void setEPin(uint8_t pinValue); + void setD4Pin(uint8_t pinValue); + void setD5Pin(uint8_t pinValue); + void setD6Pin(uint8_t pinValue); + void setD7Pin(uint8_t pinValue); + void setLED1Pin(uint8_t pinValue); + void setLED2Pin(uint8_t pinValue); + void shift595(); + +private: + void send(uint8_t, uint8_t); + void write4bits(uint8_t); + void write8bits(uint8_t); + void pulseEnable(); + + uint8_t _datapin; + uint8_t _latchpin; + uint8_t _clockpin; + char _register; //Stores the current state of the data + + uint8_t _displayfunction; + uint8_t _displaycontrol; + uint8_t _displaymode; + + uint8_t _initialized; + + uint8_t _numlines,_currline; +}; + +#endif diff --git a/ATtiny85_Serial2LCD/keywords.txt b/ATtiny85_Serial2LCD/keywords.txt new file mode 100755 index 0000000..28a1ef7 --- /dev/null +++ b/ATtiny85_Serial2LCD/keywords.txt @@ -0,0 +1,37 @@ +####################################### +# Syntax Coloring Map For LiquidCrystal +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LiquidCrystal KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +clear KEYWORD2 +home KEYWORD2 +print KEYWORD2 +setCursor KEYWORD2 +cursor KEYWORD2 +noCursor KEYWORD2 +blink KEYWORD2 +noBlink KEYWORD2 +display KEYWORD2 +noDisplay KEYWORD2 +autoscroll KEYWORD2 +noAutoscroll KEYWORD2 +leftToRight KEYWORD2 +rightToLeft KEYWORD2 +scrollDisplayLeft KEYWORD2 +scrollDisplayRight KEYWORD2 +createChar KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/README.md b/README.md index 53566c7..1a7309a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,13 @@ Serial-LCD ========== -Controlling a 16x2 LCD using an ATtiny85 & 74HC595 Shift Register +Controlling a 16x2 LCD using an ATtiny85 & 74HC595 Shift Register + +Necessary Items: + +16x2 LCD Display +ATtiny85 Microcontroller with Programmer +74HC595 Shift Register +NPN Transistor +10K Potentiometer +Jumper Wires & Breadboard \ No newline at end of file diff --git a/Serial LCD with Shift Register & ATtiny85.pdf b/Serial LCD with Shift Register & ATtiny85.pdf new file mode 100644 index 0000000..2ba30c0 Binary files /dev/null and b/Serial LCD with Shift Register & ATtiny85.pdf differ