A useless discussion about how a working sketch can't possibly work

sterretje:
Can you provide links to the libraries (old and new). I did have a look around and found https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads/.

Installed 1.3.5 from there and compiled the HelloWorld_i2c without errors in IDE 1.8.5 (Windows 8); plenty warnings about unused parameters though.

You have the link (same as in the readme file quoted above), only I am using 1.3.4. I have no errors of any sort during the compile or upload of the HelloWorld_I2C sketch to an Arduino UNO.

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define BACKLIGHT_PIN     13

LiquidCrystal_I2C lcd(0x38);  // Set the LCD I2C address

//LiquidCrystal_I2C lcd(0x38, BACKLIGHT_PIN, POSITIVE);  // Set the LCD I2C address


// Creat a set of new characters
const uint8_t charBitmap[][8] = {
   { 0xc, 0x12, 0x12, 0xc, 0, 0, 0, 0 },
   { 0x6, 0x9, 0x9, 0x6, 0, 0, 0, 0 },
   { 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0, 0x0 },
   { 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0, 0x0 },
   { 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0, 0x0 },
   { 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0, 0x0 },
   { 0x0, 0x0, 0x0, 0x6, 0x9, 0x9, 0x6, 0x0 },
   { 0x0, 0x0, 0x0, 0xc, 0x12, 0x12, 0xc, 0x0 }
   
};

void setup()
{
   int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));

  // Switch on the backlight
  pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );
  
  lcd.begin(16,2);               // initialize the lcd 

   for ( int i = 0; i < charBitmapSize; i++ )
   {
      lcd.createChar ( i, (uint8_t *)charBitmap[i] );
   }

  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" FORUM - fm   ");
  delay ( 1000 );
}

void loop()
{
   lcd.home ();
   // Do a little animation by writing to the same location
   for ( int i = 0; i < 2; i++ )
   {
      for ( int j = 0; j < 16; j++ )
      {
         lcd.print (char(random(7)));
      }
      lcd.setCursor ( 0, 1 );
   }
   delay (200);
}

From the output window (blank spaces included to show that it is the actual output):

Sketch uses 4114 bytes (12%) of program storage space. Maximum is 32256 bytes.
Global variables use 332 bytes (16%) of dynamic memory, leaving 1716 bytes for local variables. Maximum is 2048 bytes.

Follow Mr Groundfungus's advice. Install the hd44780 library. It will detect the I2C address and wiring style automatically.
Your customers will never have to worry about the make and model of I2C backpack.

For your own information. Run the diagnostic on each of your 12 LCD displays. Stick a label on each one with address and wiring style.

There are 16 possible addresses and two common wiring styles. That makes MANY ways to go wrong.

The common wiring styles are data bus on P0..P3 and data bus on P4..P7.
The backlight could be active-high or active-low. The control pins could be in a different order. You can see that the permutations get enormous.

The other advantage of hd44780 is that you have one set of class methods. All the other
LiquidCrystal_I2C classes have incompatible API. Your customers will not always install Malpartida's library. They just use the first one they find.

David.

david_prentice:
Your customers will never have to worry about the make and model of I2C backpack.

The other advantage of hd44780 is that you have one set of class methods. All the other
LiquidCrystal_I2C classes have incompatible API. Your customers will not always install Malpartida's library. They just use the first one they find.

The customers use the device as programmed. They do not program it. If they do, that is their issue. But I don't think any of them are in to this sort of thing.

david_prentice:
For your own information. Run the diagnostic on each of your 12 LCD displays. Stick a label on each one with address and wiring style.

I have. I have two versions, discernible by just looking at the backpack. As for the settings, I have them noted for each.

We are straying from the OP. I'm interested to know what library update caused fmalpartida NewCrystalLibrary to now require the full constructor.

NewCrystalLibrary to now require the full constructor.

If the I2C expander pin map is the default, there is a constuctor that requires only the I2C address of the I2C expander.

From LiquidCrystal_I2C.cpp:

 #define EN 6  // Enable bit

/*!
 @defined 
 @abstract   Read/Write bit of the LCD
 @discussion Defines the IO of the expander connected to the LCD Rw pin
 */
#define RW 5  // Read/Write bit

/*!
 @defined 
 @abstract   Register bit of the LCD
 @discussion Defines the IO of the expander connected to the LCD Register select pin
 */
#define RS 4  // Register select bit

/*!
 @defined 
 @abstract   LCD dataline allocation this library only supports 4 bit LCD control
 mode.
 @discussion D4, D5, D6, D7 LCD data lines pin mapping of the extender module
 */
#define D4 0
#define D5 1
#define D6 2
#define D7 3


// CONSTRUCTORS
// ---------------------------------------------------------------------------
LiquidCrystal_I2C::LiquidCrystal_I2C( uint8_t lcd_Addr )
{
   config(lcd_Addr, EN, RW, RS, D4, D5, D6, D7);
}

groundFungus:
If the I2C expander pin map is the default, there is a constuctor that requires only the I2C address of the I2C expander.

I know because it used to work. But the displays I had on hand and worked previous with just the address in the constructor now require the full constructor. So are there any ideas on what may have happened to now require the full constructor to be specified where previously just the address worked?

Go on. The short form of constructor defaults to EN=6, RW=5, RS=4, D4=0, D5=1, D6=2, D7=3, BL=7

This will be equivalent to

LiquidCrystal_I2C lcd(0x27);
LiquidCrystal_I2C lcd(0x27, 6, 5, 4, 0, 1, 2, 3, 7, POSITIVE);

If you have the other style of adapter you must use the full-fat constructor:

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

Since you own 12 different backpacks, you can use the appropriate constructor.

It has always surprised me that the default is D4=0, D5=1, D6=2, D7=3 because in my experience P4..P7 is more common.

David.

david_prentice:
Since you own 12 different backpacks, you can use the appropriate constructor.

I have 2 different backpacks, and many of each.

But that isn't explaining why the full constructor is now required when prior to the library updates it was not.

I give up. Both I and GroundFungus have explained it very clearly.

david_prentice:
I give up. Both I and GroundFungus have explained it very clearly.

I'm sorry I must not be seeing the answer. I see lot's of really good information, but not the answer. Can you give me a hint as to which post explains why the full constructor is now required when prior to the library updates it was not?

(stating to use a different library instead of a library that had been used and working for years, is not an explanation for why the sketch no longer works after having updated other libraries)

OK, no more about the much better library.

The logical explanation, from what I see, is that the older library that you were using had the defaults in the .cpp file to match your old displays. The new version has different defaults. How did you do the update? Through Library Manager or download the library and manual install? Do you still have the old library and can check the default pin map to see if it is different?

I had the following libraries in the 'mysketches'->libraries directory:

The proper path for the library folder should be \Documents\Arduino\libraries. Is that what you mean?

groundFungus:
The proper path for the library folder should be \Documents\Arduino\libraries. Is that what you mean?

Yes, more or less (basically, depending on the OS and drive layout but that another topic). That is to say not in the Program Files\Arduino\libraries directory.

groundFungus:
OK, no more about the much better library.

I'll get back to that, especially if i have to change all my sketches. Then I might as well also change the library being used.

groundFungus:
How did you do the update? Through Library Manager or download the library and manual install?

It was updated through the 'Add a .ZIP Library...' option. The defaults look the same between the new and old. I wish I could tell what the old version number is. I don't see the version number documented anywhere.

Well, that was my best shot. I can see no other explanation.

groundFungus:
Well, that was my best shot. I can see no other explanation.

I ran out of ideas myself, hence the thread. I'm hoping fmalpartida is still around and will chime in.

I have one thing to try, but I am not optimistic (and can't try until I'm at home with my stuff) as I think it only applies to the parallel displays (as I recall there is some sort of name conflict with the Arduino IDE and fmalpartida's library).

I had a look at the file that contains the LiquidCrystal_I2C constructors; there does not seem to be a difference between 1.2.1 (not even called NewLiquidCrystal), 1.3.1 and 1.3.4.

Checked with WinMerge.

adwsystems:
Please feel free to explain how it works.

Challenge Accepted....

Ok, while I'm not fm, I did collaborate and write several sections of that library and a few of the i/o classes.
And helped support it for a few years.
I'm the closest thing you will get to fm.
Here is the deal. fm has a company called ElectroFun that made a product called LCDXIO.
Here is a post about it: NewLiquidCrystal library with I2C LCD - #2 by bperrybap - Displays - Arduino Forum
I have one - that fm sent me, but it isn't made anymore. Here is a page from the wayback machine so you can see it:
https://web.archive.org/web/20120119082309/http://www.electrofunltd.com:80/p/i2c-lcd-extra-io.html
It was kind of a funky product in that it was kind of a backpack and could be used that way, but the PCB didn't work that well when used as a backpack do to the offset of the holes.
I'm the one that added backlight control to the LiquidCrystal_I2C class as the early code didn't have it since LCDXIO didn't support it.

When a full constructor is not specified, as in only specifying the i2c address, the library uses a default set of parameters, for the pin mappings.
The default pin mapping used by the newLiquidCrystal LiquidCrystal_I2C class uses a pin mapping for that LCDXIO device.

I have tried to find and test as many different types of i2c lcd backapacks as I can find over the years and I have
never seen any other PCF8574 based lcd backpack use this pin mapping in the several years (6+) that I've been playing with and writing code for i2c lcd backpacks.

I also spent some time going through the git history of fm's bitbucket repository to see if the default pin mapping has ever been changed. I didn't see any version of code that used a different default pin mapping than what is being used in the latest version of the LiquidCrystal_I2C code.
The latest LiquidCrystal_I2C code was updated 2016-11-25
The earliest LiquidCrystal_I2C code was from 2011-10-25
While the location of the default pin mappings has changed around a bit over the years from the .h to the .cpp
and the original code didn't even allow changing the pin mappings of the data lines from D4=0, D5=1, D6=2, D7=3,
I did not see any case of the default pin mappings being anything other than
EN=6, RW=5, RS=4, D4=0, D5=1, D6=2, D7=3

So I don't see how you could have ever used a newLiquidCrystal library obtained from fm's bitbucket repo and used the default pin mappings and had it work, since you said you needed this constructor to make it work:
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

If you actually have the older library code that you were using, you should be able to instantly tell what changed between what used to work and what you have now.
Just run a diff or use meld so you can see the differences it will be obvious.
If you cloned the git repository of the working "older" library to your system you could also use git to show you if there were any local modifications to the files.

My guess is that if the library code you were previously using worked with a constructor that was only provided an i2c address, it either didn't come from fm's newLiquidCrystal repo or was modified to use a different default pin mapping as I cannot find any evidence that the default pin mappings in the library code from fm's repository ever used the pin mappings that you have said are required for your device.


Given you seem to be using this code on a commercial product there are some things that you need to be aware of.
When using newLiquidCrystal, you need to be aware that it has licensing issues and copyright violations and legally cannot be used in any type of commercial product.

fm is aware of this (and now you are too).
fm has promised to address it for quite some time, but so far has not.
I can send you full details on this but here are the highlights:

  • The overall license fm picked is CC-BY-SA 3.0
    That license is not compatible with anything but itself. It cannot legally be linked with any GPL or LGPL code.
    It is not an appropriate license for s/w and was really intended for things like documents or other components
    that are not integrated into something larger.

  • The overall license for newLiquidCrystal cannot be CC-BY-SA 3.0
    The original code that the newLiqiudCrystal library started with was licensed as LGPL 2.0+ as such, it cannot ever be relicensed with anything but a LGPL or GPL license. To do so, as was done in this case, is a copyright violation.

  • The library ships with some GPL 3 components.
    GPL v3 is not compatible with CC-BY-SA and as such it violates both CC-BY-SA and GPL.

  • Some of the modules have had their licensing agreements changed from their original GPL licenses to other licenses
    which is a violation of the licensing terms.

The only resolution is to relicense the newLiquidCrystal library code as either LGPL 2.0+
or as GPL v3. If the code is relicensed as LGPL 2.0+ then some of the modules must be removed as they are LGPL 3.0 and you can't relicense them LGPL.
Regardless of the licensing correction, the various authors have to agree.
fm decided to move to GPL v3 and I agreed, but so far fm has not contacted the others and has made no effort to correct the licensing and copyright issues.
He did say if it becomes a big issue, he would simply remove/delete the library.

So for now that library is hopeless broken in terms of licensing/copyrights and should not be used, especially in a commercial product.

This kind of stuff is particularly important in your case as you are shipping a commercial product.
I would avoid using it.

Seems like a lot of your issues could be resolved if you switched to using hd44780.
Just keep in mind that hd44780 is LGPL v3 so your product code must be fully open source licensed as GPL 3.0
But even if using some other LCD library to avoid any GPL 3.0 licensing issues, if you use Arduino, you will still be bound by the LGPL 2.0 licensing requirements and with current Arduino development tools, it isn't possible to have closed source and satisfy all the LGPL 2.0 licensing requirements.

Given the way the Arduino IDE works, it is not possible to use Arduino for closed products since even LGPL 2.0 requires that a user be able to replace/update the LGPL open source components and currently there is no way to use the Arduino provided tools to build a project and upload a device and keep part of the code closed source to the customer.
i.e. there is no way to keep certain parts of the product closed source and grant the customer all the rights he is entitled to when using LGPL or GPL code in an Arduino based s/w product.

--- bill

I am intrigued by Malpartida choice of default wiring.

There are two convenient ways of mounting the PCD574 on a pcb.

Most Ebay backpacks have the PCF8574 mounted vertically. Data bus is on P4..P7

The only one I can find with a horizontally mounted PCF8574 is this one
The databus is probably on P0..P3 like Malpartida default.

I can't find a sale item. But backpacks marked "Arduino-IIC-LCD GY-LCD-V1" have a horizontal PCF8574 with data bus on P0..P3.

So yes, horizontal PCF exist but are not very common.

David.

David,
if you look at fm's ElectroFun board (in the wayback link), it uses a SSOP20 not a SO16.
The SSOP20 chip version of the PCF8574 has a very different pin layout. I have no clue why.

The two boards I've seen that use P4-P7 for DB4-DB7 are the mjkdz like you showed and the one labeled GY-I2CLCD.
Both use the same pin mappings and same active level backlight control.

But even all boards that use P0-P3 for DB4 to DB7 are not all the same.
While most use active high level backlight control, the one called "Robot Arduino LCM1602 backpack" uses active low backlight control. That particular backpack will also force the backlight to be always on when the jumper is installed whereas on most backpacks, removing the jumper disables the backlight control and turns off the backlight.

You can look in the hd44780 library hd44780_I2Cexp.h header file to see all the backpacks that I've encountered (and actually have tested with) and the ones the hd44780 self configure code will identify.

The one odd ball is the SYDZ board which has an incorrect backlight design. They hooked up their transistor incorrectly, so it breaks the auto detection s/w used to detect the active backlight level. It also has really nice switches for setting the I2C address but the switches are on the side of the backpack PCB that faces the LCD. So if you solder it to the LCD, you can't access the switches to alter the i2c address. For those reasons I do not recommend it,

Essential, there are 3 pin mappings and two active levels for backlight control that are being used in commercial products.
I can't really speak as to the actual popularity of any of them other than the pin mapping used on the LCDXIO board is not used on any other backpack that I have so far seen.

--- bill

Given from what I can see in fm's bitbucket repository commit history for newLiquidCrystal,
the default pin mapping used in the LiquidCrystal_I2C class has never changed.

Also, no changes or updates to the IDE would alter this.

The only way a newLiquidCrystal library from fm's bitbucket site could work with the stated backpack,
is if it had been modified.

So my conclusion is that the code that previously worked with the stated h/w had been modified.
It either cam from a different source that fm's bitbucket site (where it had been modified), or it was modified locally.
And then when the library was updated, these modifications to the default pin mappings were lost.

--- bill

My final thoughts are though I had fmalpartida's library installed, it was only being used in part (or possibly not at all but then I'm not sure how the LCDs were working). The library updates "corrected" this and forced the fmalpartida's library to be used in whole thus breaking my sketches.

To use fmalpartida's NewLiquidCrystal library, there is a manual manipulation that must be performed to the Arduino IDE install libraries. (Arduino installed liquid crystal must be removed)

I present:

bperrybap:
This thread is a duplicate of the discussion in this thread:
http://arduino.cc/forum/index.php/topic,76041.0.html
My comment is in the other thread.

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 should be a drop in replacement so existing code does not have to be modified to use it.

--- bill

In short I think my sketches got broke because because something in the libraries got fixed during the update process. (here I was thinking I was smart because I updated my libraries before I started on a new project. well foo on me)

It isn't possible to use just part of fm's newLiquidCrystal library. It has many dependencies on classes that only exist in that library.
If you had a messed up installation and were only grabbing part of it, you would get compilation errors.

While there are many libraries that have a LiquidCrystal_I2C class, I've only seen one that had a constructor that would take a single parameter of an i2c addresses and that is fm's LiquidCrystal, but that library has always used a default pin mapping that would not work with your h/w.

I suspect that at some point you modified the default parameters in your local version of newLiquidCrystal LiquidCrystal_I2C to match your hardware.
The re-installation, or an update of the library would clobber those local modifications.

But since you have said you have the earlier working library and know where you got if from, then just look at it and tell us which library the old one that worked is and how it differs from the library you just installed.
Just run a diff or a meld between the two libraries and show us all the differences.
Or post a zip of it, so we can see it.
That would settle it.

I'm still betting that you modified the newLiquidCrystal library files to match your hardware and must have forgotten about doing it. That would explain everything you have told us.

BTW,
That post of mine from 6.5 years ago about fm's newLiquidCrystal library , was when fm was getting started on newLiquidCrystal. It doesn't have anything to do with this.
It was a comment on design/architecture of that library. Things back then were very different on Arduino than they are now as there was no library manager, no way to have the IDE install a library from a zip and no automated IDE library manager that automatically pulls libraries from the cloud. Everything was manual back then. My comment was that that there are two ways to go, either as a separate/different name or as a replacement that includes a LiquidCrystal class that can be used with no changes to existing code that uses LiquidCrystal.
fm chose the latter, which was nice at the time, but it now means that it can never use the automated IDE library manager since the library manager does not allow multiple libraries with the same name and for sure will never allow a 3rd party library to override their IDE bundled library.

--- bill