Go Down

Topic: New LiquidCrystal library - LCD library (Read 26 times) previous topic - next topic


As far as optimizations are concerned, I am not too concerned about a different digitalWrite coming into the scene, in the sense that people would have to rewrite parts of the SW.

Well, in some cases that re-writing has already been done.
There are already Arduino compatible s/w core libraries for the Maple and the Chipkit
which use 32 bit ARMs running at 60-80+mhz.
I have not looked at their digitalWrite() implementation but the processor is already
5-6 times faster. So even if they used the same crappy Arduino core code digitalWrite()
implementation, they would likely already be sub microsecond for digitalWrite() given
that the current digitalWrite() on a 16Mhz AVR is about 4us.

Paul's Teensy for example is AVR based but does not use the same core code.
It's implementation is much better and much faster that the stock Arduino core
- in some cases it can reduce to a single clock cycle for digitalWrite().
The Arduino team refuses to use it.

There is also the digitalwritefast project:
(not the way I'd do it, and not the way the Paul did it for Teensy) but it does
already exist today.

The method used in the dwf project gives you very fast i/o operations when all the constants
are known at compile time.  This method of optimization is quite simple and a little too simple minded.
While it works great for a sketch where all parameters can be known at compile time,
for a library that allows configuration of pins, this would be of no benefit since it would revert
back to the existing digitalWrite().

What really needs to be done is to throw out the current digitalWrite() implementation
and re-write how digitalWrite() works so it not only does the same things that
dwf  is doine  but also reduces the number of lookups since much
of the information being looked up *is* known at compile time.
And that is what Paul's teensy core code does.

If the Arduino team hadn't defined its interface using naked constants (i.e used #defines like DPIN_0 for digital 0 etc
instead of allowing naked constants like 0 or 1 etc)
many other things could be done to speed up the implementation even for pins that are not constants.

BTW, you are looking for additional support of your library, I'd bet you'd be greeted fairly well by
the chipKit and Maple guys as they are more open than Arduino and are also looking to beef up their
library support.

--- bill


Hi Bill,

just uploaded the last changes to the LCD library. I haven't released it as such, but uploaded the change set to the main repo. This is what will become V 1.1.3.

Main highlights:
- Configuration of I2C extender pin mapping (with a very low hit on performance - less than 0,8%).
- Configurable FAST_MODE, i.e. setting the control line pulse duration to be optimized or not.

I have also seen that the library, even without the FAST_MODE active is 2x more performant than the original LiquidCrystal.

If you are interested is in the regular place, but download it through the repo, i.e. (get source).

After a weeks testing I be releasing it.

I have also posted the library to the Maple team, see what they say/think.


Very cool. I've give it a try.
--- bill


Nov 07, 2011, 02:24 am Last Edit: Nov 07, 2011, 02:32 am by bperrybap Reason: 1
I have several questions on the backlight stuff.
It appears that your board uses I2C for the data and control lines but uses a dedicated pin for the backlight control.
Other boards use a pin off the i2c i/o expander to control the backlight.
I see some i2c backlight control code but it looks like it doesn't do anything yet.
It also looked like the i2c backlight masks in LiquidCrystal_I2C.h were assuming an active low signal
from the expander to the backlight would turn it on.
Is this is mid progress?
Is there a solder pad on your board to enable backlight control from the i2c output register instead
of having to use a dedicated pin? (yes no pwm but it saves an AVR pin since on/off controlcould be done through i2c)

The backlight control is challenging, since it looks like it can potentially be
done in multiple ways and can potentially be an active high or active low signal.
Michael and I punted on backlight control so far in the glcd library so I'm very interested
in seeing how this works out.

I think it would be really nice if the backlight control were a function in the base lcd class
so that it could work across all the interfaces rather than just the devices that add it in
as a user expansion.

The tricky part is how to configure it.
What makes it particularly difficult is all the combinations particularly on i2c.
Since the constructors must be able to distinguish between using an AVR pin and a bit
in the i/o expander.
For full flexibility the code also has to know whether the backlight control is active high or active low.
And then there is PWM control.

I'm not sure about the initialization but what about using an interface that is slightly different from
the display() nodisplay() interface for backlight control?
What about using  backlight(pwmvalue) as well as backlight() and nobacklight()
The interface can be used for pwm as well as non pwm.
That way people can turn it on and off and try to use pwm on all devices and those
devices that don't support pwm simply turn it on if the pwm value is non zero.
Just an idea....

The magic is figuring out how to configure the pin.
It seems pretty easy to handle the active low stuff.
One possibility is If the constructor is configured to take integers (int or int8_t vs uint8_t) then
you could use a negative value to represent negative logic (active low) signal
at least on the backlight pin.

I would think that when using 4 bit mode that the backlight pin (if specified) is always an Arduino pin.
The tricky part is how to select between an Arduino Pin and a i/o expander bit when i2c is used.
When using i2c I would think that the default would be that the backlight pin is an i2c expander bit
rather than a Arduino pin.

Maybe it could be handled with a macro so that the user simply specifies his intension in the constructor
and the macro ORs in some magic value to help determine which is which.


Code: [Select]

LiquidCrystal_I2C lcd(lcd_Addr, En, Rw, Rs, d0,  d1, d2, d3,  iobit);
LiquidCrystal_I2C lcd(lcd_Addr, En, Rw, Rs, d0,  d1, d2, d3,  BLARDUINO(arduino_blpin));
LiquidCrystal_I2C lcd(lcd_Addr, En, Rw, Rs, d0,  d1, d2, d3,  -iobit); // negative logic
LiquidCrystal_I2C lcd(lcd_Addr, En, Rw, Rs, d0,  d1, d2, d3,  -BLARDUINO(arduino_blpin)); // negative logic

LiquidCrystal lcd(12, 11, 5, 4, 3, 2, arduino_blpin);
LiquidCrystal lcd(12, 11, 5, 4, 3, 2, BLADRUINO(arduino_blpin)); // maybe either or both for consistency?

Where BLARDUINO() is something like (avoid using integer sign bit)
Code: [Select]
#define BLARDUINO(x) (x|_BV(14))

Maybe even specify the backlight pin type in all cases for consistency.

just a thought.

Another area that may need some attention is the RW line in i2c mode.
Some backpacks like the adafruit don't use the RW line.

--- bill


Hi Bill,

I need to give it a thought. For the I2C driver the intention was to have it in the constructor, considering it as an integral part of the LCD. However, only for those that are part of the backpack. This would be like a specialized method of that class.

Trying to control the backlight is a source of a lot of discussion, in the sense that: do you consider the backlight as part of the LCD or not? When you control them using a 4 bit interface, part of is it just another pin?

Anyway, I will go through your comments and give it a thought. I am sure that you chaps have given it a lot more thought than I have.

As per the RW I did give it a though, this being the main reason for not publishing the library as such. In the previous version you just defined the RW to 0x0 and bingo. Here, I need to overload the value so it is not used as a pin.

In any case, right now is not a big deal since in the library it is not used (only in the constructor) and would work.

Go Up