Pages: 1 [2]   Go Down
Author Topic: [solved] 16x4 LCD: Characters in row 3&4 are moved to the right  (Read 3561 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Edison Member
*
Karma: 136
Posts: 1491
If you believe something is right, you won't see what's wrong (David Straker).
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am going to expand my library to ks0108 display
I have planed a device independent library. Hopefully it should also work with the GLCD lib.

We could exchange some tricks.
Sure. But then, we probably should have another thread about tricks and approaches on user interfaces for embedded systems.

Oliver
Logged

Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7199
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes. I have a thread on TUI in the software development. We could make a new thread or use that one.
Logged


Central MN, USA
Offline Offline
Tesla Member
***
Karma: 73
Posts: 7199
Phi_prompt, phi_interfaces, phi-2 shields, phi-panels
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

16*2 is the basic display and my library is working on a 16*2 display. Some pretty features such as scroll bar and centering highlighted item won't show so well on 16*2 displays but all essential features are tested on my own phi-2 shield with 16*2 display smiley
Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 40
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi,

is was browing through the forum when stumbling about this thread.
I had the same issue as I was using the LCD library with both 16x4 and 20x4 displays quite a bit and did not want to make any display sepcific programming (other than the parameters to the lcd routines). So I modified the code of the LiquidCrystal library:

i) added a private uint8_t _numcolumns variable
ii) in lcd.begin() saved the column number into this variable (currently it is not passed by the begin, but not used at all)
iii) changed the LiquidCrystal.setCursor to the following code:

Code:
void myLiquidCrystal::setCursor(uint8_t col, uint8_t row)
{
  uint8_t row_offsets[4];
   
  row_offsets[0]=0x00;
  row_offsets[1]=0x40;
  row_offsets[2]=row_offsets[0]+_numcolumns;
  row_offsets[3]=row_offsets[1]+_numcolumns;

  if ( row > _numlines ) {
    row = _numlines-1;    // we count rows starting w/0
  }

  command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
}

this works for both 16x4 and 20x4 display types. Maybe incorporate this in the LiquidCrystal Library ?

best

s
Logged

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

This thread is over a year old - perhaps you should start a new one.

Quote
this works for both 16x4 and 20x4 display types. Maybe incorporate this in the LiquidCrystal Library ?

That would be a really good idea and a simple fix.  If you somehow catch a sympathetic ear then please try to get them to also change the default configuration (if you omit lcd.begin() statement) to the 16x2 configuration instead of the almost non-existent 16x1.

Don
« Last Edit: June 17, 2012, 02:56:47 pm by floresta » Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2712
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

If you somehow catch a sympathetic ear then please try to get them to also change the default configuration (if you omit lcd.begin() statement) to the 16x2 configuration instead of the almost non-existent 16x1.

Don

While this is primarily an issue for other LiquidCrystal compatible library's it is something
to be aware of.

A potential problem with omitting lcd.begin() is that not all the LiquidCrystal compatible librarys call begin() from
their init() function which is often called from the constructors.

Some constructors and init() functions merely initialize their private object variables and perhaps set up
some of the Arduino pins but don't actually initialize the LCD hardware. The actual LCD initialization is
done later, often in begin().

The issue that comes into play is that not all the Arduino facilities are available when C++ constructors are called
because constructors are called so early during the C/C++ runtime initialization.

Because of this it may not be possible to initialize the LCD hardware if it is using something
more complex than directly connected 4/8 bit mode.
(I2c, serial, or some other hardware that may depend on interrupts, delay() etc...).

Just something to keep in mind.

--- bill



Logged

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

Quote
A potential problem with omitting lcd.begin() ...

As far as I can decipher with my limited 'C' background the last line of the LiquidCrystal constructor invokes begin() with a default (16,1) configuration and that is how the LCD controller will be initialized.   If the sketch does not include an lcd.begin() statement then the LCD controller is left in that configuration but if such a statement is included then the LCD controller will be re-initialized for the new configuration. 

As you well know there are one or more LCD suppliers who still publish old example programs written before the LiquidCrystal library was updated (around v0017).  Those examples do not include an lcd.begin() statement and virtually anyone who uses one of those sketches with the current LiquidCrystal library will wind up with a configuration that does not display anything beyond the first row (or the first half of the first row on most 16x1 displays).

I can see no detriment to changing the default configuration from (16, 1) to (16, 2) and I can see no advantage in keeping the default configuration as it is.


Don
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2712
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I do agree with you that if there is going to be a default, that 16x1 seems like an odd
choice for a default given that 16x2 seems be a much more common display.


The need for begin() isn't for the LiquidCrystal library that ships
with Arduino but rather for other 3rd party LiquidCrystal compatible libraries, that may
need other Arduino services that are not available when the constructor is called.

There are also some inconsistencies out there with respect to the default use of "begin()".
Some call it for you, some don't and at least one uses a different geometry than 16x1
So unless the sketch always call begin(), it isn't for sure that it will work or what you will get when using
3rd party libraries.

Here are some examples:

fm's library does not call begin() from the constructor. begin() is common code for all the interfaces.
While the library could call it for the 4/8 bit interface (it probably should for maximum compatibility),
it currently doesn't call it from any of the constructors.

teensyduino's liquidcrystalFast library uses a 20x1 default

LiquidCrystal library for Ladyada's MCP32008 i2c/SPI board calls begin in the constructors for SPI/serial but not for I2c.

LiquidTWI (faster i2c replacement for Ladyada's board) does not call begin() from the constructor.

ShiftRegLCD123 does not call begin() from the constructors.



--- bill
Logged

Pages: 1 [2]   Go Up
Jump to: