Pages: [1] 2 3   Go Down
Author Topic: Reading from HD44780-based LCDs  (Read 4086 times)
0 Members and 1 Guest are viewing this topic.
The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey, it's me again, this time with some interesting questions:
I have been working with a Hitachi HD44780-based LCD and as part of my project I am writing an extended library to perform read operations from the screen.

The datasheet for the HD44780 says the following regarding readings:
CMDRSR/WDB7-0
Read Busy Flag & Address01BF (DB7) Address (DB6-0)
Read data from CG/DD RAM11Data (DB7-0)

Now, the operation in question is trivial to implement when using 8bit mode, as all data channels are available. The question is, when working in 4bit mode, how is the data read then? I can't find any available documentation on this subject. Any help would be appreciated. Thanks
Logged

midwest US
Offline Offline
Newbie
*
Karma: 0
Posts: 17
I void warranties
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Basically, the same way it's sent into the HD44780, 4 bits at a time.  there will be two operations for every 8 bits, because its passed 4 bits at a time.

Take a look at page 42 of the datasheet http://www.sparkfun.com/datasheets/LCD/HD44780.pdf for more detail on how 4 bit operations work.

Logged

The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The datasheet you linked only says about write operations to the controller, it does not mention read operations.

I tried sending a pulse to the strobe (enable) to get the next bit, but that caused undesired side effects, like text randomly disappearing from the screen, which leads me to believe that approach is wrong.
Logged

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

OrlandoArias:

As you probably know, when you write information to the LCD module in four-bit mode it temporarily stores the first group of four bits that it receives (with the first enable pulse).  After it receives the second group of four bits (with the second enable pulse) it reassembles them into an eight bit byte and deals with the reassembled byte.  

I assume that when you read information from the LCD module in four-bit mode your program would have to do essentially the same thing.  You would send an enable pulse, read the incoming data (the upper four bits of the incoming byte) and stash it away.  You would then generate another enable pulse, and read the incoming data (the lower four bits of the incoming byte).  You then have to do some swapping, masking, ORing etc. to reassemble the byte.

Don
Logged

The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

As I said, I already tried the approach of sending a pulse to the strobe [enable pin], to retrieve the second nibble. That did not work. The screen output is corrupted if that is done.
Logged

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

OrlandoArias:

Quote
As I said, I already tried the approach of sending a pulse to the strobe [enable pin], to retrieve the second nibble.
I'm sorry, but that is not what you said.  Since you have provided almost no information about your program I did the best with what you did provide.

Retrieving data from the LCD module should not corrupt the display.  You have to write data to the LCD module in order to do that.  So your program code must be changing the R/W line between the Enable pulses or something along those lines....

Don
Logged

The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quote
As I said, I already tried the approach of sending a pulse to the strobe [enable pin], to retrieve the second nibble.
I'm sorry, but that is not what you said.

Oh, I believe that is what I said, from two or three posts above:

Quote
I tried sending a pulse to the strobe (enable) to get the next bits, but that caused undesired side effects, like text randomly disappearing from the screen, which leads me to believe that approach is wrong.

Quote
Since you have provided almost no information about your program I did the best with what you did provide.

I need to read from an HD44780-based LCD screen in 4 bit mode. What else do you need to know in order to provide an algorithm?
« Last Edit: September 23, 2009, 03:13:22 pm by TRON007 » Logged

Lancashire, UK
Offline Offline
Edison Member
*
Karma: 9
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Excuse the ol' scepticism, but if you have an LCD connected to the arduino that has data on it you need to read, surely that information came from the arduino in the first place. Wouldn't it be a lot easier to fire up another variable to hold the data for the next time rather than pulling it back from the display ?

Or am I missing something ?
Logged


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

pluggy:

Quote
Or am I missing something ?
It's kind of obscure, but if you are using a display with less than 80 characters (such as a 16 x 2) it is possible to use some of the DDRAM in the LCD controller for general data storage.  I don't know why anyone would want to do this, but it is a possibility.

Don
Logged

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

Orlando:

Quote
Oh, I believe that is what I said, from two or three posts above:
I'm not trying to get into a pissing match here but my background is in engineering, not horseshoes or hand grenades.  I interpret ther term 'quote' as an exact copy of what was originally said.  Reply #2 mentions the next "bit".  Reply #4 mentions the next "nibble".  Reply #6 mentions the next "bits".  I used to tell my students that the implication of not being precise in the explanation of ones work is that perhaps the work itself isn't as precise as it should be.

Quote
As I said, I already tried the approach of sending a pulse to the strobe [enable pin], to retrieve the second nibble. That did not work. The screen output is corrupted if that is done.
But you haven't provided any code to show how you are attempting to retrieve and deal with this data so all I can do is guess at what is wrong, which is what I did in the second part of reply #5.  The scenario that I guessed at is consistant with the description of the behavior that you gave.

Quote
What else do you need to know in order to provide an algorithm?
I thought I provided an algorithm in the second paragraph of Reply #3.  The reason that I used the words "I assume" at the beginning of that paragraph is because I have never actually read from the LCD RAM.  I have however used this technique to read the busy flag which uses essentially the same techniques.

If you want me to write your program for you I can probably do that, although it would be in assembly language.  Please remit $100 in small used bills (or a Gator) to get me started.


Don
Logged

Lancashire, UK
Offline Offline
Edison Member
*
Karma: 9
Posts: 1991
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks floresta.  I think I can live without the extra 48 bytes (presumably) my 16*2 is keeping from me.  I have pin 5 tied to ground anyway so read is a non starter.....  

Logged


The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, this is obviously going nowhere, and I can see how I was, at least partly, responsible for it.

Here's where we stand:
- The LCD is in 4-bit mode.
- The LCD is sent the command to read from itself. The reason this is needed is because if you were to switch to CGRAM to write your own custom character and then write something to the LCD, you must point back to a location on DDRAM, otherwise, you can write a much text as you want, some may show depending on how much you write, and how you set up the LCD to begin with. I want to implement my write CGRAM function to return to the place the cursor was in DDRAM, thus need to read from the LCD.
- I tried sending a pulse to the enable pin in order to get the second nibble. The output on the LCD gets corrupted. Yes, it seemed weird to me as well, as I was writing nothing to it. This leads me to believe that triggering the strobe is the wrong approach.
- I have searched the web tons of time before posting here, which is akin to saying I've given up on finding a solution myself. I am not the kind of person who likes to ask questions.

The library in question is supposed to be an extension (separate library) to my LCD library found in Google Code. With that being said, I have no immediate use for it, it is something that I'd like to have for the future (food for the winter if you will). The code I use I no longer have, deleted it before I committed it to my subversion repository (big mistake, I know), so I have no reference to show. The code was, however, bug free.

Having this data at hand now, and also, whilst apologizing for any misunderstandings/conflicts/headaches/irateness that may posts have caused, I shall post the question again, what to do?

Quote
If you want me to write your program for you I can probably do that, although it would be in assembly language.  Please remit $100 in small used bills (or a Gator) to get me started.
You and I, my good sir or madam, think very much alike. This statement made chuckle, as I've always say similar stuff ;D.
« Last Edit: September 23, 2009, 09:20:31 pm by TRON007 » Logged

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

Orlando:

The LED controller has 80 bytes of DDRAM with each byte corresponding to a specific location on an 80 character (40 x 2 or 20 x4) display.  The Controller continuously scans this memory and for each location it reads the information in DDRAM, uses that information (as an address) to access CGROM or CGRAM and uses the CGROM/RAM data it finds at that address to put the corresponding character on the display.  If you change the data at one of the DDRAM locations then the character displayed at the coresponding display location will change.  Looking at it the other way - the only way to change what is on the display is to change the information in the DDRAM and the only way to change what is in DDRAM is to write information to the LCD controller.

If you pulse the Enable to get the next nibble and the display gets corrupted this means that you are not reading data from the LCD as you intended but you are writing data to the controller instead (which is what I said in reply #5).

In several posts you have stated that you have pulsed the Enable to get the next nibble but you have not mentioned anything about all the other steps that must be taken to read data from the LCD controller.  I assume that you know what these steps are since they are also used in the 8-bit implementation which you imply you have done in your original post.

The bottom line is that neither I nor anyone else can help you any further without seeing some code.

(sir) Don
Logged

The Wired 2.0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 60
Destroy the core!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Keeping in mind the fact that I do not use the Arduino sketch editor (too crummy for me to work on) and that I code directly in C using some of the wiring extensions.

This is how the LCD struct is declared:
Code:
typedef enum _bmode {
      BIT_MODE_4      =4,
      BIT_MODE_8      =8
} bmode;

typedef struct _LCD {
      int datapin[8];
      int rs_pin;
      int rw_pin;
      int enable_pin;
      bmode bitmode;
} LCD;

This implementation is how I'd get data from the LCD.

Since the LCD has only 8 data channels, an 8 bit integer (char type) is enough to hold the data. This is the same implementation I had written a while back and that fails (corrupts the LCD screen display).

Code:
#include <inttypes.h>
#include "WProgram.h"
//some other include that aren't relevant to our issue.
// some interfacing code that has nothing to do with this: lcd_sendRaw()


uint8_t lcd_getRaw(LCD *l, uint8_t rs_mode){
      digitalWrite(l->rs_pin, rs_mode);
      digitalWrite(l->rw_pin, HIGH);

      uint8_t retVal = 0;

      for (int i = 0; i < l->bitmode; i++){
            pinMode(l->datapin[i], INPUT);
            retVal |= (digitalRead(l->datapin[i]) << i);
            pinMode(l->datapin[i], OUTPUT);
      }

      if (l->bitmode == BIT_MODE_4){
            retVal <<= 4; //obtained high nibble, must obtain low.

            digitalWrite(l->enable_pin, HIGH);
            digitalWrite(l->enable_pin, LOW);

            for (int i = 0; i < 4; i++){
                  pinMode(l->datapin[i], INPUT);
                  retVal |= (digitalRead(l->datapin[i]) << i);
                  pinMode(l->datapin[i], OUTPUT);
            }
      }

      digitalWrite(l->enable_pin, HIGH);
      digitalWrite(l->enable_pin, LOW);

      return retVal;
}


This function gets called whenever we need to get the status flag or any address. The status flag is simply obtaining by bitshifting 7 places to the left
Code:
busy_flag =  lcd_getRaw(lcd, LOW) >> 7;

The address counter is obtained by just anding with dec127 (b01111111).
Code:
address_counter = lcd_getRaw(lcd, LOW) & 127;

Reading data from CGRAM or DDRAM is done by calling lcd_getRaw() with a HIGH value for the rs pin
Code:
data = lcd_getRaw(lcd, HIGH);

This, however, fails, and the output is corrupted for some reason. Perhaps I made something overflow somewhere, I don't know. The code looks fine to me, in case anybody has any suggestions, please, let me know.
« Last Edit: September 24, 2009, 10:27:09 pm by TRON007 » Logged

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

I seem to remember seeing this somewhere....

      
Quote
// I wish people would document their code as well as I try to do.

Don
Logged

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