Pages: [1] 2 3   Go Down
Author Topic: How to read HD44780 LCD programmatically  (Read 2818 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How can I read the LCD?  It is a common HD44780 compatible LCD, connected in parallel 4-bit mode.
Arduino Mega 2560 Rev 3.

#include <LiquidCrystal.h>
. . .
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

There are lots of methods now for lcd, but they have to with writing to the display.
Are there other methods for the HD44780 in LiquidCrystal.h that are not exposed in the header that I can use for reading the display?
Is there another library with some methods for reading?

Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

How can I read the LCD?  It is a common HD44780 compatible LCD, connected in parallel 4-bit mode.
Arduino Mega 2560 Rev 3.

#include <LiquidCrystal.h>
. . .
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); 

There are lots of methods now for lcd, but they have to with writing to the display.
Are there other methods for the HD44780 in LiquidCrystal.h that are not exposed in the header that I can use for reading the display?
Is there another library with some methods for reading?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There is no reading back as far as I know in any library.
The only way to do this correctly is to make a "shadow" screen which buffers the content send to the screen.

This will effectively result in a HD44780 simulator, not trivial but doable - definitely a project in itself.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

2nd thought,

Better is to use a model view design pattern.
That means that you make a model (set of vars) you want to be displayed. This model will be displayed on the LCD in a separate function. for that it reads the model too.

pseudo code
Code:
struct model
{
int voltage;
float temperature;
}

void loop()
{
  model.voltage = analogRead() * 5.0/1023;
  model.temperature = getTemperature();

  if (millis() - lastDisplay >= refreshTimeout)
  {
     lastDisplay += refreshTimeout;
     // display values from model here
  }
 
  // read back model
  x = model.temperature;
  y = model.voltage;
}

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It is not possible to read from the LCD using the current LiquidCrystal library as there are no provisions to use the R/W signal on pin 5 even if you do choose to connect it. 

The LiquidCrystal440 library and its updated successor does have provisions for checking the busy flag (which involves reading from the LCD) so you could take a look at that library for some ideas. 

To get a copy start here:--> http://code.google.com/p/liquidcrystal440/ and follow the Downloads link to get to the latest version.


Don
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 452
Posts: 18694
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Please do not cross-post. This wastes time and resources as people attempt to answer your question on multiple threads.

Threads merged.

- Moderator
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
The only way to do this correctly is to make a "shadow" screen which buffers the content send to the screen.
You are answering this from a more modern perspective than might have originally been intended when the LCD controller was designed.  I mean that it looks like you are assuming that he wants to read back information that corresponds to that displayed on the screen.

If you are using a display with less than 80 characters then there is some unused RAM in the LCD controller.  In ancient times when RAM was scarce this RAM was a valuable resource and could be (and was) used for general purpose storage.  Perhaps the OP has an application such as this in mind.

Here is what the HD44780U data sheet has to say (just before Figure 1).

Display Data RAM (DDRAM)

Display   data   RAM   (DDRAM)   stores   display   data   represented   in   8-bit   character   codes.   Its   extended
capacity is 80 × 8 bits, or 80 characters. The area in display data RAM (DDRAM) that is not used for
display can be used as general data RAM.
See Figure 1 for the relationships between DDRAM addresses
and positions on the liquid crystal display.


Don
« Last Edit: February 22, 2013, 04:06:57 pm by floresta » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The HD44780 LCD  has functions to read the display in libraries for other microcontrollers (PicBasic, for example).   So I was just searching for the same functions for the Arduino.  I really, really like the Arduino, and don't like it when there is support for other microcontrollers which is lacking for the Arduino.

For the immediate need, I will create an in-memory ("shadow") view of the LCD, send that view to the LCD, and also then be able to read fro that view.  It will be a simple 2x16 array of char.  Fortunately there is a lot of extra programming space in the Mega 2560.  Having this view in RAM serves the capability of cloning the LCD display to the PC, but doesn't help any in auto-testing the LCD, hence the need to read the LCD.

In the future I will work on providing an update to the Arduino library to make it more complete. 

Thank you for all the comments and suggestions!  I consider the question to be answered.
Phil Dorcas
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you have access to library code of one of those other platforms?
Can you post a link?
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In PicBasic, the support for the LCD is built into the language, and I don't have access to it's source code.
The methods to read has two parameters, the first is the address to read from the LCD, usually $80 or $C0 for the first and second lines respectively.  The second parameter is an array of characters, where the LCD characters were placed. 

Examples for reading from the LCD:
  LCDIN $80, [ InArray[20], InArray[21], InArray[22], InArray[23],_
               InArray[24], InArray[25], InArray[26], InArray[27],_
               InArray[28], InArray[29], InArray[30], InArray[31],_
               InArray[32], InArray[33], InArray[34], InArray[35] ]
             
  LCDIN $c0, [InArray[36], InArray[37], InArray[38], InArray[39],_
              InArray[40], InArray[41], InArray[42], InArray[43],_
              InArray[44], InArray[45], InArray[46], InArray[47],_
              InArray[48], InArray[49], InArray[50], InArray[51] ]

I'll read the Fujitsu documentation and figure it out for the Arduino.  Wish I had other source code to access as a guide.  Maybe from the mfg.  Thank you.
Logged

Offline Offline
God Member
*****
Karma: 27
Posts: 829
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Reading from the LCD is pretty much the same as writing to it. When you write to it, you are simply putting a byte into the DDRAM. So, you just read it instead... You do need control of the R/W line, though.

So you set the RS pin high, the R/W line high, then toggle the E line. Each time you toggle the E line, it will increment (or decrement depending on how you set it up) and give you the byte in the next address.

So the only difference is that you are setting the read/write line high instead of low and listening on the data lines instead of writing something to it. Modifying a library wouldn't be much more than copying the functions and changing them to set the read write line and return a byte ( or array of bytes) instead of sending one.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 6
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That sounds easy enough.  Thank you!  I'll look at the LiquidCrystal library, and make the recommended changes.  Thank you very much for your help!
Logged

Offline Offline
God Member
*****
Karma: 27
Posts: 829
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You got me looking at it, actually. There actually already is support for a RW pin if you define one. I've made several little changes already to support reading. If I were to modify the library, what functions would be useful? I would think a read function where you give it an address and length would be useful. What else?
Logged

Western New York, USA
Offline Offline
Faraday Member
**
Karma: 25
Posts: 4110
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
So you set the RS pin high, the R/W line high, then toggle the E line. Each time you toggle the E line, it will increment (or decrement depending on how you set it up) and give you the byte in the next address.
It's not quite that simple in the 4-bit mode since you have to read twice for each byte and reassemble the nibbles.  Also, don't forget that you do the actual reading while E is high, not after it goes low.

Quote
You got me looking at it, actually. There actually already is support for a RW pin if you define one.
Look again.  If you define the pin then all they do is drive it low...PERIOD.

I am not trying to discourage you, I am just pointing out some of the problems.  John went through all of this when he was writing the LiquidCrystal440 library a few years ago and I provided him with some code for starters.  All he was doing is reading the busy flag, but the added work to get the other seven bits should be trivial*.  Why don't you see if you can find anything here --> http://code.google.com/p/liquidcrystal440/ (follow the Downloads link to get to the latest version) before you try to reinvent the wheel.

Don

Edit: * Famous last words....
« Last Edit: March 07, 2013, 04:10:50 pm by floresta » Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 168
Posts: 12430
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I would think a read function where you give it an address and length would be useful. What else?

primary functions would be

char lcd.readChar(row, col)        // reads 1 char
char * lcd.readStr(row, col, len)   // reads len chars - should it wrap around end of line?

some ideas:

char lcd.readChar(); // reads form last known (internal) row/col  e.g. gotoxy(r,c); x = lcd.readchar()

char lcd.readNext(); // reads a char and moves to next position?

maybe some function to read self made chars / font back into an array?

readback backlight status?
bool lcd.getBackLight()
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Pages: [1] 2 3   Go Up
Jump to: