Pages: [1] 2   Go Down
Author Topic: Problem in LiquidCrystal lib (20x4)  (Read 2231 times)
0 Members and 1 Guest are viewing this topic.
Granada Hills, CA USA
Offline Offline
Newbie
*
Karma: 0
Posts: 4
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

First post to this forum but I think I know what I am talking about (you can correct me if you want, I can take it).

I setup an Arduino with a 16x2 display and all works great.
I found a 20x4, hooked it up and things all worked OK.
Next I had a few 16x4 and plugged one in and things did not line up properly.

Looking at the code:

void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
  int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  if ( row > _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }
 
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

Notice that the offset does not change based on characters per line (no way of knowing).

Not sure if this is 'clean' bit it worked for me.

Needed a place to save number of characters so in Begin I added:

void LiquidCrystal::begin(uint8_t cols, uint8_t lines, uint8_t dotsize) {
  if (lines > 1) {
    _displayfunction |= LCD_2LINE;
  }
  _numlines = lines;
  _numcols  = cols;
  _currline = 0;

Then in setCursor I added/changed it like this:void LiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
// 16 Cols   int row_offsets[] = { 0x00, 0x40, 0x10, 0x50 };
// 20 Cols   int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
  int row_offsets[] = { 0x00, 0x40, 0x10, 0x50 };
  if(_numcols == 20) {
    row_offsets[2] = 0x14;
    row_offsets[3] = 0x54;
  }


  if ( row > _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }
 
  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

It now works for me with 16x2, 16x4, 20x2 and 20x4. It only changed the 4 line displays. I don't see any reason it will mess anything else up.

Any comments? How do we get this into the lib if no one else see problems in it?

Thanks
Tim


Logged

Central MN, USA
Online Online
Tesla Member
***
Karma: 65
Posts: 6935
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

16*4 display memory is sometimes organized a bit differently than the 16*2 and 20*4 displays. it is normal.
Logged


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

Quote
Any comments? How do we get this into the lib if no one else see problems in it?
I have commented on this many times.  The LiquidCrystal library does not use the information that it has from the lcd.begin() statement to modify the starting addresses for lines 3 and 4 of the 16x4 modules.  There is no known way for mere mortals to get this corrected.

Don

Edit:  Here's a link from almost two years ago:  http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1253367247

Also:  @tlaren:  You might want to modify the forum topic to say 16x4 instead of 20x4.
« Last Edit: August 21, 2011, 10:23:23 am by floresta » Logged

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

Quote
16*4 display memory is sometimes organized a bit differently than the 16*2 and 20*4 displays.

The 16x4 display memory is always organized a bit differently than the 16*2 and 20*4 displays.  

Quote
it is normal.

It is normal for the display to be organized that way when you consider the technical limitations that existed when the LCD controller was designed.  It is not normal for the library to ignore this fact, it is a flaw in the library.  The last time I tried to have the library fixed I was rebuffed, but shortly thereafter Lady Ada's fixes were incorporated.  Her fixes resulted in a library that actually worked which was the main reason for the modifications, but she didn't deal with this part.

Don

Edit: Search for the LiquidCrystal440 library.  John fixed this problem while modifying the library for 40x4 displays.
« Last Edit: September 04, 2011, 08:36:11 pm by floresta » Logged

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've just posted in the software forum on this subject.

Without copying and pasting, the thrust of the posting is to ask if anyone has written a scrolling routine to overcome this problem? I started to, but soon ran into the limits of my programming skills.

Jim
Logged

Central MN, USA
Online Online
Tesla Member
***
Karma: 65
Posts: 6935
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I've just posted in the software forum on this subject.

Without copying and pasting, the thrust of the posting is to ask if anyone has written a scrolling routine to overcome this problem? I started to, but soon ran into the limits of my programming skills.

Jim

What kind of scrolling are you trying to get? Describe it and someone may have already done it and can share their codes.
Logged


Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What kind of scrolling are you trying to get? Describe it and someone may have already done it and can share their codes.

Thanks for the reply.

I want to scroll a line of around 60 characters from right to left, on the top line of a 16x2 display. It's to display the software version of a project on start-up. The array is assigned to by RCS from within Emacs eg  - char version[] = "$Id$";. I only want to do this the once on initial start-up.

Jim
Logged

Central MN, USA
Online Online
Tesla Member
***
Karma: 65
Posts: 6935
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is an example code, which requires my phi_prompt library support. It essentially does what you want.
From my documentation:

3) void scroll_text(char * src, char * dst, char dst_len, short pos);
You can use this function to animate a line of text. If you have a long message and you want to animate it by scrolling it, you can call this function.
The src points to the source char array. The dst is the buffer that will be filled by the string cut from the source starting at position pos with length dst_len. So your dst char array should be at least dst_len+1 long.
Eg.
Code:
void horizontal_scroll_demo()
{

char thankyou[]="Thank you for using phi_prompt!";
char buffer[15];
lcd.clear();
for (byte i=0;i<47;i++)
{
scroll_text(thankyou,buffer,14,i-14);
lcd.setCursor(1,1);
lcd.print(buffer);
wait_on_escape(250);
}
}
The above function scrolls the char array thankyou and displays it on the LCD as an animation. Notice that when i<14, the position is negative, corresponding to amount of blank spaces before the first character. This helps the animation.

