I2C LCD and custom characters

Just got a cheap I2C 1602 LCD from Ebay.
Not too much trouble to get it going.
Used the I2C scanner sketch to check for the correct I2C address (confirmed 0x27)
Deleted the LiquidCrystal lib and replaced it with LiquidCrystal_V1.2.1.
Then finally had to include the pin definitions.

#include <LiquidCrystal_I2C.h>
#define I2C_ADDR    0x27  // Define I2C Address where the PCF8574A is
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
LiquidCrystal_I2C	lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin,BACKLIGHT_PIN,POSITIVE);

That did it.
Now playing around and having 2 questions related to defining custom characters.

Question #1:
Is it normal that during loading of the custom characters into the GCRAM of the display, these custom characters are kind of randomly thrown on the screen ?
I am specifically talking about the loading of the custom characters. (not displaying/using them, which works fine)

Question #2:
I have several different custom character sets that I need at different stages of my program.
I would like to use a function to upload the custom characters to the display and use a pointer to the particular array holding the characters for that set.
What is the proper syntax to use a 2 dimensional array in a function.

My custom character sets:

const uint8_t charBitmapRandom[][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 }   
};

const uint8_t charBitmapBattery[][8] = {
   { 31,  0,  0,  0,  0,  0,  0, 31 },          // 0 + top and bottom stripe
   { 31, 16, 16, 16, 16, 16, 16, 31 },          // 1 + top and bottom stripe
   { 31, 24, 24, 24, 24, 24, 24, 31 },          // 2 + top and bottom stripe
   { 31, 28, 28, 28, 28, 28, 28, 31 },          // 3 + top and bottom stripe
   { 31, 30, 30, 30, 30, 30, 30, 31 },          // 4 + top and bottom stripe
                                                // 5 = all dots on = char[255]
   {  1,  3,  3,  3,  3,  3,  3,  1 },          // Battery bottom
   { 16, 24, 30, 26, 26, 30, 24, 16 },          // Battery top   
};

const uint8_t charBitmapBatteryLargeOutline[][8] = {
   { 31, 31,  0,  0,  0,  0,  0,  0 },          // 0 + top stripe
   {  0,  0,  0,  0,  0,  0, 31, 31 },          // 0 + bottom stripe
   {  1,  3,  3,  3,  3,  3,  3,  3 },          // Battery bottom upper
   {  3,  3,  3,  3,  3,  3,  3,  1 },          // Battery bottom lower
   { 16, 24, 24, 24, 30, 31, 27, 27 },          // Battery top upper  
   { 27, 27, 31, 30, 24, 24, 24, 16 },          // Battery top lower  
};

const uint8_t charBitmapBatteryLarge[][8] = {
   { 31, 16, 16, 16, 16, 16, 16, 16 },          // 1 + top stripe
   { 31, 24, 24, 24, 24, 24, 24, 24 },          // 2 + top stripe
   { 31, 28, 28, 28, 28, 28, 28, 28 },          // 3 + top stripe
   { 31, 30, 30, 30, 30, 30, 30, 30 },          // 4 + top stripe
   { 16, 16, 16, 16, 16, 16, 16, 31 },          // 1 + bottom stripe
   { 24, 24, 24, 24, 24, 24, 24, 31 },          // 2 + bottom stripe
   { 28, 28, 28, 28, 28, 28, 28, 31 },          // 3 + bottom stripe
   { 30, 30, 30, 30, 30, 30, 30, 31 },          // 4 + bottom stripe
                                                // 5 = all dots on = char[255]
};

my function:

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

calling the function:

LoadCustomCharacterSet(charBitmapRandom);

If I use this function I get error message:
LCD_I2C_test_all_reduced:117: error: invalid conversion from ‘const uint8_t ()[8]’ to ‘uint8_t ()[8]’
Using this code in the loop, without going through the function, works fine.
Sorry, I am not good at pointers, references, casts, etc..

Thanks in advance for any help

Did you try googling arduino custom characters lcd ?

The first link on the search is this :

which shows this :

byte smiley[8] = {
  B00000,
  B10001,
  B00000,
  B00000,
  B10001,
  B01110,
  B00000,
};

void setup() {
  lcd.createChar(0, smiley);
  lcd.begin(16, 2);  
  lcd.write(byte(0));
}

I'm not much of a programmer so I can't comment on how you did it but the example above looks easier.
Secondly, before you start creating a bunch of custom characters you might want to just do a quick check
pages 185 & 186 of the Hitachi datasheet (see attached) and try one of those custom characters to see if they work for you.
For example , this one:

 byte degree = 0xDF;
lcd.write(degree);

prints the degree symbol after a temperature.

HD44780u.pdf (390 KB)

Dear raschemmel.
Thank you for your response.
I appreciate any input.

I have no trouble neither with finding the HD44780 standard character set, nor with defining any custom characters, nor with getting any of these characters on the screen.
Yes of course I reviewed the standard character set for symbols I could use.
And I found one I could use: Character 0xFF.

My questions were:
1: Is it common that the HD44780 (or compatible) puts the custom characters on the screen during the uploading process to the GCRAM ?
2: What is the proper syntax for calling a 2 dimensional array (e.g. the custom character array) in a function ?

I am missing how your response addresses either of my questions.

Kind regards
weersch

ok.

Question #1:
Is it normal that during loading of the custom characters into the GCRAM of the display, these custom characters are kind of randomly thrown on the screen ?
I am specifically talking about the loading of the custom characters. (not displaying/using them, which works fine)

I think you mean _CG_RAM...
Can you provide an example of this ? (photo or some other example )

What is the proper syntax to use a 2 dimensional array in a function.

Check Reply #1 on this post. I don't know if that is any help.
http://forum.arduino.cc/index.php/topic,41426.0.html
Sorry I can't be of any help...

1: Is it common that the HD44780 (or compatible) puts the custom characters on the screen during the uploading process to the GCRAM ?

Not to my knowledge.

Frequently when something 'wrong' happens the nature of the 'wrongness' may give insight into the source of the problem.

Do all of the custom characters that you upload also appear on the screen or only some of them?
Do the characters always appear at the same place on the screen or do they appear at different locations?
If they are at different locations is there any pattern to those?
You have to upload several bytes for each custom character, since you sat that the custom character appears on the screen is it correct to assume that this happens after the last byte is sent?

Don

The first thing I notice is that your arrays are not all the same size.
This means that you can't have a function that assumes a fixed size.
The way the code is now, the function is pushing out 8 custom characters
but yet not all the arrays have 8 custom characters.

The initializer:

const Ctype varname[][8] = {
{....},
....
{.....}
};

Will intialize a variable named "varname" with a variable number of entries
that each contain 8 elements of data of type Ctype and
they are all read-only constants (const).

So when you do something like:

const uint8_t charBitmapBatteryLargeOutline[][8] = {
   { 31, 31,  0,  0,  0,  0,  0,  0 },          // 0 + top stripe
   {  0,  0,  0,  0,  0,  0, 31, 31 },          // 0 + bottom stripe
   {  1,  3,  3,  3,  3,  3,  3,  3 },          // Battery bottom upper
   {  3,  3,  3,  3,  3,  3,  3,  1 },          // Battery bottom lower
   { 16, 24, 24, 24, 30, 31, 27, 27 },          // Battery top upper  
   { 27, 27, 31, 30, 24, 24, 24, 16 },          // Battery top lower  
};

You get 6 array elements, where each one of the 6 each has 8 const uint8_t values.
So if you have a function that assumes eight elements of 8 uint8_t values,
then you are walking off the end of the data and will be defining 2 extra custom characters with who knows what
data.
Maybe it doesn't matter, if you aren't using the extra characters on the end,
but it is best to avoid this kind of thing.

Maybe make them all the same size, or pass in the number of elements.

The error about invalid conversion is that
const uint8_t is not the same as uint8_t so you need to declare and cast them
all to be the same.

--- bill