Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Putting all LCD related features in a wrapper lib around the Arduino'…

…s basic LCD library
  • Loading branch information...
commit 93481595681802d0eec4523e866d3d09d72fa4db 1 parent e170b2e
@reefab authored
Showing with 26,347 additions and 0 deletions.
  1. +3 −0  .gitignore
  2. +267 −0 lib/LiquidCrystal/FastIO.cpp
  3. +219 −0 lib/LiquidCrystal/FastIO.h
  4. +198 −0 lib/LiquidCrystal/I2CIO.cpp
  5. +148 −0 lib/LiquidCrystal/I2CIO.h
  6. +347 −0 lib/LiquidCrystal/LCD.cpp
  7. +536 −0 lib/LiquidCrystal/LCD.h
  8. +299 −0 lib/LiquidCrystal/LiquidCrystal.cpp
  9. +161 −0 lib/LiquidCrystal/LiquidCrystal.h
  10. +291 −0 lib/LiquidCrystal/LiquidCrystal_I2C.cpp
  11. +204 −0 lib/LiquidCrystal/LiquidCrystal_I2C.h
  12. +209 −0 lib/LiquidCrystal/LiquidCrystal_SR.cpp
  13. +176 −0 lib/LiquidCrystal/LiquidCrystal_SR.h
  14. +135 −0 lib/LiquidCrystal/LiquidCrystal_SR2W.cpp
  15. +202 −0 lib/LiquidCrystal/LiquidCrystal_SR2W.h
  16. +283 −0 lib/LiquidCrystal/LiquidCrystal_SR3W.cpp
  17. +202 −0 lib/LiquidCrystal/LiquidCrystal_SR3W.h
  18. +1,749 −0 lib/LiquidCrystal/docs/Doxyfile
  19. +7,432 −0 lib/LiquidCrystal/docs/def/doxygen.def
  20. +2,897 −0 lib/LiquidCrystal/docs/def/doxygen.def.txt
  21. +549 −0 lib/LiquidCrystal/docs/html/_fast_i_o_8cpp.html
  22. +351 −0 lib/LiquidCrystal/docs/html/_fast_i_o_8cpp_source.html
  23. +786 −0 lib/LiquidCrystal/docs/html/_fast_i_o_8h.html
  24. +209 −0 lib/LiquidCrystal/docs/html/_fast_i_o_8h_source.html
  25. +92 −0 lib/LiquidCrystal/docs/html/_i2_c_i_o_8cpp.html
  26. +282 −0 lib/LiquidCrystal/docs/html/_i2_c_i_o_8cpp_source.html
  27. +114 −0 lib/LiquidCrystal/docs/html/_i2_c_i_o_8h.html
  28. +147 −0 lib/LiquidCrystal/docs/html/_i2_c_i_o_8h_source.html
  29. +93 −0 lib/LiquidCrystal/docs/html/_l_c_d_8cpp.html
  30. +431 −0 lib/LiquidCrystal/docs/html/_l_c_d_8cpp_source.html
  31. +711 −0 lib/LiquidCrystal/docs/html/_l_c_d_8h.html
  32. +301 −0 lib/LiquidCrystal/docs/html/_l_c_d_8h_source.html
  33. +146 −0 lib/LiquidCrystal/docs/html/_liquid_crystal_8cpp.html
  34. +383 −0 lib/LiquidCrystal/docs/html/_liquid_crystal_8cpp_source.html
  35. +117 −0 lib/LiquidCrystal/docs/html/_liquid_crystal_8h.html
  36. +176 −0 lib/LiquidCrystal/docs/html/_liquid_crystal_8h_source.html
  37. +247 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___i2_c_8cpp.html
  38. +344 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___i2_c_8cpp_source.html
  39. +97 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___i2_c_8h.html
  40. +172 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___i2_c_8h_source.html
  41. +89 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r2_w_8cpp.html
  42. +219 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r2_w_8cpp_source.html
  43. +164 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r2_w_8h.html
  44. +245 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r2_w_8h_source.html
  45. +249 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r3_w_8cpp.html
  46. +336 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r3_w_8cpp_source.html
  47. +96 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r3_w_8h.html
  48. +201 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r3_w_8h_source.html
  49. +94 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r_8cpp.html
  50. +293 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r_8cpp_source.html
  51. +148 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r_8h.html
  52. +210 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r_8h_source.html
  53. +147 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r___l_c_d3_8cpp.html
  54. +295 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r___l_c_d3_8cpp_source.html
  55. +95 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r___l_c_d3_8h.html
  56. +129 −0 lib/LiquidCrystal/docs/html/_liquid_crystal___s_r___l_c_d3_8h_source.html
  57. +95 −0 lib/LiquidCrystal/docs/html/annotated.html
  58. BIN  lib/LiquidCrystal/docs/html/bc_s.png
  59. +95 −0 lib/LiquidCrystal/docs/html/class_i2_c_i_o-members.html
  60. +339 −0 lib/LiquidCrystal/docs/html/class_i2_c_i_o.html
  61. +120 −0 lib/LiquidCrystal/docs/html/class_l_c_d-members.html
  62. +982 −0 lib/LiquidCrystal/docs/html/class_l_c_d.html
  63. BIN  lib/LiquidCrystal/docs/html/class_l_c_d.png
Sorry, we could not display the entire diff because it was too big.
View
3  .gitignore
@@ -2,3 +2,6 @@
config.h
.build
ino.ini
+
+*.gch
+/src/tags
View
267 lib/LiquidCrystal/FastIO.cpp
@@ -0,0 +1,267 @@
+// ---------------------------------------------------------------------------
+// Created by Florian Fida on 20/01/12
+// Copyright 2012 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+// http://creativecommons.org/licenses/by-sa/3.0/
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+// ---------------------------------------------------------------------------
+// fio_shiftOut1 functions are based on Shif1 protocol developed by Roman Black
+// (http://www.romanblack.com/shift1.htm)
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file FastIO.h
+// This file implements basic fast IO routines.
+//
+// @brief
+//
+// @version API 1.0.0
+//
+// @author Florian Fida -
+//
+// 2012-03-16 bperrybap updated fio_shiftout() to be smaller & faster
+//
+// @todo:
+// support chipkit:
+// (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/
+// cores/pic32/wiring_digital.c)
+// ---------------------------------------------------------------------------
+#include "FastIO.h"
+
+
+fio_register fio_pinToOutputRegister(uint8_t pin, uint8_t initial_state)
+{
+ pinMode(pin, OUTPUT);
+
+ if(initial_state != SKIP)
+ {
+ digitalWrite(pin, initial_state); // also turns off pwm timer
+ }
+#ifdef FIO_FALLBACK
+ // just wasting memory if not using fast io...
+ return 0;
+#else
+ return portOutputRegister(digitalPinToPort(pin));
+#endif
+}
+
+
+fio_register fio_pinToInputRegister(uint8_t pin)
+{
+ pinMode(pin, INPUT);
+ digitalWrite(pin, LOW); // also turns off pwm timer and pullup
+#ifdef FIO_FALLBACK
+ // just wasting memory if not using fast io...
+ return 0;
+#else
+ return portInputRegister(digitalPinToPort(pin));
+#endif
+}
+
+
+fio_bit fio_pinToBit(uint8_t pin)
+{
+#ifdef FIO_FALLBACK
+ // (ab)use the bit variable to store the pin
+ return pin;
+#else
+ return digitalPinToBitMask(pin);
+#endif
+}
+
+
+void fio_digitalWrite(fio_register pinRegister, fio_bit pinBit, uint8_t value)
+{
+#ifdef FIO_FALLBACK
+ digitalWrite(pinBit, value);
+#else
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ if(value == LOW)
+ {
+ fio_digitalWrite_LOW(pinRegister,pinBit);
+ }
+ else
+ {
+ fio_digitalWrite_HIGH(pinRegister,pinBit);
+ }
+ }
+#endif
+}
+
+int fio_digitalRead(fio_register pinRegister, uint8_t pinBit)
+{
+#ifdef FIO_FALLBACK
+ return digitalRead (pinBit);
+#else
+ if (*pinRegister & pinBit)
+ {
+ return HIGH;
+ }
+ return LOW;
+#endif
+}
+
+void fio_shiftOut (fio_register dataRegister, fio_bit dataBit,
+ fio_register clockRegister, fio_bit clockBit,
+ uint8_t value, uint8_t bitOrder)
+{
+ // # disable interrupts
+ int8_t i;
+
+ if(bitOrder == LSBFIRST)
+ {
+ for(i = 0; i < 8; i++)
+ {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ if(value & 1)
+ {
+ fio_digitalWrite_HIGH(dataRegister, dataBit);
+ }
+ else
+ {
+ fio_digitalWrite_LOW(dataRegister, dataBit);
+ }
+ value >>= 1;
+ fio_digitalWrite_HIGH (clockRegister, clockBit);
+ fio_digitalWrite_LOW (clockRegister,clockBit);
+ }
+ }
+
+ }
+ else
+ {
+ for(i = 0; i < 8; i++)
+ {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ if(value & 0x80)
+ {
+ fio_digitalWrite_HIGH(dataRegister, dataBit);
+ }
+ else
+ {
+ fio_digitalWrite_LOW(dataRegister, dataBit);
+ }
+ value <<= 1;
+ fio_digitalWrite_HIGH (clockRegister, clockBit);
+ fio_digitalWrite_LOW (clockRegister,clockBit);
+ }
+ }
+ }
+}
+
+
+void fio_shiftOut(fio_register dataRegister, fio_bit dataBit,
+ fio_register clockRegister, fio_bit clockBit)
+{
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ // shift out 0x0 (B00000000) fast, byte order is irrelevant
+ fio_digitalWrite_LOW (dataRegister, dataBit);
+
+ for(uint8_t i = 0; i<8; ++i)
+ {
+ fio_digitalWrite_HIGH (clockRegister, clockBit);
+ fio_digitalWrite_SWITCH (clockRegister, clockBit);
+ }
+ }
+}
+
+
+void fio_shiftOut1_init(uint8_t pin)
+{
+ fio_shiftOut1_init(fio_pinToOutputRegister(pin,HIGH),fio_pinToBit(pin));
+}
+
+void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit)
+{
+ // Make sure that capacitors are charged
+ // 300us is an educated guess...
+ fio_digitalWrite(shift1Register,shift1Bit,HIGH);
+ delayMicroseconds(300);
+}
+
+
+void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value,
+ boolean noLatch)
+{
+ /*
+ * this function are based on Shif1 protocol developed by Roman Black
+ * (http://www.romanblack.com/shift1.htm)
+ *
+ * test sketches:
+ * http://pastebin.com/raw.php?i=2hnC9v2Z
+ * http://pastebin.com/raw.php?i=bGg4DhXQ
+ * http://pastebin.com/raw.php?i=tg1ZFiM5
+ * http://pastebin.com/raw.php?i=93ExPDD3 - cascading
+ * tested with:
+ * TPIC6595N - seems to work fine (circuit: http://www.3guys1laser.com/
+ * arduino-one-wire-shift-register-prototype)
+ * 7HC595N
+ */
+
+ // iterate but ignore last bit (is it correct now?)
+ for(int8_t i = 7; i>=0; --i)
+ {
+
+ // assume that pin is HIGH (smokin' pot all day... :) - requires
+ // initialization
+ if(value & _BV(i))
+ {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ // HIGH = 1 Bit
+ fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
+ //hold pin LOW for 1us - done! :)
+ fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
+ } // end critical section
+ //hold pin HIGH for 15us
+ delayMicroseconds(15);
+ }
+ else
+ {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ // LOW = 0 Bit
+ fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
+ // hold pin LOW for 15us
+ delayMicroseconds(15);
+ fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,HIGH);
+ } // end critical section
+
+ // hold pin HIGH for 30us
+ delayMicroseconds(30);
+ }
+ if(!noLatch && i==1)
+ {
+ break;
+ }
+ }
+
+ if(!noLatch)
+ {
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ // send last bit (=LOW) and Latch command
+ fio_digitalWrite_SWITCHTO(shift1Register,shift1Bit,LOW);
+ } // end critical section
+ delayMicroseconds(199); // Hold pin low for 200us
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+ {
+ fio_digitalWrite_HIGH(shift1Register,shift1Bit);
+ } // end critical section
+ delayMicroseconds(299); // Hold pin high for 300us and leave it that
+ // way - using explicit HIGH here, just in case.
+ }
+}
+
+void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch)
+{
+ fio_shiftOut1(fio_pinToOutputRegister(pin, SKIP),fio_pinToBit(pin),value, noLatch);
+}
View
219 lib/LiquidCrystal/FastIO.h
@@ -0,0 +1,219 @@
+// ---------------------------------------------------------------------------
+// Created by Florian Fida on 20/01/12
+// Copyright 2012 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+// http://creativecommons.org/licenses/by-sa/3.0/
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+// ---------------------------------------------------------------------------
+// fio_shiftOut1 functions are based on Shif1 protocol developed by Roman Black
+// (http://www.romanblack.com/shift1.htm)
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file FastIO.h
+// This file implements basic fast IO routines.
+//
+// @brief
+//
+// @version API 1.0.0
+//
+// @author Florian Fida -
+// 2012-03-16 bperrybap mods for chipkit32 (pic32) Arduino
+// support chipkit:
+// (https://github.com/chipKIT32/chipKIT32-MAX/blob/master/hardware/pic32/
+// cores/pic32/wiring_digital.c)
+// ---------------------------------------------------------------------------
+#ifndef _FAST_IO_H_
+#define _FAST_IO_H_
+
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+
+#include <pins_arduino.h> // pleasing sanguino core
+#include <inttypes.h>
+
+
+#define SKIP 0x23
+
+#if defined (__AVR__)
+#include <util/atomic.h> // for critical section management
+typedef uint8_t fio_bit;
+typedef volatile uint8_t *fio_register;
+
+
+#elif defined(__PIC32MX__)
+typedef uint32_t fio_bit;
+typedef volatile uint32_t *fio_register;
+
+
+#else
+// fallback to Arduino standard digital i/o routines
+#define FIO_FALLBACK
+#define ATOMIC_BLOCK(dummy) if(true)
+#define ATOMIC_RESTORESTATE
+typedef uint8_t fio_bit;
+typedef uint8_t fio_register;
+#endif
+
+
+
+#if !defined(FIO_FALLBACK) && !defined(ATOMIC_BLOCK)
+/*
+ * Define an ATOMIC_BLOCK that implements ATOMIC_FORCEON type
+ * Using the portable Arduino interrupts() and noInterrupts()
+ */
+#define ATOMIC_RESTORESTATE ATOMIC_FORCEON // sorry, no support for save/restore yet.
+#define ATOMIC_FORCEON uint8_t sreg_save \
+ __attribute__((__cleanup__(__iSeiParam))) = 0
+
+static __inline__ uint8_t __iCliRetVal(void)
+{
+ noInterrupts();
+ return(1);
+}
+static __inline__ void __iSeiParam(const uint8_t *__s)
+{
+ interrupts();
+}
+#define ATOMIC_BLOCK(type) for(type, __Todo = __iCliRetVal(); __Todo; __Todo = 0)
+
+#endif // end of block to create compatible ATOMIC_BLOCK()
+
+
+
+/*!
+ @function
+ @abstract Get the output register for specified pin.
+ @discussion if fast digital IO is disabled this function returns NULL
+ @param pin[in] Number of a digital pin
+ @result Register
+ */
+fio_register fio_pinToOutputRegister(uint8_t pin, uint8_t initial_state = LOW);
+
+/*!
+ @function
+ @abstract Get the input register for specified pin.
+ @discussion if fast digital IO is disabled this function returns NULL
+ @param pin[in] Number of a digital pin
+ @result Register
+ */
+fio_register fio_pinToInputRegister(uint8_t pin);
+
+/*!
+ @function
+ @abstract Find the bit which belongs to specified pin
+ @discussion if fast digitalWrite is disabled this function returns the pin
+ @param pin[in] Number of a digital pin
+ @result Bit
+ */
+fio_bit fio_pinToBit(uint8_t pin);
+
+
+/*!
+ @method
+ @abstract direct digital write
+ @discussion without any checks
+ @discussion falls back to normal digitalWrite if fast io is disabled
+ @param pinRegister[in] Register - ignored if fast digital write is disabled
+ @param pinBit[in] Bit - Pin if fast digital write is disabled
+ @param value[in] desired output
+ */
+// __attribute__ ((always_inline)) /* let the optimizer decide that for now */
+void fio_digitalWrite ( fio_register pinRegister, fio_bit pinBit, uint8_t value );
+
+/**
+ * This is where the magic happens that makes things fast.
+ * Implemented as preprocessor directives to force inlining
+ * SWITCH is fast for FIO but probably slow for FIO_FALLBACK so SWITCHTO is recommended if the value is known.
+ */
+
+#ifndef FIO_FALLBACK
+#define fio_digitalWrite_LOW(reg,bit) *reg &= ~bit
+#define fio_digitalWrite_HIGH(reg,bit) *reg |= bit
+#define fio_digitalWrite_SWITCH(reg,bit) *reg ^= bit
+#define fio_digitalWrite_SWITCHTO(reg,bit,val) fio_digitalWrite_SWITCH(reg,bit)
+#else
+// reg -> dummy NULL, bit -> pin
+#define fio_digitalWrite_HIGH(reg,bit) digitalWrite(bit,HIGH)
+#define fio_digitalWrite_LOW(reg,bit) digitalWrite(bit,LOW)
+#define fio_digitalWrite_SWITCH(reg,bit) digitalWrite(bit, !digitalRead(bit))
+#define fio_digitalWrite_SWITCHTO(reg,bit,val) digitalWrite(bit,val);
+#endif
+
+/*!
+ @function
+ @abstract direct digital read
+ @discussion without any checks
+ @discussion falls back to normal digitalRead if fast io is disabled
+ @param pinRegister[in] Register - ignored if fast io is disabled
+ @param pinBit[in] Bit - Pin if fast io is disabled
+ @result Value read from pin
+ */
+int fio_digitalRead ( fio_register pinRegister, fio_bit pinBit );
+
+/*!
+ @method
+ @abstract faster shift out
+ @discussion using fast digital write
+ @discussion falls back to normal digitalWrite if fastio is disabled
+ @param dataRegister[in] Register of data pin - ignored if fast digital write is disabled
+ @param dataBit[in] Bit of data pin - Pin if fast digital write is disabled
+ @param clockRegister[in] Register of data pin - ignored if fast digital write is disabled
+ @param clockBit[in] Bit of data pin - Pin if fast digital write is disabled
+ @param bitOrder[in] bit order
+ */
+void fio_shiftOut( fio_register dataRegister, fio_bit dataBit, fio_register clockRegister,
+ fio_bit clockBit, uint8_t value, uint8_t bitOrder );
+
+/*!
+ @method
+ @abstract faster shift out clear
+ @discussion using fast digital write
+ @discussion falls back to normal digitalWrite if fastio is disabled
+ @param dataRegister[in] Register of data pin - ignored if fast digital write is disabled
+ @param dataBit[in] Bit of data pin - Pin if fast digital write is disabled
+ @param clockRegister[in] Register of data pin - ignored if fast digital write is disabled
+ @param clockBit[in] Bit of data pin - Pin if fast digital write is disabled
+ */
+void fio_shiftOut(fio_register dataRegister, fio_bit dataBit, fio_register clockRegister, fio_bit clockBit);
+
+/*!
+ * @method
+ * @abstract one wire shift out
+ * @discussion protocol needs initialisation (fio_shiftOut1_init)
+ * @param shift1Register[in] pins register
+ * @param shift1Bit[in] pins bit
+ * @param value[in] value to shift out, last byte is ignored and always shifted out LOW
+ */
+void fio_shiftOut1(fio_register shift1Register, fio_bit shift1Bit, uint8_t value, boolean noLatch = false);
+/*!
+ * @method
+ * @abstract one wire shift out
+ * @discussion protocol needs initialisation (fio_shiftOut1_init)
+ * @param pin[in] digital pin
+ * @param value[in] value to shift out, last byte is ignored and always shifted out LOW
+ */
+void fio_shiftOut1(uint8_t pin, uint8_t value, boolean noLatch = false);
+/*!
+ * @method
+ * @abstract initializes one wire shift out protocol
+ * @discussion Puts pin to HIGH state and delays until Capacitors are charged.
+ * @param shift1Register[in] pins register
+ * @param shift1Bit[in] pins bit
+ */
+void fio_shiftOut1_init(fio_register shift1Register, fio_bit shift1Bit);
+/*!
+ * @method
+ * @abstract initializes one wire shift out protocol
+ * @discussion Puts pin to HIGH state and delays until Capacitors are charged.
+ * @param pin[in] digital pin
+ */
+void fio_shiftOut1_init(uint8_t pin);
+
+#endif // FAST_IO_H
View
198 lib/LiquidCrystal/I2CIO.cpp
@@ -0,0 +1,198 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file I2CIO.h
+// This file implements a basic IO library using the PCF8574 I2C IO Expander
+// chip.
+//
+// @brief
+// Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
+// The library implements basic IO general methods to configure IO pin direction
+// read and write uint8_t operations and basic pin level routines to set or read
+// a particular IO port.
+//
+//
+// @version API 1.0.0
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+
+#include <inttypes.h>
+
+#include <../Wire/Wire.h>
+#include "I2CIO.h"
+
+// CLASS VARIABLES
+// ---------------------------------------------------------------------------
+
+
+// CONSTRUCTOR
+// ---------------------------------------------------------------------------
+I2CIO::I2CIO ( )
+{
+ _i2cAddr = 0x0;
+ _dirMask = 0xFF; // mark all as INPUTs
+ _shadow = 0x0; // no values set
+ _initialised = false;
+}
+
+// PUBLIC METHODS
+// ---------------------------------------------------------------------------
+
+//
+// begin
+int I2CIO::begin ( uint8_t i2cAddr )
+{
+ _i2cAddr = i2cAddr;
+
+ Wire.begin ( );
+
+ _initialised = Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
+
+#if (ARDUINO < 100)
+ _shadow = Wire.receive ();
+#else
+ _shadow = Wire.read (); // Remove the byte read don't need it.
+#endif
+
+ return ( _initialised );
+}
+
+//
+// pinMode
+void I2CIO::pinMode ( uint8_t pin, uint8_t dir )
+{
+ if ( _initialised )
+ {
+ if ( OUTPUT == dir )
+ {
+ _dirMask &= ~( 1 << pin );
+ }
+ else
+ {
+ _dirMask |= ( 1 << pin );
+ }
+ }
+}
+
+//
+// portMode
+void I2CIO::portMode ( uint8_t dir )
+{
+
+ if ( _initialised )
+ {
+ if ( dir == INPUT )
+ {
+ _dirMask = 0xFF;
+ }
+ else
+ {
+ _dirMask = 0x00;
+ }
+ }
+}
+
+//
+// read
+uint8_t I2CIO::read ( void )
+{
+ uint8_t retVal = 0;
+
+ if ( _initialised )
+ {
+ Wire.requestFrom ( _i2cAddr, (uint8_t)1 );
+#if (ARDUINO < 100)
+ retVal = ( _dirMask & Wire.receive ( ) );
+#else
+ retVal = ( _dirMask & Wire.read ( ) );
+#endif
+
+ }
+ return ( retVal );
+}
+
+//
+// write
+int I2CIO::write ( uint8_t value )
+{
+ int status = 0;
+
+ if ( _initialised )
+ {
+ // Only write HIGH the values of the ports that have been initialised as
+ // outputs updating the output shadow of the device
+ _shadow = ( value & ~(_dirMask) );
+
+ Wire.beginTransmission ( _i2cAddr );
+#if (ARDUINO < 100)
+ Wire.send ( _shadow );
+#else
+ Wire.write ( _shadow );
+#endif
+ status = Wire.endTransmission ();
+ }
+ return ( (status == 0) );
+}
+
+//
+// digitalRead
+uint8_t I2CIO::digitalRead ( uint8_t pin )
+{
+ uint8_t pinVal = 0;
+
+ // Check if initialised and that the pin is within range of the device
+ // -------------------------------------------------------------------
+ if ( ( _initialised ) && ( pin <= 7 ) )
+ {
+ // Remove the values which are not inputs and get the value of the pin
+ pinVal = this->read() & _dirMask;
+ pinVal = ( pinVal >> pin ) & 0x01; // Get the pin value
+ }
+ return (pinVal);
+}
+
+//
+// digitalWrite
+int I2CIO::digitalWrite ( uint8_t pin, uint8_t level )
+{
+ uint8_t writeVal;
+ int status = 0;
+
+ // Check if initialised and that the pin is within range of the device
+ // -------------------------------------------------------------------
+ if ( ( _initialised ) && ( pin <= 7 ) )
+ {
+ // Only write to HIGH the port if the port has been configured as
+ // an OUTPUT pin. Add the new state of the pin to the shadow
+ writeVal = ( 1 << pin ) & ~_dirMask;
+ if ( level == HIGH )
+ {
+ _shadow |= writeVal;
+
+ }
+ else
+ {
+ _shadow &= ~writeVal;
+ }
+ status = this->write ( _shadow );
+ }
+ return ( status );
+}
+
+//
+// PRIVATE METHODS
+// ---------------------------------------------------------------------------
View
148 lib/LiquidCrystal/I2CIO.h
@@ -0,0 +1,148 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file I2CIO.h
+// This file implements a basic IO library using the PCF8574 I2C IO Expander
+// chip.
+//
+// @brief
+// Implement a basic IO library to drive the PCF8574* I2C IO Expander ASIC.
+// The library implements basic IO general methods to configure IO pin direction
+// read and write uint8_t operations and basic pin level routines to set or read
+// a particular IO port.
+//
+// @version API 1.0.0
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+
+#ifndef _I2CIO_H_
+#define _I2CIO_H_
+
+#include <inttypes.h>
+
+#define _I2CIO_VERSION "1.0.0"
+
+/*!
+ @class
+ @abstract I2CIO
+ @discussion Library driver to control PCF8574 based ASICs. Implementing
+ library calls to set/get port through I2C bus.
+ */
+
+class I2CIO
+{
+public:
+ /*!
+ @method
+ @abstract Constructor method
+ @discussion Class constructor constructor.
+ */
+ I2CIO ( );
+
+ /*!
+ @method
+ @abstract Initializes the device.
+ @discussion This method initializes the device allocating an I2C address.
+ This method is the first method that should be call prior to calling any
+ other method form this class. On initialization all pins are configured
+ as INPUT on the device.
+
+ @param i2cAddr: I2C Address where the device is located.
+ @result 1 if the device was initialized correctly, 0 otherwise
+ */
+ int begin ( uint8_t i2cAddr );
+
+ /*!
+ @method
+ @abstract Sets the mode of a particular pin.
+ @discussion Sets the mode of a particular pin to INPUT, OUTPUT. digitalWrite
+ has no effect on pins which are not declared as output.
+
+ @param pin[in] Pin from the I2C IO expander to be configured. Range 0..7
+ @param dir[in] Pin direction (INPUT, OUTPUT).
+ */
+ void pinMode ( uint8_t pin, uint8_t dir );
+
+ /*!
+ @method
+ @abstract Sets all the pins of the device in a particular direction.
+ @discussion This method sets all the pins of the device in a particular
+ direction. This method is useful to set all the pins of the device to be
+ either inputs or outputs.
+ @param dir[in] Direction of all the pins of the device (INPUT, OUTPUT).
+ */
+ void portMode ( uint8_t dir );
+
+ /*!
+ @method
+ @abstract Reads all the pins of the device that are configured as INPUT.
+ @discussion Reads from the device the status of the pins that are configured
+ as INPUT. During initialization all pins are configured as INPUTs by default.
+ Please refer to pinMode or portMode.
+
+ @param none
+ */
+ uint8_t read ( void );
+
+ /*!
+ @method
+ @abstract Read a pin from the device.
+ @discussion Reads a particular pin from the device. To read a particular
+ pin it has to be configured as INPUT. During initialization all pins are
+ configured as INPUTs by default. Please refer to pinMode or portMode.
+
+ @param pin[in] Pin from the port to read its status. Range (0..7)
+ @result Returns the pin status (HIGH, LOW) if the pin is configured
+ as an output, reading its value will always return LOW regardless of its
+ real state.
+ */
+ uint8_t digitalRead ( uint8_t pin );
+
+ /*!
+ @method
+ @abstract Write a value to the device.
+ @discussion Writes to a set of pins in the device. The value is the binary
+ representation of all the pins in device. The value written is masked with
+ the configuration of the direction of the pins; to change the state of
+ a particular pin with this method, such pin has to be configured as OUTPUT
+ using the portMode or pinMode methods. If no pins have been configured as
+ OUTPUTs this method will have no effect.
+
+ @param value[in] value to be written to the device.
+ @result 1 on success, 0 otherwise
+ */
+ int write ( uint8_t value );
+
+ /*!
+ @method
+ @abstract Writes a digital level to a particular pin.
+ @discussion Write a level to the indicated pin of the device. For this
+ method to have effect, the pin has to be configured as OUTPUT using the
+ pinMode or portMode methods.
+
+ @param pin[in] device pin to change level. Range (0..7).
+ @para level[in] logic level to set the pin at (HIGH, LOW).
+ @result 1 on success, 0 otherwise.
+ */
+ int digitalWrite ( uint8_t pin, uint8_t level );
+
+
+
+private:
+ uint8_t _shadow; // Shadow output
+ uint8_t _dirMask; // Direction mask
+ uint8_t _i2cAddr; // I2C address
+ bool _initialised; // Initialised object
+
+};
+
+#endif
View
347 lib/LiquidCrystal/LCD.cpp
@@ -0,0 +1,347 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LCD.cpp
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK.
+//
+// @brief
+// This is a basic implementation of the HD44780 library of the
+// Arduino SDK. This library is a refactored version of the one supplied
+// in the Arduino SDK in such a way that it simplifies its extension
+// to support other mechanism to communicate to LCDs such as I2C, Serial, SR, ...
+// The original library has been reworked in such a way that this will be
+// the base class implementing all generic methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets.
+//
+// This base class is a pure abstract class and needs to be extended. As reference,
+// it has been extended to drive 4 and 8 bit mode control, LCDs and I2C extension
+// backpacks such as the I2CLCDextraIO using the PCF8574* I2C IO Expander ASIC.
+//
+//
+// @version API 1.1.0
+//
+// 2012.03.29 bperrybap - changed comparision to use LCD_5x8DOTS rather than 0
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+#include "LCD.h"
+
+// CLASS CONSTRUCTORS
+// ---------------------------------------------------------------------------
+// Constructor
+LCD::LCD ()
+{
+
+}
+
+// PUBLIC METHODS
+// ---------------------------------------------------------------------------
+// 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).
+// A call to begin() will reinitialize the LCD.
+//
+void LCD::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
+{
+ if (lines > 1)
+ {
+ _displayfunction |= LCD_2LINE;
+ }
+ _numlines = lines;
+ _cols = cols;
+
+ // for some 1 line displays you can select a 10 pixel high font
+ // ------------------------------------------------------------
+ if ((dotsize != LCD_5x8DOTS) && (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 before 4.5V so we'll wait
+ // 50
+ // ---------------------------------------------------------------------------
+ delay (100); // 100ms delay
+
+ //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
+ send(0x03, FOUR_BITS);
+ delayMicroseconds(4500); // wait min 4.1ms
+
+ // second try
+ send ( 0x03, FOUR_BITS );
+ delayMicroseconds(4500); // wait min 4.1ms
+
+ // third go!
+ send( 0x03, FOUR_BITS );
+ delayMicroseconds(150);
+
+ // finally, set to 4-bit interface
+ send ( 0x02, FOUR_BITS );
+ }
+ 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 the LCD
+ clear();
+
+ // Initialize to default text direction (for romance languages)
+ _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
+ // set the entry mode
+ command(LCD_ENTRYMODESET | _displaymode);
+
+ backlight();
+
+}
+
+// Common LCD Commands
+// ---------------------------------------------------------------------------
+void LCD::clear()
+{
+ command(LCD_CLEARDISPLAY); // clear display, set cursor position to zero
+ delayMicroseconds(HOME_CLEAR_EXEC); // this command is time consuming
+}
+
+void LCD::home()
+{
+ command(LCD_RETURNHOME); // set cursor position to zero
+ delayMicroseconds(HOME_CLEAR_EXEC); // This command is time consuming
+}
+
+void LCD::setCursor(uint8_t col, uint8_t row)
+{
+ const byte row_offsetsDef[] = { 0x00, 0x40, 0x14, 0x54 }; // For regular LCDs
+ const byte row_offsetsLarge[] = { 0x00, 0x40, 0x10, 0x50 }; // For 16x4 LCDs
+
+ if ( row >= _numlines )
+ {
+ row = _numlines-1; // rows start at 0
+ }
+
+ // 16x4 LCDs have special memory map layout
+ // ----------------------------------------
+ if ( _cols == 16 && _numlines == 4 )
+ {
+ command(LCD_SETDDRAMADDR | (col + row_offsetsLarge[row]));
+ }
+ else
+ {
+ command(LCD_SETDDRAMADDR | (col + row_offsetsDef[row]));
+ }
+
+}
+
+// Turn the display on/off
+void LCD::noDisplay()
+{
+ _displaycontrol &= ~LCD_DISPLAYON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+void LCD::display()
+{
+ _displaycontrol |= LCD_DISPLAYON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns the underline cursor on/off
+void LCD::noCursor()
+{
+ _displaycontrol &= ~LCD_CURSORON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LCD::cursor()
+{
+ _displaycontrol |= LCD_CURSORON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns on/off the blinking cursor
+void LCD::noBlink()
+{
+ _displaycontrol &= ~LCD_BLINKON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+void LCD::blink()
+{
+ _displaycontrol |= LCD_BLINKON;
+ command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// These commands scroll the display without changing the RAM
+void LCD::scrollDisplayLeft(void)
+{
+ command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
+}
+
+void LCD::scrollDisplayRight(void)
+{
+ command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
+}
+
+// This is for text that flows Left to Right
+void LCD::leftToRight(void)
+{
+ _displaymode |= LCD_ENTRYLEFT;
+ command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This is for text that flows Right to Left
+void LCD::rightToLeft(void)
+{
+ _displaymode &= ~LCD_ENTRYLEFT;
+ command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This method moves the cursor one space to the right
+void LCD::moveCursorRight(void)
+{
+ command(LCD_CURSORSHIFT | LCD_CURSORMOVE | LCD_MOVERIGHT);
+}
+
+// This method moves the cursor one space to the left
+void LCD::moveCursorLeft(void)
+{
+ command(LCD_CURSORSHIFT | LCD_CURSORMOVE | LCD_MOVELEFT);
+}
+
+
+// This will 'right justify' text from the cursor
+void LCD::autoscroll(void)
+{
+ _displaymode |= LCD_ENTRYSHIFTINCREMENT;
+ command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'left justify' text from the cursor
+void LCD::noAutoscroll(void)
+{
+ _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
+ command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// Write to CGRAM of new characters
+void LCD::createChar(uint8_t location, uint8_t charmap[])
+{
+ location &= 0x7; // we only have 8 locations 0-7
+
+ command(LCD_SETCGRAMADDR | (location << 3));
+ delayMicroseconds(30);
+
+ for (int i=0; i<8; i++)
+ {
+ write(charmap[i]); // call the virtual write method
+ delayMicroseconds(40);
+ }
+}
+
+//
+// Switch on the backlight
+void LCD::backlight ( void )
+{
+ setBacklight(255);
+}
+
+//
+// Switch off the backlight
+void LCD::noBacklight ( void )
+{
+ setBacklight(0);
+}
+
+//
+// Switch fully on the LCD (backlight and LCD)
+void LCD::on ( void )
+{
+ display();
+ backlight();
+}
+
+//
+// Switch fully off the LCD (backlight and LCD)
+void LCD::off ( void )
+{
+ noBacklight();
+ noDisplay();
+}
+
+// General LCD commands - generic methods used by the rest of the commands
+// ---------------------------------------------------------------------------
+void LCD::command(uint8_t value)
+{
+ send(value, COMMAND);
+}
+
+#if (ARDUINO < 100)
+void LCD::write(uint8_t value)
+{
+ send(value, DATA);
+}
+#else
+size_t LCD::write(uint8_t value)
+{
+ send(value, DATA);
+ return 1; // assume OK
+}
+#endif
View
536 lib/LiquidCrystal/LCD.h
@@ -0,0 +1,536 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LCD.h
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK.
+//
+// @brief
+// This is a basic implementation of the LiquidCrystal library of the
+// Arduino SDK. This library is a refactored version of the one supplied
+// in the Arduino SDK in such a way that it simplifies its extension
+// to support other mechanism to communicate to LCDs such as I2C, Serial, SR,
+// The original library has been reworked in such a way that this will be
+// the base class implementing all generic methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets.
+//
+// This base class is a pure abstract class and needs to be extended. As reference,
+// it has been extended to drive 4 and 8 bit mode control, LCDs and I2C extension
+// backpacks such as the I2CLCDextraIO using the PCF8574* I2C IO Expander ASIC.
+//
+// The functionality provided by this class and its base class is identical
+// to the original functionality of the Arduino LiquidCrystal library.
+//
+// @version API 1.1.0
+//
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#ifndef _LCD_H_
+#define _LCD_H_
+
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+
+#include <inttypes.h>
+#include <Print.h>
+
+
+/*!
+ @defined
+ @abstract Enables disables fast waits for write operations for LCD
+ @discussion If defined, the library will avoid doing un-necessary waits.
+ this can be done, because the time taken by Arduino's slow digitalWrite
+ operations. If fast digitalIO operations, comment this line out or undefine
+ the mode.
+ */
+#ifdef __AVR__
+#define FAST_MODE
+#endif
+
+/*!
+ @function
+ @abstract waits for a given time in microseconds (compilation dependent).
+ @discussion Waits for a given time defined in microseconds depending on
+ the FAST_MODE define. If the FAST_MODE is defined the call will return
+ inmediatelly.
+ @param uSec[in] time in microseconds.
+ @result None
+ */
+inline static void waitUsec ( uint16_t uSec )
+{
+#ifndef FAST_MODE
+ delayMicroseconds ( uSec );
+#endif // FAST_MODE
+}
+
+
+/*!
+ @defined
+ @abstract All these definitions shouldn't be used unless you are writing
+ a driver.
+ @discussion All these definitions are for driver implementation only and
+ shouldn't be used by applications.
+ */
+// LCD 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 and cursor 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
+
+
+// Define COMMAND and DATA LCD Rs (used by send method).
+// ---------------------------------------------------------------------------
+#define COMMAND 0
+#define DATA 1
+#define FOUR_BITS 2
+
+
+/*!
+ @defined
+ @abstract Defines the duration of the home and clear commands
+ @discussion This constant defines the time it takes for the home and clear
+ commands in the LCD - Time in microseconds.
+ */
+#define HOME_CLEAR_EXEC 2000
+
+/*!
+ @defined
+ @abstract Backlight off constant declaration
+ @discussion Used in combination with the setBacklight to swith off the
+ LCD backlight. @set setBacklight
+*/
+#define BACKLIGHT_OFF 0
+
+/*!
+ @defined
+ @abstract Backlight on constant declaration
+ @discussion Used in combination with the setBacklight to swith on the
+ LCD backlight. @set setBacklight
+ */
+#define BACKLIGHT_ON 255
+
+
+/*!
+ @typedef
+ @abstract Define backlight control polarity
+ @discussion Backlight control polarity. @see setBacklightPin.
+ */
+typedef enum { POSITIVE, NEGATIVE } t_backlighPol;
+
+class LCD : public Print
+{
+public:
+
+ /*!
+ @method
+ @abstract LiquidCrystal abstract constructor.
+ @discussion LiquidCrystal class abstract constructor needed to create
+ the base abstract class.
+ */
+ LCD ( );
+
+ /*!
+ @function
+ @abstract LCD initialization.
+ @discussion Initializes the LCD to a given size (col, row). This methods
+ initializes the LCD, therefore, it MUST be called prior to using any other
+ method from this class.
+
+ This method is abstract, a base implementation is available common to all LCD
+ drivers. Should it not be compatible with some other LCD driver, a derived
+ implementation should be done on the driver specif class.
+
+ @param cols[in] the number of columns that the display has
+ @param rows[in] the number of rows that the display has
+ @param charsize[in] character size, default==LCD_5x8DOTS
+ */
+ virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
+
+ /*!
+ @function
+ @abstract Clears the LCD.
+ @discussion Clears the LCD screen and positions the cursor in the upper-left
+ corner.
+
+ This operation is time consuming for the LCD.
+
+ @param none
+ */
+ void clear();
+
+ /*!
+ @function
+ @abstract Sets the cursor to the upper-left corner.
+ @discussion Positions the cursor in the upper-left of the LCD.
+ That is, use that location in outputting subsequent text to the display.
+ To also clear the display, use the clear() function instead.
+
+ This operation is time consuming for the LCD.
+
+ @param none
+ */
+ void home();
+
+ /*!
+ @function
+ @abstract Turns off the LCD display.
+ @discussion Turns off the LCD display, without losing the text currently
+ being displayed on it.
+
+ @param none
+ */
+ void noDisplay();
+
+ /*!
+ @function
+ @abstract Turns on the LCD display.
+ @discussion Turns on the LCD display, after it's been turned off with
+ noDisplay(). This will restore the text (and cursor location) that was on
+ the display prior to calling noDisplay().
+
+ @param none
+ */
+ void display();
+
+ /*!
+ @function
+ @abstract Turns off the blinking of the LCD cursor.
+
+ @param none
+ */
+ void noBlink();
+
+ /*!
+ @function
+ @abstract Display the cursor of the LCD.
+ @discussion Display the blinking LCD cursor. If used in combination with
+ the cursor() function, the result will depend on the particular display.
+
+ @param none
+ */
+ void blink();
+
+ /*!
+ @function
+ @abstract Hides the LCD cursor.
+
+ @param none
+ */
+ void noCursor();
+
+ /*!
+ @function
+ @abstract Display the LCD cursor.
+ @discussion Display the LCD cursor: an underscore (line) at the location
+ where the next character will be written.
+
+ @param none
+ */
+ void cursor();
+
+ /*!
+ @function
+ @abstract Scrolls the contents of the display (text and cursor) one space
+ to the left.
+
+ @param none
+ */
+ void scrollDisplayLeft();
+
+ /*!
+ @function
+ @abstract Scrolls the contents of the display (text and cursor) one space
+ to the right.
+
+ @param none
+ */
+ void scrollDisplayRight();
+
+ /*!
+ @function
+ @abstract Set the direction for text written to the LCD to left-to-right.
+ @discussion Set the direction for text written to the LCD to left-to-right.
+ All subsequent characters written to the display will go from left to right,
+ but does not affect previously-output text.
+
+ This is the default configuration.
+
+ @param none
+ */
+ void leftToRight();
+
+ /*!
+ @function
+ @abstract Set the direction for text written to the LCD to right-to-left.
+ @discussion Set the direction for text written to the LCD to right-to-left.
+ All subsequent characters written to the display will go from right to left,
+ but does not affect previously-output text.
+
+ left-to-right is the default configuration.
+
+ @param none
+ */
+ void rightToLeft();
+
+ /*!
+ @function
+ @abstract Moves the cursor one space to the left.
+ @discussion
+ @param none
+ */
+ void moveCursorLeft();
+
+
+ /*!
+ @function
+ @abstract Moves the cursor one space to the right.
+
+ @param none
+ */
+ void moveCursorRight();
+
+ /*!
+ @function
+ @abstract Turns on automatic scrolling of the LCD.
+ @discussion Turns on automatic scrolling of the LCD. This causes each
+ character output to the display to push previous characters over by one
+ space. If the current text direction is left-to-right (the default),
+ the display scrolls to the left; if the current direction is right-to-left,
+ the display scrolls to the right.
+ This has the effect of outputting each new character to the same location on
+ the LCD.
+
+ @param none
+ */
+ void autoscroll();
+
+ /*!
+ @function
+ @abstract Turns off automatic scrolling of the LCD.
+ @discussion Turns off automatic scrolling of the LCD, this is the default
+ configuration of the LCD.
+
+ @param none
+ */
+ void noAutoscroll();
+
+ /*!
+ @function
+ @abstract Creates a custom character for use on the LCD.
+ @discussion Create a custom character (glyph) for use on the LCD.
+ Most chipsets only support up to eight characters of 5x8 pixels. Therefore,
+ this methods has been limited to locations (numbered 0 to 7).
+
+ The appearance of each custom character is specified by an array of eight
+ bytes, one for each row. The five least significant bits of each byte
+ determine the pixels in that row. To display a custom character on screen,
+ write()/print() its number, i.e. lcd.print (char(x)); // Where x is 0..7.
+
+ @param location[in] LCD memory location of the character to create
+ (0 to 7)
+ @param charmap[in] the bitmap array representing each row of the character.
+ */
+ void createChar(uint8_t location, uint8_t charmap[]);
+
+ /*!
+ @function
+ @abstract Position the LCD cursor.
+ @discussion Sets the position of the LCD cursor. Set the location at which
+ subsequent text written to the LCD will be displayed.
+
+ @param col[in] LCD column
+ @param row[in] LCD row - line.
+ */
+ void setCursor(uint8_t col, uint8_t row);
+
+ /*!
+ @function
+ @abstract Switch-on the LCD backlight.
+ @discussion Switch-on the LCD backlight.
+ The setBacklightPin has to be called before setting the backlight for
+ this method to work. @see setBacklightPin.
+ */
+ void backlight ( void );
+
+ /*!
+ @function
+ @abstract Switch-off the LCD backlight.
+ @discussion Switch-off the LCD backlight.
+ The setBacklightPin has to be called before setting the backlight for
+ this method to work. @see setBacklightPin.
+ */
+ void noBacklight ( void );
+
+ /*!
+ @function
+ @abstract Switch on the LCD module.
+ @discussion Switch on the LCD module, it will switch on the LCD controller
+ and the backlight. This method has the same effect of calling display and
+ backlight. @see display, @see backlight
+ */
+ void on ( void );
+
+ /*!
+ @function
+ @abstract Switch off the LCD module.
+ @discussion Switch off the LCD module, it will switch off the LCD controller
+ and the backlight. This method has the same effect of calling noDisplay and
+ noBacklight. @see display, @see backlight
+ */
+ void off ( void );
+
+ //
+ // virtual class methods
+ // --------------------------------------------------------------------------
+ /*!
+ @function
+ @abstract Sets the pin to control the backlight.
+ @discussion Sets the pin in the device to control the backlight.
+ This method is device dependent and can be programmed on each subclass. An
+ empty function call is provided that does nothing.
+
+ @param value: pin associated to backlight control.
+ @param pol: backlight polarity control (POSITIVE, NEGATIVE)
+ */
+ virtual void setBacklightPin ( uint8_t value, t_backlighPol pol ) { };
+
+ /*!
+ @function
+ @abstract Sets the pin to control the backlight.
+ @discussion Sets the pin in the device to control the backlight. The behaviour
+ of this method is very dependent on the device. Some controllers support
+ dimming some don't. Please read the actual header file for each individual
+ device. The setBacklightPin method has to be called before setting the backlight
+ or the adequate backlight control constructor.
+ @see setBacklightPin.
+
+ NOTE: The prefered methods to control the backlight are "backlight" and
+ "noBacklight".
+
+ @param 0..255 - the value is very dependent on the LCD. However,
+ BACKLIGHT_OFF will be interpreted as off and BACKLIGHT_ON will drive the
+ backlight on.
+ */
+ virtual void setBacklight ( uint8_t value ) { };
+
+ /*!
+ @function
+ @abstract Writes to the LCD.
+ @discussion This method writes character to the LCD in the current cursor
+ position.
+
+ This is the virtual write method, implemented in the Print class, therefore
+ all Print class methods will end up calling this method.
+
+ @param value[in] Value to write to the LCD.
+ */
+#if (ARDUINO < 100)
+ virtual void write(uint8_t value);
+#else
+ virtual size_t write(uint8_t value);
+#endif
+
+#if (ARDUINO < 100)
+ using Print::write;
+#else
+ using Print::write;
+#endif
+
+protected:
+ // Internal LCD variables to control the LCD shared between all derived
+ // classes.
+ uint8_t _displayfunction; // LCD_5x10DOTS or LCD_5x8DOTS, LCD_4BITMODE or
+ // LCD_8BITMODE, LCD_1LINE or LCD_2LINE
+ uint8_t _displaycontrol; // LCD base control command LCD on/off, blink, cursor
+ // all commands are "ored" to its contents.
+ uint8_t _displaymode; // Text entry mode to the LCD
+ uint8_t _numlines; // Number of lines of the LCD, initialized with begin()
+ uint8_t _cols; // Number of columns in the LCD
+ t_backlighPol _polarity; // Backlight polarity
+
+private:
+ /*!
+ @function
+ @abstract Send a command to the LCD.
+ @discussion This method sends a command to the LCD by setting the Register
+ select line of the LCD.
+
+ This command shouldn't be used to drive the LCD, only to implement any other
+ feature that is not available on this library.
+
+ @param value[in] Command value to send to the LCD (COMMAND, DATA or
+ FOUR_BITS).
+ */
+ void command(uint8_t value);
+
+ /*!
+ @function
+ @abstract Send a particular value to the LCD.
+ @discussion Sends a particular value to the LCD. This is a pure abstract
+ method, therefore, it is implementation dependent of each derived class how
+ to physically write to the LCD.
+
+ Users should never call this method.
+
+ @param value[in] Value to send to the LCD.
+ @result mode LOW - write to the LCD CGRAM, HIGH - write a command to
+ the LCD.
+ */
+#if (ARDUINO < 100)
+ virtual void send(uint8_t value, uint8_t mode) { };
+#else
+ virtual void send(uint8_t value, uint8_t mode) = 0;
+#endif
+
+};
+
+#endif
View
299 lib/LiquidCrystal/LiquidCrystal.cpp
@@ -0,0 +1,299 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LiquidCrystal.cpp
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK.
+//
+// @brief
+// This is a basic implementation of the LiquidCrystal library of the
+// Arduino SDK. The original library has been reworked in such a way that
+// this class implements the all methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets using the parallel port of
+// the LCD (4 bit and 8 bit).
+//
+// The functionality provided by this class and its base class is identical
+// to the original functionality of the Arduino LiquidCrystal library.
+//
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+#include "LiquidCrystal.h"
+
+// CONSTANT definitions
+// ---------------------------------------------------------------------------
+#define LCD_NOBACKLIGHT 0xFF
+
+// LCD driver configuration (4bit or 8bit driver control)
+#define LCD_4BIT 1
+#define LCD_8BIT 0
+
+// STATIC helper functions
+// ---------------------------------------------------------------------------
+
+
+// CONSTRUCTORS
+// ---------------------------------------------------------------------------
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+ init(LCD_8BIT, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+ init(LCD_8BIT, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
+{
+ init(LCD_4BIT, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)
+{
+ init(LCD_4BIT, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+}
+
+// Contructors with backlight control
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
+ uint8_t backlightPin, t_backlighPol pol)
+{
+ init(LCD_8BIT, rs, 255, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+ setBacklightPin ( backlightPin, pol );
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
+ uint8_t backlightPin, t_backlighPol pol)
+{
+ init(LCD_8BIT, rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7);
+ setBacklightPin ( backlightPin, pol );
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t backlightPin, t_backlighPol pol)
+{
+ init(LCD_4BIT, rs, rw, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+ setBacklightPin ( backlightPin, pol );
+}
+
+LiquidCrystal::LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t backlightPin, t_backlighPol pol)
+{
+ init(LCD_4BIT, rs, 255, enable, d0, d1, d2, d3, 0, 0, 0, 0);
+ setBacklightPin ( backlightPin, pol );
+}
+
+// PUBLIC METHODS
+// ---------------------------------------------------------------------------
+
+/************ low level data pushing commands **********/
+//
+// send
+void LiquidCrystal::send(uint8_t value, uint8_t mode)
+{
+ // Only interested in COMMAND or DATA
+ digitalWrite( _rs_pin, ( mode == DATA ) );
+
+ // if there is a RW pin indicated, set it low to Write
+ // ---------------------------------------------------
+ if (_rw_pin != 255)
+ {
+ digitalWrite(_rw_pin, LOW);
+ }
+
+ if ( mode != FOUR_BITS )
+ {
+ if ( (_displayfunction & LCD_8BITMODE ) )
+ {
+ writeNbits(value, 8);
+ }
+ else
+ {
+ writeNbits ( value >> 4, 4 );
+ writeNbits ( value, 4 );
+ }
+ }
+ else
+ {
+ writeNbits ( value, 4 );
+ }
+ waitUsec ( EXEC_TIME ); // wait for the command to execute by the LCD
+}
+
+//
+// setBacklightPin
+void LiquidCrystal::setBacklightPin ( uint8_t pin, t_backlighPol pol )
+{
+ pinMode ( pin, OUTPUT ); // Difine the backlight pin as output
+ _backlightPin = pin;
+ _polarity = pol;
+ setBacklight(BACKLIGHT_OFF); // Set the backlight low by default
+}
+
+//
+// setBackligh
+void LiquidCrystal::setBacklight ( uint8_t value )
+{
+ // Check if there is a pin assigned to the backlight
+ // ---------------------------------------------------
+ if ( _backlightPin != LCD_NOBACKLIGHT )
+ {
+ // Check if the pin is associated to a timer, i.e. PWM
+ // ---------------------------------------------------
+ if(digitalPinToTimer(_backlightPin) != NOT_ON_TIMER)
+ {
+ // Check for control polarity inversion
+ // ---------------------------------------------------
+ if ( _polarity == POSITIVE )
+ {
+ analogWrite ( _backlightPin, value );
+ }
+ else
+ {
+ analogWrite ( _backlightPin, 255 - value );
+ }
+ }
+ // Not a PWM pin, set the backlight pin for POSI or NEG
+ // polarity
+ // --------------------------------------------------------
+ else if (((value > 0) && (_polarity == POSITIVE)) ||
+ ((value == 0) && (_polarity == NEGATIVE)))
+ {
+ digitalWrite( _backlightPin, HIGH);
+ }
+ else
+ {
+ digitalWrite( _backlightPin, LOW);
+ }
+ }
+}
+
+// PRIVATE METHODS
+// ---------------------------------------------------------------------------
+
+
+// init
+void LiquidCrystal::init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7)
+{
+ uint8_t i;
+
+ // Initialize the IO pins
+ // -----------------------
+
+ _rs_pin = rs;
+ _rw_pin = rw;
+ _enable_pin = enable;
+
+ _data_pins[0] = d0;
+ _data_pins[1] = d1;
+ _data_pins[2] = d2;
+ _data_pins[3] = d3;
+ _data_pins[4] = d4;
+ _data_pins[5] = d5;
+ _data_pins[6] = d6;
+ _data_pins[7] = d7;
+
+ // Initialize the IO port direction to OUTPUT
+ // ------------------------------------------
+
+ for ( i = 0; i < 4; i++ )
+ {
+ pinMode ( _data_pins[i], OUTPUT );
+ }
+
+ // Initialize the rest of the ports if it is an 8bit controlled LCD
+ // ----------------------------------------------------------------
+
+ if ( !fourbitmode )
+ {
+ for ( i = 4; i < 8; i++ )
+ {
+ pinMode ( _data_pins[i], OUTPUT );
+ }
+ }
+ pinMode(_rs_pin, OUTPUT);
+
+ // we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
+ if (_rw_pin != 255)
+ {
+ pinMode(_rw_pin, OUTPUT);
+ }
+
+ pinMode(_enable_pin, OUTPUT);
+
+ // Initialise displaymode functions to defaults: LCD_1LINE and LCD_5x8DOTS
+ // -------------------------------------------------------------------------
+ if (fourbitmode)
+ _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+ else
+ _displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
+
+ // Now we pull both RS and R/W low to begin commands
+ digitalWrite(_rs_pin, LOW);
+ digitalWrite(_enable_pin, LOW);
+
+ if (_rw_pin != 255)
+ {
+ digitalWrite(_rw_pin, LOW);
+ }
+
+ // Initialise the backlight pin no nothing
+ _backlightPin = LCD_NOBACKLIGHT;
+ _polarity = POSITIVE;
+}
+
+//
+// pulseEnable
+void LiquidCrystal::pulseEnable(void)
+{
+ // There is no need for the delays, since the digitalWrite operation
+ // takes longer.
+ digitalWrite(_enable_pin, HIGH);
+ waitUsec(1); // enable pulse must be > 450ns
+ digitalWrite(_enable_pin, LOW);
+}
+
+//
+// write4bits
+void LiquidCrystal::writeNbits(uint8_t value, uint8_t numBits)
+{
+ for (uint8_t i = 0; i < numBits; i++)
+ {
+ digitalWrite(_data_pins[i], (value >> i) & 0x01);
+ }
+ pulseEnable();
+}
+
+
View
161 lib/LiquidCrystal/LiquidCrystal.h
@@ -0,0 +1,161 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LiquidCrystal.h
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK.
+//
+// @brief
+// This is a basic implementation of the LiquidCrystal library of the
+// Arduino SDK. The original library has been reworked in such a way that
+// this class implements the all methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets using the parallel port of
+// the LCD (4 bit and 8 bit).
+//
+//
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#ifndef LiquidCrystal_4bit_h
+#define LiquidCrystal_4bit_h
+
+#include <inttypes.h>
+
+#include "LCD.h"
+#include "FastIO.h"
+
+
+/*!
+ @defined
+ @abstract Command execution time on the LCD.
+ @discussion This defines how long a command takes to execute by the LCD.
+ The time is expressed in micro-seconds.
+ */
+#define EXEC_TIME 37
+
+class LiquidCrystal : public LCD
+{
+public:
+ /*!
+ @method
+ @abstract 8 bit LCD constructors.
+ @discussion Defines the pin assignment that the LCD will have.
+ The constructor does not initialize the LCD.
+ */
+ LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+ LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+
+ // Constructors with backlight control
+ LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
+ uint8_t backlightPin, t_backlighPol pol);
+ LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
+ uint8_t backlightPin, t_backlighPol pol);
+ /*!
+ @method
+ @abstract 4 bit LCD constructors.
+ @discussion Defines the pin assignment that the LCD will have.
+ The constructor does not initialize the LCD.
+ */
+ LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
+ LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
+
+ // Constructors with backlight control
+ LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t backlightPin, t_backlighPol pol);
+ LiquidCrystal(uint8_t rs, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t backlightPin, t_backlighPol pol);
+ /*!
+ @function
+ @abstract Send a particular value to the LCD.
+ @discussion Sends a particular value to the LCD for writing to the LCD or
+ as an LCD command.
+
+ Users should never call this method.
+
+ @param value Value to send to the LCD.
+ @result mode LOW - write to the LCD CGRAM, HIGH - write a command to
+ the LCD.
+ */
+ virtual void send(uint8_t value, uint8_t mode);
+
+ /*!
+ @function
+ @abstract Sets the pin to control the backlight.
+ @discussion Sets the pin in the device to control the backlight.
+
+ @param pin: pin assigned to the backlight
+ @param pol: backlight pin control polarity (POSITIVE, NEGATIVE).
+ */
+ void setBacklightPin ( uint8_t pin, t_backlighPol pol );
+
+ /*!
+ @function
+ @abstract Switch-on/off the LCD backlight.
+ @discussion Switch-on/off the LCD backlight.
+ The setBacklightPin has to be called before setting the backlight for
+ this method to work. @see setBacklightPin. For dimming control of the
+ backlight, the configuration pin must be a PWM output pin. Dim control
+ is achieved by passing a value from 1 to 255 as a parameter. If the
+ pin configured when calling the setBacklightPin does not support PWM,
+ then: (0) backlight off, (1..255) backlight on.
+
+ @param value: backlight value. 0: off, 1..255: dim control of the
+ backlight. For negative logic 255: off, 254..0: dim control.
+ */
+ void setBacklight ( uint8_t value );
+
+private:
+
+ /*!
+ @method
+ @abstract Initializes the LCD pin allocation and associated HW
+ @discussion Initializes the LCD pin allocation and configuration.
+ */
+ void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
+ uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
+
+ /*!
+ @method
+ @abstract Writes numBits bits from value value to the LCD.
+ @discussion Writes numBists bits (the least significant) to the LCD control
+ data lines.
+ */
+ void writeNbits(uint8_t value, uint8_t numBits);
+
+ /*!
+ @method
+ @abstract Pulse the LCD enable line (En).
+ @discussion Sends a pulse of 1 uS to the Enable pin to execute an command
+ or write operation.
+ */
+ void pulseEnable();
+
+ uint8_t _rs_pin; // LOW: command. HIGH: character.
+ uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
+ uint8_t _enable_pin; // activated by a HIGH pulse.
+ uint8_t _data_pins[8]; // Data pins.
+ uint8_t _backlightPin; // Pin associated to control the LCD backlight
+};
+
+#endif
View
291 lib/LiquidCrystal/LiquidCrystal_I2C.cpp
@@ -0,0 +1,291 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LiquidCrystal_I2C.c
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK but using an I2C IO extension board.
+//
+// @brief
+// This is a basic implementation of the LiquidCrystal library of the
+// Arduino SDK. The original library has been reworked in such a way that
+// this class implements the all methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets using I2C extension
+// backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC.
+//
+// The functionality provided by this class and its base class is identical
+// to the original functionality of the Arduino LiquidCrystal library.
+//
+//
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#if (ARDUINO < 100)
+#include <WProgram.h>
+#else
+#include <Arduino.h>
+#endif
+#include <inttypes.h>
+#include "I2CIO.h"
+#include "LiquidCrystal_I2C.h"
+
+// CONSTANT definitions
+// ---------------------------------------------------------------------------
+
+// flags for backlight control
+/*!
+ @defined
+ @abstract LCD_NOBACKLIGHT
+ @discussion NO BACKLIGHT MASK
+ */
+#define LCD_NOBACKLIGHT 0x00
+
+/*!
+ @defined
+ @abstract LCD_BACKLIGHT
+ @discussion BACKLIGHT MASK used when backlight is on
+ */
+#define LCD_BACKLIGHT 0xFF
+
+
+// Default library configuration parameters used by class constructor with
+// only the I2C address field.
+// ---------------------------------------------------------------------------
+/*!
+ @defined
+ @abstract Enable bit of the LCD
+ @discussion Defines the IO of the expander connected to the LCD Enable
+ */
+#define EN 6 // Enable bit
+
+/*!
+ @defined
+ @abstract Read/Write bit of the LCD
+ @discussion Defines the IO of the expander connected to the LCD Rw pin
+ */
+#define RW 5 // Read/Write bit
+
+/*!
+ @defined
+ @abstract Register bit of the LCD
+ @discussion Defines the IO of the expander connected to the LCD Register select pin
+ */
+#define RS 4 // Register select bit
+
+/*!
+ @defined
+ @abstract LCD dataline allocation this library only supports 4 bit LCD control
+ mode.
+ @discussion D4, D5, D6, D7 LCD data lines pin mapping of the extender module
+ */
+#define D4 0
+#define D5 1
+#define D6 2
+#define D7 3
+
+
+// CONSTRUCTORS
+// ---------------------------------------------------------------------------
+LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr )
+{
+ config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7);
+}
+
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t backlighPin,
+ t_backlighPol pol = POSITIVE)
+{
+ config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7);
+ setBacklightPin(backlighPin, pol);
+}
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
+ uint8_t Rs)
+{
+ config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7);
+}
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
+ uint8_t Rs, uint8_t backlighPin,
+ t_backlighPol pol = POSITIVE)
+{
+ config(lcd_Addr, En, Rw, Rs, D4, D5, D6, D7);
+ setBacklightPin(backlighPin, pol);
+}
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
+ uint8_t Rs, uint8_t d4, uint8_t d5,
+ uint8_t d6, uint8_t d7 )
+{
+ config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7);
+}
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw,
+ uint8_t Rs, uint8_t d4, uint8_t d5,
+ uint8_t d6, uint8_t d7, uint8_t backlighPin,
+ t_backlighPol pol = POSITIVE )
+{
+ config(lcd_Addr, En, Rw, Rs, d4, d5, d6, d7);
+ setBacklightPin(backlighPin, pol);
+}
+
+// PUBLIC METHODS
+// ---------------------------------------------------------------------------
+
+//
+// begin
+void LiquidCrystal_I2C::begin(uint8_t cols, uint8_t lines, uint8_t dotsize)
+{
+
+ init(); // Initialise the I2C expander interface
+ LCD::begin ( cols, lines, dotsize );
+}
+
+
+// User commands - users can expand this section
+//----------------------------------------------------------------------------
+// Turn the (optional) backlight off/on
+
+//
+// setBacklightPin
+void LiquidCrystal_I2C::setBacklightPin ( uint8_t value, t_backlighPol pol = POSITIVE )
+{
+ _backlightPinMask = ( 1 << value );
+ _polarity = pol;
+ setBacklight(BACKLIGHT_OFF);
+}
+
+//
+// setBacklight
+void LiquidCrystal_I2C::setBacklight( uint8_t value )
+{
+ // Check if backlight is available
+ // ----------------------------------------------------
+ if ( _backlightPinMask != 0x0 )
+ {
+ // Check for polarity to configure mask accordingly
+ // ----------------------------------------------------------
+ if (((_polarity == POSITIVE) && (value > 0)) ||
+ ((_polarity == NEGATIVE ) && ( value == 0 )))
+ {
+ _backlightStsMask = _backlightPinMask & LCD_BACKLIGHT;
+ }
+ else
+ {
+ _backlightStsMask = _backlightPinMask & LCD_NOBACKLIGHT;
+ }
+ _i2cio.write( _backlightStsMask );
+ }
+}
+
+
+// PRIVATE METHODS
+// ---------------------------------------------------------------------------
+
+//
+// init
+int LiquidCrystal_I2C::init()
+{
+ int status = 0;
+
+ // initialize the backpack IO expander
+ // and display functions.
+ // ------------------------------------------------------------------------
+ if ( _i2cio.begin ( _Addr ) == 1 )
+ {
+ _i2cio.portMode ( OUTPUT ); // Set the entire IO extender to OUTPUT
+ _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+ status = 1;
+ _i2cio.write(0); // Set the entire port to LOW
+ }
+ return ( status );
+}
+
+//
+// config
+void LiquidCrystal_I2C::config (uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 )
+{
+ _Addr = lcd_Addr;
+
+ _backlightPinMask = 0;
+ _backlightStsMask = LCD_NOBACKLIGHT;
+ _polarity = POSITIVE;
+
+ _En = ( 1 << En );
+ _Rw = ( 1 << Rw );
+ _Rs = ( 1 << Rs );
+
+ // Initialise pin mapping
+ _data_pins[0] = ( 1 << d4 );
+ _data_pins[1] = ( 1 << d5 );
+ _data_pins[2] = ( 1 << d6 );
+ _data_pins[3] = ( 1 << d7 );
+}
+
+
+
+// low level data pushing commands
+//----------------------------------------------------------------------------
+
+//
+// send - write either command or data
+void LiquidCrystal_I2C::send(uint8_t value, uint8_t mode)
+{
+ // No need to use the delay routines since the time taken to write takes
+ // longer that what is needed both for toggling and enable pin an to execute
+ // the command.
+
+ if ( mode == FOUR_BITS )
+ {
+ write4bits( (value & 0x0F), COMMAND );
+ }
+ else
+ {
+ write4bits( (value >> 4), mode );
+ write4bits( (value & 0x0F), mode);
+ }
+}
+
+//
+// write4bits
+void LiquidCrystal_I2C::write4bits ( uint8_t value, uint8_t mode )
+{
+ uint8_t pinMapValue = 0;
+
+ // Map the value to LCD pin mapping
+ // --------------------------------
+ for ( uint8_t i = 0; i < 4; i++ )
+ {
+ if ( ( value & 0x1 ) == 1 )
+ {
+ pinMapValue |= _data_pins[i];
+ }
+ value = ( value >> 1 );
+ }
+
+ // Is it a command or data
+ // -----------------------
+ if ( mode == DATA )
+ {
+ mode = _Rs;
+ }
+
+ pinMapValue |= mode | _backlightStsMask;
+ pulseEnable ( pinMapValue );
+}
+
+//
+// pulseEnable
+void LiquidCrystal_I2C::pulseEnable (uint8_t data)
+{
+ _i2cio.write (data | _En); // En HIGH
+ _i2cio.write (data & ~_En); // En LOW
+}
View
204 lib/LiquidCrystal/LiquidCrystal_I2C.h
@@ -0,0 +1,204 @@
+// ---------------------------------------------------------------------------
+// Created by Francisco Malpartida on 20/08/11.
+// Copyright 2011 - Under creative commons license 3.0:
+// Attribution-ShareAlike CC BY-SA
+//
+// This software is furnished "as is", without technical support, and with no
+// warranty, express or implied, as to its usefulness for any purpose.
+//
+// Thread Safe: No
+// Extendable: Yes
+//
+// @file LiquidCrystal_I2C.h
+// This file implements a basic liquid crystal library that comes as standard
+// in the Arduino SDK but using an I2C IO extension board.
+//
+// @brief
+// This is a basic implementation of the LiquidCrystal library of the
+// Arduino SDK. The original library has been reworked in such a way that
+// this class implements the all methods to command an LCD based
+// on the Hitachi HD44780 and compatible chipsets using I2C extension
+// backpacks such as the I2CLCDextraIO with the PCF8574* I2C IO Expander ASIC.
+//
+// The functionality provided by this class and its base class is identical
+// to the original functionality of the Arduino LiquidCrystal library.
+//
+//
+// @author F. Malpartida - fmalpartida@gmail.com
+// ---------------------------------------------------------------------------
+#ifndef LiquidCrystal_I2C_h
+#define LiquidCrystal_I2C_h
+#include <inttypes.h>
+#include <Print.h>
+
+#include "I2CIO.h"
+#include "LCD.h"
+
+
+class LiquidCrystal_I2C : public LCD
+{
+public:
+
+ /*!
+ @method
+ @abstract Class constructor.
+ @discussion Initializes class variables and defines the I2C address of the
+ LCD. The constructor does not initialize the LCD.
+
+ @param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
+ the address can be configured using the on board jumpers.
+ */
+ LiquidCrystal_I2C (uint8_t lcd_Addr);
+ // Constructor with backlight control
+ LiquidCrystal_I2C (uint8_t lcd_Addr, uint8_t backlighPin, t_backlighPol pol);
+
+ /*!
+ @method
+ @abstract Class constructor.
+ @discussion Initializes class variables and defines the I2C address of the
+ LCD. The constructor does not initialize the LCD.
+
+ @param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
+ the address can be configured using the on board jumpers.
+ @param En[in] LCD En (Enable) pin connected to the IO extender module
+ @param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
+ @param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
+ */
+ LiquidCrystal_I2C( uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs);
+ // Constructor with backlight control
+ LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
+ uint8_t backlighPin, t_backlighPol pol);
+
+ /*!
+ @method
+ @abstract Class constructor.
+ @discussion Initializes class variables and defines the I2C address of the
+ LCD. The constructor does not initialize the LCD.
+
+ @param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
+ the address can be configured using the on board jumpers.
+ @param En[in] LCD En (Enable) pin connected to the IO extender module
+ @param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
+ @param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
+ @param d4[in] LCD data 0 pin map on IO extender module
+ @param d5[in] LCD data 1 pin map on IO extender module
+ @param d6[in] LCD data 2 pin map on IO extender module
+ @param d7[in] LCD data 3 pin map on IO extender module
+ */
+ LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
+ // Constructor with backlight control
+ LiquidCrystal_I2C(uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
+ uint8_t backlighPin, t_backlighPol pol);
+ /*!
+ @function
+ @abstract LCD initialization and associated HW.
+ @discussion Initializes the LCD to a given size (col, row). This methods
+ initializes the LCD, therefore, it MUST be called prior to using any other
+ method from this class or parent class.
+
+ The begin method can be overloaded if necessary to initialize any HW that
+ is implemented by a library and can't be done during construction, here
+ we use the Wire class.
+
+ @param cols[in] the number of columns that the display has
+ @param rows[in] the number of rows that the display has
+ @param charsize[in] size of the characters of the LCD: LCD_5x8DOTS or
+ LCD_5x10DOTS.
+ */
+ virtual void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);
+
+ /*!
+ @function
+ @abstract Send a particular value to the LCD.
+ @discussion Sends a particular value to the LCD for writing to the LCD or
+ as an LCD command.
+
+ Users should never call this method.
+
+ @param value[in] Value to send to the LCD.
+ @param mode[in] DATA - write to the LCD CGRAM, COMMAND - write a
+ command to the LCD.
+ */
+ virtual void send(uint8_t value, uint8_t mode);
+
+ /*!
+ @function
+ @abstract Sets the pin to control the backlight.
+ @discussion Sets the pin in the device to control the backlight. This device
+ doesn't support dimming backlight capability.
+
+ @param 0: backlight off, 1..255: backlight on.
+ */
+ void setBacklightPin ( uint8_t value, t_backlighPol pol );
+
+ /*!
+ @function
+ @abstract Switch-on/off the LCD backlight.
+ @discussion Switch-on/off the LCD backlight.
+ The setBacklightPin has to be called before setting the backlight for
+ this method to work. @see setBacklightPin.
+
+ @param value: backlight mode (HIGH|LOW)
+ */
+ void setBacklight ( uint8_t value );
+
+private:
+
+ /*!
+ @method
+ @abstract Initializes the LCD class
+ @discussion Initializes the LCD class and IO expansion module.
+ */
+ int init();
+
+ /*!
+ @function
+ @abstract Initialises class private variables
+ @discussion This is the class single point for initialising private variables.
+
+ @param lcd_Addr[in] I2C address of the IO expansion module. For I2CLCDextraIO,
+ the address can be configured using the on board jumpers.
+ @param En[in] LCD En (Enable) pin connected to the IO extender module
+ @param Rw[in] LCD Rw (Read/write) pin connected to the IO extender module
+ @param Rs[in] LCD Rs (Reset) pin connected to the IO extender module
+ @param d4[in] LCD data 0 pin map on IO extender module
+ @param d5[in] LCD data 1 pin map on IO extender module
+ @param d6[in] LCD data 2 pin map on IO extender module
+ @param d7[in] LCD data 3 pin map on IO extender module
+ */
+ void config (uint8_t lcd_Addr, uint8_t En, uint8_t Rw, uint8_t Rs,
+ uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7 );
+
+ /*!
+ @method
+ @abstract Writes an 4 bit value to the LCD.
+ @discussion Writes 4 bits (the least significant) to the LCD control data lines.
+ @param value[in] Value to write to the LCD
+ @param more[in] Value to distinguish between command and data.
+ COMMAND == command, DATA == data.
+ */
+ void write4bits(uint8_t value, uint8_t mode);
+
+ /*!
+ @method
+ @abstract Pulse the LCD enable line (En).
+ @discussion Sends a pulse of 1 uS to the Enable pin to execute an command
+ or write operation.
+ */
+ void pulseEnable(uint8_t);
+
+
+ uint8_t _Addr; // I2C Address of the IO expander
+ uint8_t _backlightPinMask; // Backlight IO pin mask
+ uint8_t _backlightStsMask; // Backlight status mask
+ I2CIO _i2cio; // I2CIO PCF8574* expansion module driver I2CLCDextraIO
+ uint8_t _En; // LCD expander word for enable pin
+ uint8_t _Rw; // LCD expander word for R/W pin
+ uint8_t _Rs; // LCD expander word for Register Select pin
+ uint8_t _data_pins[4]; // LCD data lines
+
+};
+
+#endif
View
209