Where to find phi-prompt library:

http://liudr.wordpress.com/libraries/phi_prompt/

I use this function scroll_text() to automatically scroll items on my menus to show long items. It is around 1:40 into this following video:


Logged


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

Quote
I've just posted in the software forum on this subject.

Since you started that second thread it would be appropriate to respond to the posts there as well as the ones here.

Don
Logged

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is an example code, which requires my phi_prompt library support. It essentially does what you want.

It certainly looks like just what I need. I've downloaded and printed the docs and am now going to have a coffee and read them.

Many thanks.

Jim
Logged

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I've just posted in the software forum on this subject.

Since you started that second thread it would be appropriate to respond to the posts there as well as the ones here.

You're quite right - I'll do so.

(I clicked the 'Notify' button on this and the other thread, expecting to get an email notification of replies, but have received no notification from either.)

Jim
Logged

Central MN, USA
Online Online
Tesla Member
***
Karma: 65
Posts: 6935
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

This is an example code, which requires my phi_prompt library support. It essentially does what you want.

It certainly looks like just what I need. I've downloaded and printed the docs and am now going to have a coffee and read them.

Many thanks.

Jim

Alright! The documentation is pretty long though.

If you need all the library features, you are certainly welcome to read the whole thing and use the whole library. If all you need right now is the scrolling text, you can just put this together with the previous code, and replace wait_on_escape(250) by delay(250):

Code:
void scroll_text(char * src, char * dst, char dst_len, short pos)
{
  for (byte j=0;j<dst_len;j++)
  {
    if ((pos<0)||(pos>strlen(src)-1))
    {
      dst[j]=' ';
    }
    else dst[j]=src[pos];
    pos++;
  }
  dst[dst_len]=0;
}

That will get you started.

The wait_on_escape(250) is a delay while polling all buttons so it quits after time expires or button presses. These buttons are discrete tactile buttons hooked to digital pins.
Logged


Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


If all you need right now is the scrolling text, you can just put this together with the previous code, and replace wait_on_escape(250) by delay(250):

Code:
void scroll_text(char * src, char * dst, char dst_len, short pos)
{
  for (byte j=0;j<dst_len;j++)
  {
    if ((pos<0)||(pos>strlen(src)-1))
    {
      dst[j]=' ';
    }
    else dst[j]=src[pos];
    pos++;
  }
  dst[dst_len]=0;
}

It looks like the above, plus your earlier code, will be all I need. Thanks again!

Jim
Logged

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

Quote
(I clicked the 'Notify' button on this and the other thread, expecting to get an email notification of replies, but have received no notification from either.)

This is most likely accomplished by means of 'cookies'.  Since it is working for us you might want to make sure that cookies are enabled in your browser.  It's under the menu  Tools | Options | Privacy on my version of Firefox and probably something similar on the others.

Don
Logged

Hertfordshire, U.K.
Offline Offline
Jr. Member
**
Karma: 1
Posts: 84
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
(I clicked the 'Notify' button on this and the other thread, expecting to get an email notification of replies, but have received no notification from either.)

This is most likely accomplished by means of 'cookies'.  Since it is working for us you might want to make sure that cookies are enabled in your browser.  It's under the menu  Tools | Options | Privacy on my version of Firefox and probably something similar on the others.

Don

I've just checked - the messages were in the junk folder of my ISP account. I've added the email address to the whitelist.

Jim
Logged

Pages: [1] 2   Go Up
Jump to: