Introducing the LiquidCrystal NKC Library!

Library looks really nice.

IMO, a good goal of creating a LCD library like this should be to make it as compatible as possible with other existing APIs, to try to make it as easy as possible to migrate existing sketch code to this library and hardware.
In the best case scenario, the user would only have to modify the header file includes and his lcd object constructor declaration/definition with no modifications necessary to the actual sketch code.
i.e. the goal should be to make things as easy and as simple as possible for user migrate existing sketch code and not have to do any device specific API functions to get the existing sketch code up and running.

With that in mind, here are a couple comments on the library API functions as I would recommend a few changes to get the functions to conform to the LCD 1.0 API as well as the LiquidCrystal API.
https://playground.arduino.cc/Code/LCDAPI/
Note: It is not possible to fully compatible with all the LCD API 1.0 functions and the LIquidCrystal functions as there are some incompatibilities like the parameter order in setCursor()

You can take a look at what I did for the hd44780 library here:

While there are many libraries out there that are non conformant particularly with how they implemented the setBacklight() function, this is how some of the the better and more popular libraries have implemented a few of these functions.

off()
Should turn everything off if possible, backlight and display pixels.

on()
Should turn everything back on, backlight and display pixels.

displayOff()
If possible turns off pixels but does not alter backlight.
Implemented this way conforms with the Arduino LiquidCrystal API since that API does not support backlight control.

displayOn()
If possible turns on pixels but does not alter backlght.
Implemented this way conforms with the Arduino LiquidCrystal API since that API does not support backlight control.

setBacklight(dimlevel)
This is often incorrectly implemented, including by entities such as AdaFruit,
PLEASE, PLEASE do not promote the use of setBacklight(HIGH) as that is an improper use of the setBacklight(dimlevel) API function and for libraries that implement this function properly and have dimmable backlights, it will result in a very dim backlight.
While you may see some implementations that check for zero/non-zero of the dimlevel parameter, they are doing that for h/w that does not support dimming and for h/w that does not support dimming, the backlight should be on for any non-zero dim level, but when dimming is supported, the parameter is a dim level.

As noted in the LCD API 1.0 spec, this function is supposed to set a dim level, if possible, not turn the backlight on/off based on non-zero or zero value.
If dimming is not supported, then 0 turns the backlight off, and any non-zero value turns the backlight on.

init() vs begin()
While the LCD API 1.0 used init() (and so did the very early LiquidCrystal API), the LiquidCrystal API now uses begin() rather than init() and that is what pretty much all the LCD libraries now use.
I would highly recommend adding a begin() function.
What the LiquidCrystal_I2C library did was to leave in the init() function but add a begin function. This works well as it makes it easy for users to migrate regardless of whether they are using older LiquidCrystal_I2C sketch code that used init() or newer code or LiquidCrystal code that uses begin()
In the hd44780 code i have a hidden/undocumented init() function for the hd44780_I2Cexp i/o class to allow easy migration of old code that used the LiquidCrystal_I2C library that used init() rather than begin()

backlight state after initialization.
This is a grey area, in that should it be on or off when initialization is complete?
It can be argued either way.
Some libraries have decided to leave it off, some have chosen to turn the backlight on during initialization so that the backlight is always on when the begin() function returns.
My reasoning for always turning on the backlight in begin() is so that existing sketch code written for the LiquidCrystal API which has no backlight control API functions will continue to work with no sketch changes.
If the backlight is off by default when begin() return, then sketch code written for LiquidCrystal will never turn on the backlight light unless modified since the LiquidCrystal API had no backlight support functions and the existing sketch would obviously never have called a backlight API function to turn it on.
IMO, turning it on makes it easier for less technical users to tell that something is working particularly when using inverted displays that show white text on dark backgrounds since when the backlight is off, it is just a dark/black display.

Here are what a few of the more popular libraries have done:
note: i wrote the backlight code for both newLiquidCrystal and hd44780

  • LiquidCrystal - there is no backlight support for this library.
  • fm's newLiquidCrystal - on after begin()
    when using newer backlight constructor.
  • hd44780 library - on after begin()
  • LiquidCrystal_I2C - explicitly turns it off in begin() / init()

--- bill

1 Like