Arduino with I2C LCD BTHQ 21605AV (with chipset pcf2119)

Hi,
I would like to use an i2C BTHQ21605V display from batron.
I have retrieved the library here Batron LCD sur I2C - Français - Arduino Forum

And I made the following changes:
In LCDI2C.h, I changed to #include "WConstants.h" by #include "arduino.h"
And in LCDI2C.cpp, I changed all the Wire.send by Wire.write.

But I still have a compilation problem.

Thank you in advance for your help

LCDI2C.zip (3.61 KB)

But I still have a compilation problem.

Which is?

Never mind. I see that you includes an error file in the zip file.

The header file contains:

  virtual void write(unsigned char ch);

But, the class derives from Print, which declares that write() is a virtual function (a class that derives from Print must implement it) that returns a size_t, not returns nothing.

Change the void to size_t, in the header file and in the source file. Add a return statement to the write() method to return the number of characters written.

Thank you PaulS, for your quick reply

I am sorry but I never do some Library :confused:

So, I modified the line 20 in LCDI2C.h: virtual size_t write (unsigned char ch);
but I did not understand the two parts of your modification :confused:

LCDI2C.h (714 Bytes)

That library you are working with is very wimpy and is very incomplete in terms of API functions and LiquidCrytal API compatibility.
I would suggest that you try my hd44780 library. It includes support for that type of display.
hd44780 provides full LiquidCrystal API compatibility as well as some additional features.
So you should be able to run most LCD code you find that was written for LiquidCrystal by simply changing the include and the constructor declaration.

You can install it using the IDE library manager and be up and running very quickly.
You can read more about it here: GitHub - duinoWitchery/hd44780: Extensible hd44780 LCD library

The i/o class for that display is hd44780_I2Clcd
There are several examples that show what needs to be included and the constructor.
The hd44780_I2Clcd i/o class does not yet auto locate the LCD i2c address and the included examples used an address of 0x3e which is different from your 0x3b address, so you will have to modify the i2c address for your display.

But other than that you should be able to be up and running in just a few minutes.
Install the code using the IDE library manager, go down to the examples under ioClass and go down to the hd44780_I2Clcd examples, to find the examples for that display.
Just remember to modify the i2c address to your i2c address and it should work.

let me know if you have any issues.

--- bill

Thank you Bill for this valuable advices
I'm going to try :wink:

The next version of the library that should be available in a day or so will include auto i2c address detection for the hd44780_I2Clcd i/o class so all the hd4780_I2Clcd examples should "just work" out of the box without having to alter the i2c address.
(code is already done and working)

--- bill

Hi,
Following the advice of bill, I tried to use the library and the example hd4780_I2Clcd
But this does not work as wanted. see picture 1 :frowning:

In order to flip the display, I have added the following lines:
Lcd.command (0x35);
Lcd.command (0x07);

1st problem: the lcd.begin () function does not work because the time is not displayed on the second line. see picture 2
I had to add the following line:
Lcd.command (0x34); // command: functions (2x16, basic set)

2nd problem: The display is wrong because the chipset used in the LCD is a PCF2119R
The library does not use the correct character table. see picture 3 and datasheet
In addition, the default character is not a space

Given the complexity of the library, someone could help me to modify this library but I will prefere editing my first library, It's easier for me and for the rest of my project.

Tank you in Advance

file.zip (272 KB)

While you are free to make any modifications you want to your own private copy as the code is open source, I would discourage that as you will then likely not be able to use future updates of the library without having to make modifications to your code.
(For example, the code you posted in the zip image is already behind the latest hd44780 release)
It would be better to help me to get the library updated to work with that display since I want the library to work with type of display as well.
(Although I think the font issue might be an issue that I may not want to solve - see below)

I guess in my earlier posts I should have been clearer by saying that the code should work with that display.
I don't have one of those to test with, and you are seeing the results of what happens when I can't actually test it. Normally I never release alpha code for this very reason. I don't like to give out code that doesn't work.

