EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

auto-detecting the resolution of HD44780-based LCD modules ?

Started by whygee November 11, 2009
Hello,

I have hooked alphanumerical LCDs on some uCs in the past and I have
always had to adjust the software to the actually installed module.
I have a small collection of "compatible" displays with 1 to 4 lines
and 8 to 40 char/line so the software could become messy.

In applications or situations where the LCD model is not pre-determined
(like, a customer intends to upgrade to another resolution in the future
or you don't know if the particular reference will be available later),
I have wondered what would make LCD-handling interfaces more flexible.

One solution is to add jumpers, or pads, or things like that, on the PCB.
This is not really practical because when changing the module, the
jumpers or pads must also be updated, which is error-inducing.
This also wastes precious pins...

I know that some recent LCD controlers have advanced features
but most of what I find today is cheap, standard, even old modules
so I rule out advanced protocols.


A particularly simple solution that I have just found is to solder some
SMD resistors (>100K) on the data bus, either to ground or Vdd.
These pull-ups or pull-downs provide a few bits that the host CPU or uC
can read when it does not drive the bus itself. So there is no
additional pin to reserve.

HD44780 displays are also often used in "reduced wiring" :
Write enable is tied to write and only 4 data bits are used.
This is compatible with the pull-up/down system, because in this
situation the LCD module never drives the data bus.

I remember that there may be other pull-up/downs, maybe on the LCD side,
but I can't be sure now, it could vary with the manufacturer or model...
Anyway, the resistors are mounted on the module and not the host PCB
so the value (could be 10K or less if needed) can be adjusted
without affecting the host board.


So we have 4 bits : I guess that the encoded values on the data bus
can be very easy :

bits 4 & 5 : number of char/line :
      0   0   8
      1   0   16
      0   1   20
      1   1   40 ?

bits 6 & 7 : number of lines
      0   0   1
      1   0   2
      0   1   4
      1   1   error ?

So during power-up, the host CPU/uC can hold the data bus in HiZ,
read the 4 bits of data and determine the dimensions.
The handling routines are then updated with correct values
(start addresses etc.).

More bits could be read by feeding the pull-ups with the backlight's
power, for example (don't forget the diodes to prevent messing with the values)
or simply with the lower nibble. But it is more important to know whether
the module has the pull-up/down resistors, so the dimensions could
fall back to 1x8 for example. If most modules have pull-ups,
then we could encode the dimensions in reverse order so
1111 means 1x8, and then there are only pull-downs to wire...


What do the readers think about this ? Is there something similar
in the wild ? Is it worth it to modify my modules to implement this
method ? Am I going to get annoying side effects ? (like different
addresses with different makers of modules)

YG

-- 
http://ygdes.com / http://yasep.org
whygee wrote:
> A particularly simple solution that I have just found is to solder some > SMD resistors (>100K) on the data bus, either to ground or Vdd. > These pull-ups or pull-downs provide a few bits that the host CPU or uC > can read when it does not drive the bus itself. So there is no > additional pin to reserve. > > HD44780 displays are also often used in "reduced wiring" : > Write enable is tied to write and only 4 data bits are used. > This is compatible with the pull-up/down system, because in this > situation the LCD module never drives the data bus. > > I remember that there may be other pull-up/downs, maybe on the LCD side, > but I can't be sure now, it could vary with the manufacturer or model... > Anyway, the resistors are mounted on the module and not the host PCB > so the value (could be 10K or less if needed) can be adjusted > without affecting the host board. > > So during power-up, the host CPU/uC can hold the data bus in HiZ, > read the 4 bits of data and determine the dimensions. > The handling routines are then updated with correct values > (start addresses etc.).
You haven't described *what* you are "reading". I.e., is this *the* data bus? Or, a port dedicated to the display? Or, something else?
> More bits could be read by feeding the pull-ups with the backlight's > power, for example (don't forget the diodes to prevent messing with the > values) > or simply with the lower nibble. But it is more important to know whether > the module has the pull-up/down resistors, so the dimensions could > fall back to 1x8 for example. If most modules have pull-ups, > then we could encode the dimensions in reverse order so > 1111 means 1x8, and then there are only pull-downs to wire... > > What do the readers think about this ? Is there something similar > in the wild ? Is it worth it to modify my modules to implement this > method ? Am I going to get annoying side effects ? (like different > addresses with different makers of modules)
If you are reading a port (or a buffer explicitly decoded) dedicated to the display, then you have some control over what else is on that bus. If you are just trying to read *the* data bus while (in theory) *nothing* is on the bus, then you are subject to whatever else happens to be *on* that bus (this is also true of the above case but presumably that is a more restricted portion of the design). You have to pick your pup/pdn values so that everything that might *want* to drive that portion of the bus can handle the added DC load. You also have to make sure the other things on the bus don't bias the bus unexpectedly. E.g., with lots of TTL on the bus, it will *tend* to float HI. (given enough time -- i.e., the speed of the bus needs to be taken into consideration). OTOH, if everything on the bus is *CMOS*, you might find that the bus just *stores* (capacitively) the last value driven onto it. (i.e., if the CPU writes a 0x37 and then tries to read an "undriven bus", it could read that 0x37 back! If the bus is also used to bring opcodes in from the program store, then it could just end up reading the last byte/value of the most recently fetched instruction... Bottom line: the bus isn't a DC device. Make sure you understand its AC characteristics as well as the DC impact of your proposed change. Can't you just burn a byte in your FLASH/ROM that represents the display being used and let your code interpret *that*?
Hello,
and thank you for the answer :-)

D Yuniskis wrote:
> whygee wrote: >> So during power-up, the host CPU/uC can hold the data bus in HiZ, >> read the 4 bits of data and determine the dimensions. >> The handling routines are then updated with correct values >> (start addresses etc.). > You haven't described *what* you are "reading". > I.e., is this *the* data bus? Or, a port dedicated > to the display? Or, something else?
I am speaking about a dedicated port. Very very often, the HD44780-like LCD modules are tied to the microcontroller with dedicated wires. The controllers are AFAIK made with very low power, and slow, silicon, so they are unsuitable for general purpose communications (the timings are too slow and could interfere with other faster devices). Eventually, when the CPU does not have dedicated I/Os, an external latch is used : look at the LCD tied to the parallel printer port as an example.
>> What do the readers think about this ? Is there something similar >> in the wild ? Is it worth it to modify my modules to implement this >> method ? Am I going to get annoying side effects ? (like different >> addresses with different makers of modules) > > If you are reading a port (or a buffer explicitly decoded) > dedicated to the display, then you have some control over > what else is on that bus.
yes, that's the point that was inherent and implicit in my original post.
> If you are just trying to read *the* data bus while (in > theory) *nothing* is on the bus, then you are subject to > whatever else happens to be *on* that bus.
Sure.
> You have to pick your pup/pdn values so that everything > that might *want* to drive that portion of the bus can handle > the added DC load. You also have to make sure the other > things on the bus don't bias the bus unexpectedly.
<snip>
> Bottom line: the bus isn't a DC device. Make sure you > understand its AC characteristics as well as the DC impact > of your proposed change.
Another post on Usenet pointed me to the fact that the LCD controller has 125uA pull-ups. I knew I missed a fact or two :-) This makes my system a bit more power-hungry. There is the LCD pull-up (equivalent to 40K), then eventually the configuration SMT resistor (about 10K or less) and then the CPU/microcontroller must provide more than 1mA to reverse the data again when needed. However, detection becomes easier because unmodified modules will read "1111" and can be handled with certainty. On top of that, the integrated pull-up make external pull-ups unnecessary and only pull-downs are needed.
> Can't you just burn a byte in your FLASH/ROM that represents > the display being used and let your code interpret *that*?
with a microcontroller, this amounts to reflashing the memory after a recompile, so I see no advantage for field upgrades. For example, a technician has to carry a computer with the programming tool, or even bring a new board with new firmware, just because the LCD module is upgraded :-/ Anyway thank you for the remarks, I just hoped that my idea was not completely stupid and it looks almost feasible (at least when power consumption is not an issue). YG -- http://ygdes.com / http://yasep.org
whygee wrote:
> D Yuniskis wrote: >> whygee wrote: > > I am speaking about a dedicated port. > > Very very often, the HD44780-like LCD modules are tied > to the microcontroller with dedicated wires. > The controllers are AFAIK made with very low power, > and slow, silicon, so they are unsuitable for > general purpose communications (the timings are > too slow and could interfere with other faster devices).
OK
>> You have to pick your pup/pdn values so that everything >> that might *want* to drive that portion of the bus can handle >> the added DC load. You also have to make sure the other >> things on the bus don't bias the bus unexpectedly. > <snip> >> Bottom line: the bus isn't a DC device. Make sure you >> understand its AC characteristics as well as the DC impact >> of your proposed change.
>
> Another post on Usenet pointed me to the fact that the > LCD controller has 125uA pull-ups. I knew I missed a fact or two :-) > > This makes my system a bit more power-hungry. > There is the LCD pull-up (equivalent to 40K), then > eventually the configuration SMT resistor (about 10K or less) > and then the CPU/microcontroller must provide more than 1mA > to reverse the data again when needed.
Usually sinking current isn't a problem. And, many "dedicated I/O ports" can also source a fair bit of power. Though this is still power that you need to supply (if you have a tight power budget).
> However, detection becomes easier because unmodified modules > will read "1111" and can be handled with certainty. On top of that, > the integrated pull-up make external pull-ups unnecessary > and only pull-downs are needed.
Presumably, the modules can't be "significantly" modified. I.e., tacking on a few resistors is relatively trivial (though SMT components may prove harder to find good mounting pads) but adding other (e.g., active) components would be out of the question (?) For example, could you add a small serial memory device that you could query? (i.e., think in terms of the way DIMMs are identified) More expensive than resistors but more versatile.
>> Can't you just burn a byte in your FLASH/ROM that represents >> the display being used and let your code interpret *that*? > with a microcontroller, this amounts to reflashing the memory > after a recompile, so I see no advantage for field upgrades. > For example, a technician has to carry a computer with > the programming tool, or even bring a new board with new > firmware, just because the LCD module is upgraded :-/
No. I am saying your firmware knows how to handle all of these modules (this must be the case for *your* scheme, too, since your firmware doesn't know what module will be attached). You can reserve one memory location that you reflash whenever the module is *changed* (to a different type) -- assuming you don't have any other nonvolatile memory to use. Can your microcontroller be reprogrammed "in system"?
> Anyway thank you for the remarks, > I just hoped that my idea was not completely stupid > and it looks almost feasible (at least when power > consumption is not an issue).
Hello,

D Yuniskis wrote:
> whygee wrote: >> Another post on Usenet pointed me to the fact that the >> LCD controller has 125uA pull-ups. I knew I missed a fact or two :-) >> >> This makes my system a bit more power-hungry. >> There is the LCD pull-up (equivalent to 40K), then >> eventually the configuration SMT resistor (about 10K or less) >> and then the CPU/microcontroller must provide more than 1mA >> to reverse the data again when needed. > > Usually sinking current isn't a problem. And, many > "dedicated I/O ports" can also source a fair bit of power. > Though this is still power that you need to > supply (if you have a tight power budget).
Indeed : I once had a design where I had to chase every useless mA. Pull-ups and such were consuming maybe half of the power. After that, the design was smaller and could use a cheaper/smaller LDO.
>> However, detection becomes easier because unmodified modules >> will read "1111" and can be handled with certainty. On top of that, >> the integrated pull-up make external pull-ups unnecessary >> and only pull-downs are needed. > > Presumably, the modules can't be "significantly" modified. > I.e., tacking on a few resistors is relatively trivial > (though SMT components may prove harder to find good > mounting pads)
that's the idea :-) but I've done crazy 3D circuits with 0603 parts lately so i'm not afraid ... http://ygdes.com/baguette/baguette_dcdc.jpg
> but adding other (e.g., active) components > would be out of the question (?)
well, more expensive, more complex... How can one be sure that an SPI/I2C part will not interfere with the LCD ?
> For example, could you add a small serial memory device > that you could query? (i.e., think in terms of the way DIMMs > are identified) More expensive than resistors but more > versatile.
I've also thought about hooking a 2-wire EEPROM on the LED backlight pin but i'm not sure it's such a good idea and it would add too much code to the CPU's application. It seems that the 4 bits provided by the pull-downs is enough, at least for my applications.
>> For example, a technician has to carry a computer with >> the programming tool, or even bring a new board with new >> firmware, just because the LCD module is upgraded :-/ > No. I am saying your firmware knows how to handle all > of these modules (this must be the case for *your* > scheme, too, since your firmware doesn't know what > module will be attached). You can reserve one memory > location that you reflash whenever the module is > *changed* (to a different type) -- assuming you don't > have any other nonvolatile memory to use.
or there could be a "configuration menu" that sets the handling routine at power-up. An internal EEPROM byte (think PIC) contains the type, that is changed through the menu before changing the LCD. So no programming/flashing device to carry. But if a clueless technician messes with the menu, the board is bricked :-/ So here comes the flashing device again, along with the portable PC...
> Can your microcontroller be reprogrammed "in system"?
most could but require a bulky laptop with external devices... Also the uCs are soldered so no possibility to unsocket and change the chip. anyway, it's going forward :-) I have also found a list of other resolutions with starting addresses at http://home.iae.nl/users/pouweha/lcd/lcd0.shtml so it looks that i'll need to use the full 15 valid combinations of 4 bits, instead of 4x3 combinations where some don't exist. regards, yg -- http://ygdes.com / http://yasep.org
hi !

Robert Roland wrote:
> On Fri, 13 Nov 2009 16:36:27 +0100, whygee <yg@yg.yg> wrote: >> But if a clueless technician messes with the menu, the board is bricked :-/ > > You could add an emergency combination, such as holding both buttons > while powering up, to get into a default 1x8 mode, which works on all > displays.
This "mode" is already used to get into the "menu" (plus a hardware key).
> You would have to implement the display configuration menu > in that limited 1x8 space, but I think that should be possible.
i've been too much spoilt by the width allowed by 1x16 displays ;-P
> A jumper could also be used to enter the config menu if that is more > suitable.
well it's another pin, and is is used by a standard key-enabled switch. It looks like soldering some SMT pull-down resistors is not so complex or stupid after all :-) Thanks, YG -- http://ygdes.com / http://yasep.org
On Fri, 13 Nov 2009 16:36:27 +0100, whygee <yg@yg.yg> wrote:

>or there could be a "configuration menu" that >sets the handling routine at power-up. An internal EEPROM byte >(think PIC) contains the type, that is changed through the menu >before changing the LCD. So no programming/flashing device >to carry. > >But if a clueless technician messes with the menu, the board is bricked :-/
You could add an emergency combination, such as holding both buttons while powering up, to get into a default 1x8 mode, which works on all displays. You would have to implement the display configuration menu in that limited 1x8 space, but I think that should be possible. A jumper could also be used to enter the config menu if that is more suitable. -- RoRo
Hello again,

I've written a draft (incomplete, preliminary etc.)
about this idea, available at
http://yasep.org/~whygee/RFCpulldownLCD.html

I have found a few tricks to reduce the power draw,
like tying the pull-down resistors to the RS pin
instead of Vss.

Comments are welcome,
YG
-- 
http://ygdes.com / http://yasep.org

The 2024 Embedded Online Conference