Multiplex a HD44780 20x2 LCD display

Hi,

I want to control a HD44780-compatible LCD, but also multiplex the pins used so they can be interfaced with another module.

I'll be using an Arduino Nano.

Can the Arduino LCD library be used if I want to re-use the pins through multiplexing? I'd need:

  1. some sort of chip-select pin that would tell the LCD to enter hi-Z mode on its pins.
  2. I'd also have to make sure the LCD library doesn't interfere with the pins while I'm talking to the other module.

Is the above possible, when using the LCD library?

Thank

There's already the enable pin that acts as a chip select for the LCD, all other pins can be shared without any changes if you don't read from the LCD.
You can connect all the pins going to the LCD (apart from enable) to something else and the LCD will ignore their state as long as the enable pin is kept High.
Of course you'll need another chip select to not mess the other stuff when sending data to the LCD.

semicolo:
There's already the enable pin that acts as a chip select for the LCD, all other pins can be shared without any changes if you don't read from the LCD.
You can connect all the pins going to the LCD (apart from enable) to something else and the LCD will ignore their state as long as the enable pin is kept High.
Of course you'll need another chip select to not mess the other stuff when sending data to the LCD.

I don't think this is completely correct but it isn't completely wrong either.

The enable pin does not act as a chip select in the same way for the LCD controller as it would on something like a tri-state buffer. The LCD reads the status of its data lines on the falling edge of the enable pin and it will ignore the status of those lines at other times. This doesn't necessarily mean that the LCD circuitry will not affect other devices that are trying to use those lines at those other times.

It is true that you can connect all the pins going to the LCD (apart from enable) to something else another LCD and the first LCD will ignore their state as long as the enable pin is kept High. I have also seen examples of applications that share the four data lines with keypads, but those are essentially switches, not IC gates.

So, if you want to interface with another LCD module you will be ok, but not necessarily with any other type of 'module' or any other type of 'something else'.

Don

I routinely use 5 of the 6 pins used to connect an LCD display for other I/O functions as well. I used either the standard LiquidCrystal library or a customized version of it. The only pin that has to be dedicated to the display is the one driving the Enable signal. Tie the R/W LCD pin to ground that the LCD never drives any of those 5 signal lines.

floresta:

semicolo:
There's already the enable pin that acts as a chip select for the LCD, all other pins can be shared without any changes if you don't read from the LCD.
You can connect all the pins going to the LCD (apart from enable) to something else and the LCD will ignore their state as long as the enable pin is kept High.
Of course you'll need another chip select to not mess the other stuff when sending data to the LCD.

I don't think this is completely correct but it isn't completely wrong either.

The enable pin does not act as a chip select in the same way for the LCD controller as it would on something like a tri-state buffer. The LCD reads the status of its data lines on the falling edge of the enable pin and it will ignore the status of those lines at other times. This doesn't necessarily mean that the LCD circuitry will not affect other devices that are trying to use those lines at those other times.

It is true that you can connect all the pins going to the LCD (apart from enable) to something else another LCD and the first LCD will ignore their state as long as the enable pin is kept High. I have also seen examples of applications that share the four data lines with keypads, but those are essentially switches, not IC gates.

So, if you want to interface with another LCD module you will be ok, but not necessarily with any other type of 'module' or any other type of 'something else'.

Don

My understanding of the hd44780 interface is that the "idle" (when not talking to the LCD) state for E is low.
So my understanding would lead me to keep enable low when not using or wanting to talk
to the associated LCD.
I would do this for three reasons:

  1. the LCD ignores the control lines and does not read or drive the data lines when E is low

  2. the LCD looks at the control lines on the rising edge of E or when E is high.
    It can and will react when E is high depending on the state of the control lines.
    For example, if R/W is high then the LCD will drive the data lines.
    So if R/W is one of the pins that is being driven by an Arduino pin and shared, the LCD
    will be stomping on the data pins every time R/W goes high when E is high.

  3. If you push E high when not using the LCD. Then when you want to talk to the LCD
    again, you have to set up the control lines. If E is still high you while you are modifying
    the control lines, you are now violating tAS which says that you must have R/W and RS stable
    for tAS before you raise E.
    While it may not affect most LCDs, I don't like to knowingly violate the LCD interface timing specs.


The library that ships with Arduino does allow sharing of the data pins with other peripherals.
The library re-programs the data pins to be output every time it sends a byte to the lcd (command or data).
The library does not re-program the control lines (E, RS, R/W (if used)).
So this means that yes you can share the data lines with something else but not the control lines.
The library will set the E line back to low when done sending a command or data byte to allow
the data lines to be used for some other purpose.

Just keep in mind that whatever else is using the Arduino pins that are connected to the LCD data pins
should re-program the pins to the needed input/output mode.
Theoretically it could get away with not setting the mode if the pins are all output since the liquid crystal library will
set them to output.
But better practice would be to set the pins to the desired mode in case there is yet another
library sharing the pins that alters the pin mode.


Summary:
If you are using the liquidcrystal library that ships with the IDE you can share pins.
If you use 4 bit mode, 6 Arduino pins are used to talk to 7 LCD pins:
E, RS, D4, D5, D6, D7.
Tie the R/W line on the LCD to ground and save the Arduino pin.
I would not waste an Arduino pin for LCD R/W since the liquidCrystal library
will set it to LOW and not really do anything other than waste a pin.

You can share the Arduino pins hooked to LCD pins D4, D5, D6, D7 with other peripherals.
You cannot share the Arduino pins hooked up to LCD E and RS
You don't have to do anything special. The library takes care of allowing the data pin sharing.
NOTE:
Theoretically you could share the Arduino pin hooked up to the LCD RS line
but the library doesn't reset the mode for the RS pin
like it does for the data lines, so if the other peripheral code sets the RS pin to input, then
the LiquidCrystal library will no longer work.
It is a one line patch to the LiquidCrystal library to correct this if you really want/need
to share the pin used for the LCD RS line.

I will say that not all HD44780 libraries support the ability to share pins.
For example, fm's new liquidcrystal library will not support sharing the data lines.
It increases performance by not re-programming the data lines to be outputs each time a byte is
sent to the LCD.

--- bill

Extremely helpful! Thank you everyone.

Bill, just to confirm:

I do want to re-use the RS line for another purpose. You say:

It is a one line patch to the LiquidCrystal library to correct this if you really want/need
to share the pin used for the LCD RS line.

So I could just re-assert the pin used for the LCD RS line as an an output after each time that I use the other module, like so:

// Insert code for other module here

pinMode(LCD_RS, OUTPUT);

// Insert code for LCD module here

Or would I have to modify the CPP code for the LiquidCrystal library?

Thanks again!
Jody

While it should be done it LiquidCrystal.cpp to make it "just work".

You could do it in your sketch code and it would work ok.
You just need to make sure that if the other code alters the mode from OUTPUT
that you reset it back before you call any lcd function.
You will also need to make sure that you aren't messing with these pins from
interrupt routines.

--- bill