In terms of complexity the library architecture is actually not THAT complicated.
It uses virtual functions for the i/o classes but that allows the underlying code to be broken out into small layers that are very specific.

I would like to fix the library code to work correctly with that display.
I will need to get one of those devices to test with before the code will become bullet proof.

One thing that I did notice is that the pcf2119x chip designers totally screwed up the way they implemented their Function Set command. Their SL and M bits are bits 1 and 2 and they should have been bits 2 and 3 so that they would be compatible with the hd44780 F & N function set bits which are bits 2 and 3 and offer the same functionality.

That is why you needed to send the 0x34 command. Because they screwed up their hd44780 function set command. They use bit 2 instead of bit 3 to indicate a 2 line display.

IMO, what they did was unnecessary and VERY VERY stupid - seems like a rooky mistake on their part.
This will mean that there will always have to be something special done on this type of display, either in the library or in user code since in this particular aspect it deviates from the hd44780 interface.

I'll look at everything in more detail but this kind of sucks and I may have to create a hd44780_pcf2119x i/o class just to work around this to allow users to get that "it just works" experience.
It could be done using the 3rd parameter in begin() but I really don't like handling it that way as then it requires modifying actual sketch code when displays change and a major goal of this library is that device specific parameters are all in the constructor and not handled in application/sketch code.
It could also be handled by leaving the display in 1x32 mode but then altering the row offsets used by setCursor()
This is interesting because it would then also allow the to line to wrap to the 2nd line but again if there isn't a separate i/o class, the application has to do special things for this display - which is something that I REALLY want to avoid.

In terms of the font issue, this seems like another area where they REALLY screwed up.
The module appears come with one of 6 different fonts. A, D, F, I, R, S
The problem is that for fonts F, R, and S, they don't map the ASCII code points to ASCII character glyphs instead they move the ASCII code points up high. This is a very dumb thing to do.
Fonts A and I are good for ASCII, and D is usable with no lower case
but Fonts F, R and S are a disaster.

This one is not really workable in a generic way as ASCII pretty much won out about 40 years ago so pretty much everything assumes ASCII encoding at least for the lower 0x80 code points.
Yes there is UTF encoding which is used to support larger and varied fonts but supporting it is complex and simply isn't done very often as it requires using other data types than an 8 bit char and the the Arduino Print class doesn't and probably won't ever support it.
And even UTF assumes ASCII for the lower 0x80 code points.
I did some kludges in my openGLCD library to minimally support UTF but in reality it is not all that useful as all it does is allow simple UTF encoding for code points 0-255 which doesn't cover many/most of the fonts.

In this case the issue is that the sketch is sending ASCII codes but the font on the display module is not an ASCII font.
My recommendation would be get another display with one of the fonts that works with ASCII code points - Font A, D, or I with A or I being preferable.

If you insist on using a LCD module with on of the 'broken' fonts (F, R or S), then about the only easy thing that you could do is put a hack into the code to flip the upper and lower halves of the code points to move the near ASCII code points to the lower have of the code points.
But even that won't fix everything as there are some characters missing like: [ \ ] ^ { | } ~

And then there is the issue of how to handle the code points 0x0-0x0f and 0x80 to 0x8f
If you do a simple flip then the custom character code points would now be 0x80 to 0x8f.
You could do a simple additional check and only flip code points 0x10 to 0x7f and 0x90 to 0xff
That would keep the custom characters down low and preserver the code points 0x80 to 0x8f
Custom characters is going to be an issue.The reason being is that when a custom character is defined, normal writes is used. So it becomes a real issue of knowing when to do the code point bit flipping.
i.e. you want it flipped for sending character data but you don't want to mess with the data value when creating a custom code point. The issue is that the both look exactly the same to the i/o class.

