LiquidCrystal_SR1W.h
Go to the documentation of this file.

    00001
    00002 // ---------------------------------------------------------------------------
    00003 // Created/Adapted by Stephen Erisman 2013-07-06
    00004 // Copyright 2013 - Under creative commons license 3.0:
    00005 //        Attribution-ShareAlike CC BY-SA
    00006 //
    00007 // This software is furnished "as is", without technical support, and with no
    00008 // warranty, express or implied, as to its usefulness for any purpose.
    00009 //
    00010 // @file LiquidCrystal_SR1W.h
    00011 // Connects a hd44780 LCD using 1 pin from the Arduino, via an 8-bit Latching
    00012 // ShiftRegister (SR1W from now on).
    00013 //
    00014 // @brief
    00015 // This is the 1 wire shift register interface class for the LCD library
    00016 //
    00017 // The functionality provided by this class and its base class is a superset of
    00018 // the original functionality of the Arduino LiquidCrystal library and can
    00019 // be used as such.
    00020 // See the LCD class for a full description of the API functions available.
    00021 //
    00022 // It works with a 8-bit latched, no-tristate, unidirectional SIPO (Serial-In-Parallel-Out)
    00023 // shift register, and an hd44780 LCD in 4-bit mode.
    00024 // The 74HC595 shift register has been tested.
    00025 //
    00026 //
    00027 // 1 Pin required from the Arduino:
    00028 // - Serial PIN:
    00029 //    The Serial PIN is wired directly to the shift register's Clock PIN and its
    00030 //    unaltered signal directly triggers the Clock on every LOW to HIGH transition.
    00031 //
    00032 //    Additionally, the Serial PIN is wired through a resistor capacitor (RC) filter to
    00033 //    the shift register's Data PIN.  During a quick transition of the Serial PIN the
    00034 //    RC filter will maintain the Data PIN's previous value because the capacitor isn't
    00035 //    given enough time to charge (or discharge) to the alternate state.  If the transition
    00036 //    is held for enough time, however, the RC capacitor will charge (or discharge) and the
    00037 //    value seen by the Data PIN will have changed state.
    00038 //
    00039 //    There are two circuit versions that behave differently for Latch, Enable, and Clear:
    00040 //
    00041 //  HW_CLEAR version:
    00042 //    In this version the shift register's Latch and LCD's Enable PINs are wired directly to
    00043 //    the shift register's Q'H output.  The shift register's /Clear PIN is then wired up
    00044 //    through two logic "gates": first QH and Q'H are AND'd together with a diode-resistor
    00045 //    "gate" the output of which is NAND'd with VCC using a resistor-NPN-resistor "gate".
    00046 //    So, /CLR = ((QH AND Q'H) NAND VCC).  We also put a capacitor on the NPN base to GND
    00047 //    to delay the signal a bit and allow the Latch and EN signals some extra time to trigger.
    00048 //
    00049 //    This all fits together as follows:
    00050 //      1. We shift in a '1'.
    00051 //      2. Ws shift in the other 7 bits.
    00052 //      3. At this point the first '1' has been shifted into Q'H causing it to go HIGH.
    00053 //      4. When Q'H is HIGH it causes Latch and EN to also go HIGH.
    00054 //      5. When Latch transitions to HIGH it changes the shift register outputs to the bits
    00055 //         that were shifted in.
    00056 //      6. This causes QH to go HIGH (if it wasn't already).
    00057 //      7. Now that QH AND Q'H are both HIGH they causes the base capacitor to start charging.
    00058 //      8. When the capacitor has charged enough the transistor brings /CLR LOW.
    00059 //      8. This will cause /CLR to trigger and the shift register will be cleared
    00060 //         (NOTE: This doesn't change the latched outputs)
    00061 //      9. The clearing of the shift register causes Q'H to go LOW.
    00062 //      9. When Q'H is LOW it causes Latch and EN to also go LOW.
    00063 //      10. When EN transitions to LOW the LCD reads in the bits on the shift register pins
    00064 //          and does it's thing.
    00065 //      11. Now that Q'H is LOW the base capacitor starts discharging.
    00066 //      12. When the capacitor has discharged enough the transistor will stop sinking /CLR.
    00067 //      13. This will cause /CLR to be pulled back up to HIGH by the VCC pullup resistor
    00068 //          (it will stay that way until our next nibble/byte has been shifted in)
    00069 //      14. We are now ready for our next nibble/byte.
    00070 //
    00071 //
    00072 //  SW_CLEAR version:
    00073 //    In this version the Serial PIN is wired to the shift register's Latch and LCD's Enable
    00074 //    PINs through another RC filter.  These PINs are also wired through a diode (AND "gate")
    00075 //    tied to the shift register's Q'H output.  This combination means that the Latch and
    00076 //    Enable PINs will be held LOW as long as EITHER the Q'H or RC output is LOW.
    00077 //
    00078 //    This all fits together as follows:
    00079 //      1. We shift in a '1'.
    00080 //      2. We shift in the other 7 bits. (NOTE: We leave Serial PIN HIGH at the end of this)
    00081 //      3. At this point the first '1' has been shifted into Q'H causing it to go HIGH.
    00082 //         (NOTE: Up until this time Q'H has been LOW so the attached diode has been keeping
    00083 //          the Latch/EN pins LOW.)
    00084 //      4. Now that Q'H is HIGH it causes the attached diode to stop discharging the Latch/EN
    00085 //         capacitor.  We delay here for a while to make sure it is fully charged.
    00086 //      5. When the capacitor has charged enough Latch/EN will be HIGH
    00087 //      5. When Latch transitions to HIGH it changes the shift register outputs to what was
    00088 //         shifted in.
    00089 //      6. We now bring the Serial PIN LOW and wait for the Latch/EN capacitor to discharge.
    00090 //      7. When the capacitor has discharged enough Latch/EN will be LOW
    00091 //      8. When EN transitions to LOW the LCD reads in the bits on the shift register pins
    00092 //         and does it's thing.
    00093 //      9. We now shift in '0' 8 times (as quickly as possible).
    00094 //      10. If we keep the LOW to HIGH to LOW pulses short enough while shifting in the '0's
    00095 //          the Latch/EN capacitor won't have time to charge to a point where it will re-trigger
    00096 //          the Latch/EN pins.
    00097 //      11. Now Q'H will be LOW and the shift register has been cleared (NOTE: This doesn't
    00098 //          change the latched outputs.)
    00099 //      12. We now bring the Serial PIN HIGH again and wait for the Data capacitor to recharge.
    00100 //      13. When the Data capacitor has fully charged we are ready for our next nibble/byte.
    00101 //
    00102 //
    00103 // These designs incorporate (and merge) ideas originally found here (1-wire concept):
    00104 //   http://www.romanblack.com/shift1.htm
    00105 // and here (diode-resistor AND "gate" EN control):
    00106 //   http://www.rentron.com/Myke1.htm
    00107 // as well as introducing some new and original ideas (particularly how HW_CLEAR works).
    00108 //
    00109 // Because of its use of the diode AND "gate", the SW_CLEAR design allows for faster sending
    00110 // of data to the LCD compared to Roman's original design.  With the proposed 5uS delay (see
    00111 // notes below), a byte can be sent to the LCD in as little as 30 uS (plus overhead) when
    00112 // sending all 1's. This increases to as much as 190 uS (plus overhead) when sending all 0's.
    00113 // This is in comparison to Roman's estimate of around 3-4 mS to send a byte. So this
    00114 // implementation is 15-133 times faster for the cost of a single (1N4148 or similar) diode.
    00115 //
    00116 // The HW_CLEAR version is even faster as it can completely eliminate the clearSR() call as
    00117 // well as the delays that are needed to latch the data in the SW_CLEAR version.
    00118 //
    00119 //
    00120 // Default Shift Register Bits - Shifted MSB first:
    00121 // Bit #0 (QA) - not used
    00122 // Bit #1 (QB) - connects to LCD data input D7
    00123 // Bit #2 (QC) - connects to LCD data input D6
    00124 // Bit #3 (QD) - connects to LCD data input D5
    00125 // Bit #4 (QE) - connects to LCD data input D4
    00126 // Bit #5 (QF) - optional backlight control
    00127 // Bit #6 (QG) - connects to RS (Register Select) on the LCD
    00128 // Bit #7 (QH) - used for /CLR on the HW_CLEAR version (cannot be changed)
    00129 //        (Q'H) - used for Latch/EN (via the diode AND "gate") (cannot be changed)
    00130 //
    00131 // NOTE: Any of these can be changed around as needed EXCEPT Bit #7 (QH and Q'H).
    00132 //
    00133 //
    00134 // Circuit Types (for the 74HC595)
    00135 // -------------------------------
    00136 // The 74HC595 is a latching shift register.  See the explanations above for how these circuits
    00137 // work.
    00138 //
    00139 //
    00140 // HW_CLEAR version: (Faster but higher part count)
    00141 // ------------------------------------------------
    00142 //
    00143 //                         74HC595     (VCC)
    00144 //                       +----u----+     |        2.2nF
    00145 // (LCD D7)------------1-|QB    VCC|-16--+    +----||----(GND)
    00146 // (LCD D6)------------2-|QC     QA|-15       |
    00147 // (LCD D5)------------3-|QD    SER|-14-------+--[ Resistor ]--+
    00148 // (LCD D4)------------4-|QE    /OE|-13--(GND)     1.5k        |
    00149 // (BL Circuit)--------5-|QF    RCK|-12-----+                  |
    00150 //                       |         |         \                 |
    00151 // (LCD RS)------------6-|QG    SCK|-11-------)----------------+--(Serial PIN)
    00152 //                       |         |          |
    00153 //             +-------7-|QH   /CLR|-10-------)--+--[ Resistor ]--(VCC)
    00154 //             |         |         |         /   |       1k
    00155 //             |    +--8-|GND   Q'H|--9-----+    |
    00156 //             |    |    +---------+        |    |         (GND)--(LCD RW)
    00157 //             |    |      0.1uF            |     \
    00158 //             |  (GND)-----||----(VCC)     +------)--------------(LCD EN)
    00159 //             |                            |     /
    00160 //             |----|<|----+--[ Resistor ]--|    |
    00161 //                 diode   |       1k            C
    00162 //                         |                     |
    00163 //                         +-------------+---B-|> (NPN)
    00164 //                                       |       |
    00165 //                               (2.2nF) =       E
    00166 //                                       |       |
    00167 //                                     (GND)   (GND)
    00168 //
    00169 //
    00170 // SW_CLEAR version: (Lower part count but slower)
    00171 // -----------------------------------------------
    00172 //
    00173 //                         74HC595     (VCC)
    00174 //                       +----u----+     |          2.2nF
    00175 // (LCD D7)------------1-|QB    VCC|-16--+      +----||----(GND)
    00176 // (LCD D6)------------2-|QC     QA|-15         |
    00177 // (LCD D5)------------3-|QD    SER|-14---------+--[ Resistor ]--+
    00178 // (LCD D4)------------4-|QE    /OE|-13--(GND)         1.5k      |
    00179 // (BL Circuit)--------5-|QF    RCK|-12---------+                |
    00180 //                       |         |             \               |
    00181 // (LCD RS)------------6-|QG    SCK|-11-----------)--------------+--(Serial PIN)
    00182 //                     7-|QH   /CLR|-10--(VCC)   /               |
    00183 //                  +--8-|GND   Q'H|--9---|<|---+--[ Resistor ]--+
    00184 //                  |    +---------+     diode  |      1.5k
    00185 //                  |                           |
    00186 //                  |      0.1uF                |
    00187 //                (GND)-----||----(VCC)         +----||----(GND)
    00188 //                                              |   2.2nF
    00189 // (LCD EN)-------------------------------------+
    00190 // (LCD RW)--(GND)
    00191 //
    00192 //
    00193 // In either case the LCD RW pin is hardwired to GND meaning we will only be able to write
    00194 // to the LCD.
    00195 // Therefore, the Busy Flag (BF, data bit D7) is not able to be read and we have to make use
    00196 // of the minimum delay time constraints.  This isn't really a problem because it usually
    00197 // takes us longer to shift and latch the data than the minimum delay anyway.  For now, we
    00198 // simply keep track of our delays and add more delay at the end to get to at least 37 uS.
    00199 //
    00200 //
    00201 // Backlight Control Circuit
    00202 // -------------------------
    00203 // Since we are using the latching nature of the shift resiter we don't need the extra
    00204 // backlight circuitry that SR2W uses.  Keeping it around, however, would still work because
    00205 // the circuit just slows down the transitions to the mosfet a bit.
    00206 //
    00207 // Here are two more optimized versions that can be used.
    00208 //
    00209 //
    00210 // NPN Transistor version: (Cheaper but more power draw and higher part count)
    00211 // ---------------------------------------------------------------------------
    00212 //
    00213 //                (value depends on LCD, 100ohm is usually safe)
    00214 // (LCD BL anode)---[ resistor ]---(VCC)
    00215 //
    00216 // (LCD BL cathode)---------------+
    00217 //                                |
    00218 //                                C
    00219 //                                |
    00220 // (BL input)--[ Resistor ]---B-|> (NPN)
    00221 //                  1k            |
    00222 //                                E
    00223 //                                |
    00224 //                              (GND)
    00225 //
    00226 // NOTE: The Bate resistor is needed because the NPN is current fed.  For lower
    00227 //       power draw, try a 10k resistor.
    00228 //
    00229 //
    00230 // N-CH Mosfet version: (More costly but less power draw and lower part count)
    00231 // ---------------------------------------------------------------------------
    00232 //
    00233 //                (value depends on LCD, 100ohm is usually safe)
    00234 // (LCD BL anode)---[ resistor ]---(VCC)
    00235 //
    00236 // (LCD BL cathode)---------------+
    00237 //                                |
    00238 //                                D
    00239 //                                |
    00240 // (BL input)----------------G-|-< (2N7000 FET)
    00241 //                                |
    00242 //                                S
    00243 //                                |
    00244 //                              (GND)
    00245 //
    00246 // NOTE: Gate resistor not needed because the mosfet is voltage fed and only really
    00247 //       pulls current while switching.
    00248 //
    00249 // In either case, when the BL input is HIGH the LCD backlight will turn on.
    00250 //
    00251 //
    00252 // History
    00253 // 2013.07.31 serisman - fixed potential interrupt bug and made more performance optimizations
    00254 // 2013.07.10 serisman - more performance optimizations and modified the HW_CLEAR circuit a bit
    00255 // 2013.07.09 serisman - added an even faster version that performs the clear in hardware
    00256 // 2013.07.08 serisman - changed code to shift data MSB first to match SR2W
    00257 // 2013.07.07 serisman - major speed optimization
    00258 // 2013.07.06 serisman - created/modified from SR2W source to create SR1W
    00259 // @author  S. Erisman - arduino@serisman.com
    00260 // --------------------------------------------------------------------------------
    00261
    00262 #ifndef _LIQUIDCRYSTAL_SR1W_
    00263 #define _LIQUIDCRYSTAL_SR1W_
    00264
    00265 #include <inttypes.h>
    00266 #include "LCD.h"
    00267 #include "FastIO.h"
    00268
    00269 // 1-wire SR timing constants
    00270 // ---------------------------------------------------------------------------
    00271
    00272 // NOTE:
    00273 //  The 1.5k resistor (1.2k - 1.8k with a 20% tolerance)
    00274 //   takes between 2.376uS and 4.36uS to fully charge or discharge
    00275 //       the 2.2n capacitor (1.98n - 2.42n with a 10% tolerance).
    00276 //      We round this up to a 5uS delay to provide an additional safety margin.
    00277
    00278 #define SR1W_DELAY_US           5
    00279 #define SR1W_DELAY()            { delayMicroseconds(SR1W_DELAY_US); numDelays++; }
    00280
    00281 // 1-wire SR output bit constants
    00282 // ---------------------------------------------------------------------------
    00283
    00284 #define SR1W_UNUSED_MASK        0x01    // Set unused bit(s) to '1' as they are slightly faster to clock in.
    00285 #define SR1W_D7_MASK            0x02
    00286 #define SR1W_D6_MASK            0x04
    00287 #define SR1W_D5_MASK            0x08
    00288 #define SR1W_D4_MASK            0x10
    00289 #define SR1W_BL_MASK            0x20
    00290 #define SR1W_RS_MASK            0x40
    00291 #define SR1W_EN_MASK            0x80    // This cannot be changed. It has to be the first thing shifted in.
    00292
    00293 #define SR1W_ATOMIC_WRITE_LOW(reg, mask)        ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *reg &= ~mask; }
    00294 #define SR1W_ATOMIC_WRITE_HIGH(reg, mask)       ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { *reg |= mask; }
    00295
    00296
    00297 typedef enum { SW_CLEAR, HW_CLEAR } t_sr1w_circuitType;
    00298
    00299 class LiquidCrystal_SR1W : public LCD
    00300 {
    00301 public:
    00313    LiquidCrystal_SR1W (uint8_t srdata, t_sr1w_circuitType circuitType,
    00314                        t_backlighPol blpol = POSITIVE);
    00315
    00328    virtual void send(uint8_t value, uint8_t mode);
    00329
    00330
    00340    void setBacklight ( uint8_t mode );
    00341
    00342 private:
    00343
    00349    void init ( uint8_t srdata, t_sr1w_circuitType circuitType, t_backlighPol blpol,
    00350                uint8_t lines, uint8_t font );
    00351
    00357    uint8_t clearSR ();
    00358
    00363    uint8_t loadSR (uint8_t val);
    00364
    00365    fio_register _srRegister; // Serial PIN
    00366    fio_bit _srMask;
    00367
    00368    t_sr1w_circuitType _circuitType;
    00369
    00370    uint8_t _blPolarity;
    00371    uint8_t _blMask;
    00372 };
    00373 #endif

All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines