Hi have just published a library that is fully compatible with the current "LiquidCrystal" library that comes as standard with the Arduino SDK.

The main difference with the standard library is that it is supposed to be a generic and extendible library to control most LCD based on the Hitachi HD44780 (most alpha-numeric LCDs these days) using a wider range of "physical interfaces": 4 or 8 bit parallel, I2C, SPI, Serial.

The first version of the library supports the same functionality and interface as the "LiquidCrystal" library and with the very same interface and also allows you to control them via the I2C bus using an IO expander board. This means that you can control an LCD with just 2 Arduino pins as opposed to 7 or 11. You can even chain up to 8 LCDs on the same I2C bus should your application need it (using the I2CLCDextraIO board).

The New Liquid Crystal library is in fact a class hierarchy, where the base class is an abstract class "LiquidCrystal". Therefore, any project that you have developed is fully compatible with this library by just changing two lines of code (an include and the object creation - variable creation). The advantages:

It is a bit faster that the standard LiquidCrystal

Your projects can swap in and out LCDs that use an IO expander board, you are not constraint by library availability with different APIs.

The library is extendable, therefore it can grow to support new LCD control devices such as I2C, SPI, Serial, 1wire, RF, CAM, ...

Since the base class is abstract, anyone developing a MMI or user interface for their project, they can simply code the entire application with a reference to the class without constraining the users to have a particular LCD control mechanism. The type of LCD used is defined in the setup of the sketch.

The performance of the I2C driven interface is very good, you can even do animations with it.

The library is also compatible with the new release of the Arduino SKD 1.0-rc2 and will support the final release.

If you have run out of IO pins in your application, you can always use an I2C IO expander like the I2CLCDextraIO (image attached).

The library has been tested with several LCDs based on the Hitachi HD44780 and the I2CLCDextraIO board.

Hi Don,That's a very good point! I was thinking about changing the name and have the actual LiquidCristal lib port in the library still be the LiquidCrystal library. That way there would be 100% compatibility (even for constructors).

My general comment over there (summarized here) was that, IMHO,this library either needs to be able to coexist with the existing LiquidCrystal library (by having different names) or it shouldbe a drop in replacement so existing code does not have to be modified to use it.

sorry I didn't answer before. You have raised very fair points in your previous post, I will do a cut and past from the previous post to answer and keep in one place the library discussion.

Quote

What about using something like hd44780 instead of LiquidCrystal for the basename of everything?That way the library is totally separate and insulated from the LiquidCrystal library andcan even coexist, which makes it easier for users to add without breaking any otherexisting sketches they may have that currently use the LiquidCrystal library.

Yes, I think you have a fair point here. The basic idea was to create a drop-in replacement to the LiquidCrystal library. The problem is that the LiquidCrystal library was never thought out to be extendable. Therefore, the first thing I did was to virtualize some of the methods of the original library and create a sub-class to implement the access details. However, the class hierarchy looked very strange.

I can also see that people will not like to replace the current LCD library and when they compile find out that it doesn't. To be fair, I think that I will rename this library and try to create a "compatibility define".

Mind you, this is not an easy task, since to be fair, the LiquidCristal class would have to be the base class to all 4 bit objects and also to be used as a virtual class.

Quote

If the intent is to replace the LiquidCrystal library, then, IMHO, I think it is importantthat it be a drop in replacement and still allow existing LiquidCrystal sketchesto continue to compile without having to make any changes, even if it is as simpleas updating the constructor names in the sketch

I think that the easiest thing to do is:- Rename the base class to something <TBD>. I would appreciate all your help here. Something that is easy to remember and descriptive of what it does (I had "LCD" in mind).- Rename the current LiquidCrystal_4bit class to LiquidCrystal.

This would simply give you full compatibility with the current library and be able to use the extensions differently. In this case, the library would be a simple replacement without having to change a single line of code.

Quote

It would make it really easy to also add in support for using a shift register or a SPI interface:http://code.google.com/p/arduinoshiftreglcd/

I will download the library and give it a shot at porting it to this new structure. This would certainly enrich the port folio of the library.

Name required for the new library. HELP appreciated to its naming. The library (and base class should be easy to remember, descriptive of what it does).

I have ported the ShiftRegister LCD library to the <TBD> LCD library hierarchy. It has been a breeze to port it over as it just fitted nicely. Unfortunately, I haven't been able to test it - help on this front will be appreciated.

I will upload the library as soon as I get a name for it. Currently I am calling it "LCD".

sorry I didn't answer before. You have raised very fair points in your previous post, I will do a cut and past from the previous post to answer and keep in one place the library discussion.

I can also see that people will not like to replace the current LCD library and when they compile find out that it doesn't. To be fair, I think that I will rename this library and try to create a "compatibility define".

Mind you, this is not an easy task, since to be fair, the LiquidCristal class would have to be the base class to all 4 bit objects and also to be used as a virtual class.

Quote

If the intent is to replace the LiquidCrystal library, then, IMHO, I think it is importantthat it be a drop in replacement and still allow existing LiquidCrystal sketchesto continue to compile without having to make any changes, even if it is as simpleas updating the constructor names in the sketch

I think that the easiest thing to do is:- Rename the base class to something <TBD>. I would appreciate all your help here. Something that is easy to remember and descriptive of what it does (I had "LCD" in mind).- Rename the current LiquidCrystal_4bit class to LiquidCrystal.

This would simply give you full compatibility with the current library and be able to use the extensions differently. In this case, the library would be a simple replacement without having to change a single line of code.

I think I'd try to keep the separation and not rename anything LiquidCrystal.Not sure what the real answer is for a new name because even the name LCD may not be clear enoughI've seen people get confused and call both text and graphic devices a "LCD".(I'll use the name hd44780 in my examples below)

I think the key to providing backward compability.is how to transparently map the existing LiquidCrystal constructor name in their source codeto the new libraries constructor name.i.e. you don't necessarily have to actually rename the hd44780_4bit constructor to "LiquidCrystal".You just have to recognize that constructor name or transparently map it to your new name.After that, since all the API function namesin the new class match the old class it is all transparent.

So, I think you could have a a set of headers that all use something like hd44780 and thenhave a LiquidCrystal.h header file that might look like:

An alternate method might be to have a constructor named LiquidCrystal in the hd44780_4bit.cpp modulethat can be enabled with a special define.In that case the LiquidCrystal.h header would include the 2 hd44780 header files as aboveand turn on the special define to enable the LiquidCrystal named constructor.

I don't believe that it can be done using only a simple define in the new headersto turn on a 100% backward compatibility mode becauseto have full 100% backward compatibility, the header file LiquidCrystal.h has to exist because that is whatthe existing code that uses the LiquidCrystal library includes.And if a file called LiquidCrystal.h exists in this new library, then this new Library cannot co-exist with the current LiquidCrystal library as itwill confuse the IDE or worse the include path points to both directories and its not clear which LiquidCrystal.h headeris included. (the original one, or the one from this new library)It is a total catch-22.

I don't see that this issue can ever be resolved.There are essentially 2 choices- total replacement of existing LiquidCrystal library and have a new fully backward compatible library (which requires removing existing LiquidCrystal library)- A new library named something like hd44780 that lives side by side with LiquidCrystal

The 2nd case is probably easier to swallow for people. This also removes any backward compatibility issuesfor the new library as old/existing code continues to use the existing LiquidCrystal library and new applicationswill simply include the new hd44780.h and then the appropriate hd44780_xxx.h header for the particular hardware.Also, any existing application that is to be converted to using the new library will simply require a few small editsto get the includes and the constructor names set up correctly.

Another possibility might be still going with option #2 above but alsoto ship the new library with something like a dummy/masked LiquidCrystal.h backward compatibility header that is named something like LiquidCrystal.h.compat(to avoid any name collisions with the current LiquidCrystal library and hide it from the IDE)that contains the includes and mapping defines kind of like what was shown above. Then provide instructions to people that want use this new library as a full replacement for the existing LiquidCrystal library withhow to do that.(By simply renaming the LiquidCrystal.h.compat to LiquidCrystal.h and removing the current LiquidCrystal library.)

Just some ideas...

One big thing I noticed that I think is a real deal killer is that the library code currently only works with the Arduino 1.0pre-release code and does not work with the pre Arduino 1.0 environment.There are few places that need to check the value of ARDUINO < 100 and then include <wiring.h> ratherthan "Arduino.h> and then the write() function needs the same conditional and either return vode or a size_t

There is no simple way to have full compatibility without having to replace the LiquidCrystal library as such.

Adding defs to the Library will simply end up in a compiler/linker problem where symbols are multiply defined. This is how the Arduino compilation environment is. On a different environment it would be simpler in the sense that you would point your include and linker libraries to different locations.

In any case, what I am going to do is to have it a replacement library since as far as the 4bit and 8bit control are identical.

Regarding the arduino SDK version, it is just a question of time that all users will migrate to the new version. I don't like messing with compilation flags to make things compatible, but I can understand the need for it. So for the first versions of the library I will use conditional compilation flags to make the library compliant with the 22 version and the 1.0.

I was also thinking about doing a port of the SPI control library but at this point I think the package can go as is.

Regarding the arduino SDK version, it is just a question of time that all users will migrate to the new version. I don't like messing with compilation flags to make things compatible, but I can understand the need for it. So for the first versions of the library I will use conditional compilation flags to make the library compliant with the 22 version and the 1.0.

I'm glad to see the support for 0022 (I'm off to try it out on my 1602 display - will report back)

I do think the adoption rate of 1.0 is a great unknown.I would not underestimate the confusion and frustration that 1.0 is going to create, particularlygiven that it is going to break so much existing code. Think about this:- 100% of all the existing library code will not work with 1.0 until it is modified- 1.0 uses more RAM which will cause some sketches to no longer work (and they will fail in crazy ways since it will likely be stack overflows)- Some APIs have slightly changed (Print class being the most notable) which causes existing sketches to no longer work or compile.

I believe that some folks will simply choose to stay with 0022 instead or even revert back to it from 1.0,particularly if they as the start to find existing libraries or sketches that don't work with 1.0 or that thingssimply are not as stable under 1.0 as they were under 0022.

From a high level perspective, for all it breaks, it really doesn't offer much.A few IDE GUI changes and overlapped hardware serial output in some situationsat the cost of eating up extra ram, a few new events and timer control is about it.Yes it does allow some new things going forward but has a very high cost in terms ofbackward compatibility.

Adding to the future pain & confusion is that it has not been particularly easy to find the 1.0 beta & release candidates.To get the best feedback, it should have been prominently offered along side the latest (0022) release so thatpeople of all skill levels could be trying out the release and reporting feedback.As it is, I think that 1.0 is getting very little testing by the real end user target audience.As an example, I find it quite telling that the GLCD v3 library that I maintainhas been downloaded over 2000 times,and while I have added 1.0 support into that code, I have not released it yet and have notreceived a single request for 1.0 support.

So, IMHO, 1.0 will be a mess and create quite a bit of frustration for quite some time onceit is released.

I'm glad to see the support for 0022 (I'm off to try it out on my 1602 display - will report back)

Fantastic, thanks for trying it out. Sounds brilliant - unfortunately I was not able to run it with the 0022 version.

I think you have very fair point and agree with you that the version 1.0 is going to cause a lot more headaches than what it is trying to solve. Only time will tell.

You are more than right, finding or downloading version 1.0-RC2 is not an easy feat. For some reason it is not where the rest of the downloads for version 0022. You do need to go into the entire layout to find it. Not very practical for early adopters and start rolling it out around the community.

Nice to see that you are the maintainer of the GLCD Library. Great job there!

Initial testing is not good.BTW, I highly suggest you install a 0022 package for testing.0022 can coexist with the 1.0 packagesso that testing can be done on both as I believe that 0022 really needs to workand is going to be around for quite some time.

ARG!!!! backward compatibility for 2wrire stuff is also broken in 1.0!Why oh why didn't the arduino guys provide a wrapper function to map read() to receive()and write() to send(). Just another example of and how far reaching the 1.0 damage isand how messed up the 1.0 transition is going to be.These guys really need to have a "backward compatibility" mode (define) that can be setfrom the IDE to allow all the old sketches to continue to compile under 1.0 - I'm going to add this to the Arduino issues list.

Back to the new lcd library.

There are some issues with the 1.0 ifdefs on the 0022 side.Look at the declarations and code for write() in the LCD.h and LCD.cpp files:

Ok a few typos, those are easy to fix.Then there is the issue of using .ino for the sketch extensions.That doesn't work for 0022. .pde will work for both 0022 and 1.0Ok so thats an easy one to fix as well.

There is also the 2wire issues mentioned above for 0022.I tried to use ifdefs to replace write with send and read with receive but it wasn't enough.I got some strange undefined references:

undefined reference to `__cxa_pure_virtual'perhaps due to the function prototypes changing or perhaps a name collisionwith the Wire library send() function.

So I never was able to get it to link on 0022. (it did build, link and work on 1.0rc2)

You will see the errors/issues when you compile the code on 0022 after you fix the write/send read/receive issue.

Now for the Grand Daddy of all problems."As is" the new library modules will not compile on 0022 or 1.0 unless <Wire.h> is included by the userssketch. Existing code does not include this header so it breaks backward compatibility.

This is caused by the way the way the IDE handles its include paths.IMHO it is a HUGE issue that caused much heartburn during the ks0108/glcd librarydevelopment. In fact it still creates issues to this day.

Here is the issue. The IDE sets the compiler include path to the Arduino core directory plus it determines additional paths path based on the included files discovered/used in the sketch.The sketch is compiled using that include path.However, and here is the HUGE issue, when compiling the files for a library that the IDE detected the sketch needs,the IDE uses the same include path as the sketch plus it also adds any directories in the library that contain headers,to the include path when it compiles all the modules for the library.

This now creates some horrible issues. Like a library has no guaranteed way to include the header filesfor another library because the base level library directory is not part of the include path and theusers sketch may not include a header from that library.

So things like#include <Wire.h> won't work in a library unless the user sketch also includes <Wire.h> becausethe necessary path is not part of the include path unless the sketch includes it.Now you can sort of cheat and use "../Wire/Wire.h", because the library modules being compiledare all relative to base level library directory.However, this will not work if the user installs the libraryunder his personal libraries directory under his sketchbook because in that case the otherlibraries may not be relative to the library and may be over in the Arduino libraries directory wherever theIDE was installed.You can't use <../Wire/Wire.h> because it looks like gcc doesn't allow relative paths off directoriesin the include path.

The Arduino sketch building methodology simply falls apart when libraries need to be able to directly call other librariestransparently from the users sketch.

The real answer is to always add both base level library directories to the include path.That way you can do things like:#include <Wire/Wire.h> or #include <glcd/glcd.h> etc... It is very clean and it is the way it should have beendone from the beginning rather than this goofy method of adding all the include paths for just the libraries that are detected as being used.

But I think convincing the Arduino team to make any changes is difficult at best.

The HelloWorld.pde sketch with the old LiquidCrystal library on 0022 is 2522 bytes.

So switching from the current LiquidCrystal library on 0022 to 1.0 with the new cd librarycosts an extra 126 bytes of flash, and there is also some additional RAM requirements aswell since there are some new virtual functions.

thanks for the feedback. Very much appreciated. I will look into the 0022 issue. The problem is I work on a Mac and having two instances of the Arduino IDE is a bit of a pain since you have to install one and remove the other one. I will take a look and see what the problem is during linkage.

As for the Wire.h, every single sketch that uses the Wire library has to have the include in the sketch. It is a real pain. How did you sort this out in the GLCD? Relative includes?

Size, size. This is a pending subject. I haven't taken a closer look at the elf file, but I assume that some of the penalties are from having 2 classes more than just 1, additional constructors, a bit more code during initialization to make the library a bit faster.

As far as RAM, there are 2 new virtual methods, so the overhead is there, not much, but a bit.