Yes the hd44780 code could be updated track the additional state information and pass it down to the i/o class so that the i/o class can then know whether to do the code point flipping or to put the added code into the i/o class to figure out if a custom font is being defined, but that is not something I'm interested in doing & supporting.
IMO this is a case of the combination of a sketch sending ASCII code points and a LCD that does not support ASCII code points in its font and the library shouldn't have to solve this issue.

If you are willing to give up custom characters the changes are pretty minimal.
I'd recommend doing it in hd44780_I2Clcd rather than in hd44780 so that it won't break all the other devices.
It is only a single of code to do it using an exclusive or with 0x80 to flip the code upper/lower code points..

        if(type == hd44780::HD44780_IOdata)
        {
                ctlbyte = I2Clcd_RS; // control byte with RS and no continue
                value ^= 0x80; // flip the upper/lower code points
        }
        else
        {
                ctlbyte = 0; // control byte with no RS and no continue
        }

This will flip the two halves of the code points so 0x-0x7f are now 0x80-0xff and 0x80-0xff is now 0x00-0x7f which should place the ascii glyphs in the correct location.

If you do this kind of custom modifications to the library, I'd recommend using git & github so you can merge in future hd44780 library updates. i.e. fork the code into your own github repo, then locally clone it into your sketchbook area that way you can push/pull changes back and forth between your local development area and your github repo and you can merge in changes from hd44780 and even do pull requests back to hd44780 if you think the code changes you have made are generic enough for the library.

I'll think on this font issue some more, like maybe about having a way to properly handle flipping the upper and lower code points of a font while still allowing custom fonts to work. But so far this seems to be an issue for this one display and an issue that can't be fully resolved no matter what is done in the library.

--- bill

I just noticed another issue with the display which really shows how dumb their fonts are.
In looking at the photos you can see that the display attempts to clear the screen by writing ascii to the display, however the font does not have a blank character glyph in the 0x20 code point.

This means that the hd44780 clear display instruction doesn't work with those broken fonts.
This would require yet more changes to the library to support and work around this.

While all this can be worked around in s/w, IMO, this is a broken display and I'd recommend getting another display.

Whoever created fonts F, R, and S, clearly didn't know what they were doing.

--- bill

Great !!!
Here is the result :wink:
But I will follow your advice, to follow up my project, I will try to find a new LCD
Thank you so much for your help

Photo..JPG

Fabio95000:
Great !!!
Here is the result :wink:

Cool. So what did you end up doing?
Flipping the characters and re-doing the clear() code in hd44780?

But I will follow your advice, to follow up my project, I will try to find a new LCD
Thank you so much for your help

Unfortunately, the way that they did that display, it makes it tough to use any "standard" LCD software.

Hi Bill,
I did at the simplest, I modified your library hd44780_I2Clcd as you suggested it to me
And I did a subroutine in my app to replace the begin and clear functions
Thanks again for your help
Fabio

Bill,
I chose this LCD:

What do you think of this new LCD ?

The font seems ok. I'm not sure how the contrast works on that display.
If it requires that something be done to make it work, then you will have to modify hd44780_I2Clcd or create your own class by copying this one and making the tweaks in that one.
It might be better to create a new i/o class since that way, updates to hd44780 won't clobber your code.
You could add a iosetContrast() function to your i/o class so you can have constrast control from the sketch.
All you have to do to create your own class is copy the existing class to a new .h file and rename the class to match the name of the header file. If you want to be able to get hd44780 updates in the future, you will want to put it ins its own library directory. Just create a new directory in your skethes/libraries directory that matches the name of the class and put your new i/o library class header in that directory.
The IDE should find it after that and you will be able to update hd44780 in the future without clobber your custom i/o class header file.

--- bill

Bonjour,
j'ai également des difficultés à utiliser l'afficher BTHQ 21605AV. Avez vous trouvé une librairie compatible avec la dernière version d'Arduino.

Merci de votre aide.