lcd.print won't display my custom Characters Array ? multi-dimensinal battery

Hello I really don't understand why my array is not working ! So I realy need your help

I searched 5 times in Google and it's showing no good results :blush:
To share with you the pictures and video I use Drop-box Download it here : https://db.tt/ji1dOCWb
So let's go ! :

I would like to do this .
Click here to see 3 steps of the displayed battery (there are 9 in total) :

I have created a 2Dimmensionnal array (see my full code below) (aka matrix) and each row contain one state of a battery here is a schematic :

row [0] : "▯▢▢▷" // this row represents an empty AAA battery 
row [1] : "▮▩▢▷"
row [2] : "▮▩▩▷"
row [3] : "▮▩▩ ▶"  // this row represents an Full AAA battery    :open_mouth:

and each "â–©" character is a custom made character with this function :

lcd.createChar(0, customLcdfont_squareONE);

As you saw in my video it works at the end !
but it's absolutly not the way I want it to work !
the code that works is a mess ! a shame !

I think the problem is that the Raw n°1 ([0]) starts with a 0,
(try it out it's very strange), if we replace

"char batteryFonts [10][5]={

 { 0, 1, 1, 2 }, // you see { "0"<= this, 1, 1, 2 }, is a problem I think 
{ 3, 1, 1, 2 },
etc, 
etc,... 

 // this sentence behind does not work !!! but only with the raw [0]

 lcd.print( batteryFonts[0]);  

}

with

"char batteryFonts [10][5]={

 { 4, 1, 1, 2 }, // 4 or what ever you want 
etc, 
etc,... 


 // this sentence behind does  work !!! but only with a row that starts not with a 0 WHY ??? CAN U TELL ME ? please ? 

 lcd.print( batteryFonts[0]);  

}

It works ! it displays right ! :fearful:

Here is my full code get it and Just connect the pins 12, 13, 7, 4, 3, 2 to the LCD : and have a fun try :wink:

//This is a simple program that charges alkaline batteries 
//Copyleft
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 7, 4, 3, 2); // why pin 13 and not 12 ? because I love the led attached to it <3


// the empty battery - end 
byte customLcdfont_A [8] = { // B stand for "Binary" and then the pixel ... 
B01111,
B11000,
B10101,
B10100,
B10100,
B10100,
B11000,
B01111

// the empty battery body with fancy graphics enabled

};
byte customLcdfont_B [8] = { // B stand for "Binary" and then the pixel ... 
B11111,
B00000,
B11001,
B00000,
B000000000000000000,
B00000,
B00000,
B11111
};


// the empty battery + end

byte customLcdfont_C [8] = { // B stand for "Binary" and then the pixel ... 
B11100,
B00100,
B10111,
B00101, //Iloveyourmothersomutch
B00111,
B00111,
B00100,
B11100
};


// the full battery - end

byte customLcdfont_D [8] = { // B stand for "Binary" and then the pixel ... 
B1111,
B11111,
B10110,
B10111,
B10111,
B10111,
B11111,
B1111
};


// the FULL battery + end
byte customLcdfont_E [8] = { // B stand for "Binary" and then the pixel ... 
B11100,
B11100,
B01111,
B11101,
B11111,
B11111,
B11100,
B11100
};

// the full battery  body

byte customLcdfont_F [8] = {
B11111,
B11111,
B00110,
B11111,
B11111,
B11111,
B11111,
B11111
};

// the 1/3 battery body 

byte customLcdfont_G [8] = {
B11111,
B11000,
B00001,
B11000,
B11000,
B11000,
B11000,
B11111
};
// the 2/3 battery body 

byte customLcdfont_H [8] = {
B11111,
B11110,
B00111,
B11110,
B11110,
B11110,
B11110,
B11111
};



/**************************************************************************/
void setup() {
  int i = 0 ; 
  // initialize serial communications at 9600 bps:
  lcd.createChar(0, customLcdfont_A);
  lcd.createChar(1, customLcdfont_B);
  lcd.createChar(2, customLcdfont_C); 
  lcd.createChar(3, customLcdfont_D);
  lcd.createChar(4, customLcdfont_E);
  lcd.createChar(5, customLcdfont_F);
  lcd.createChar(6, customLcdfont_G);
  lcd.createChar(7, customLcdfont_H);

  lcd.begin(16, 2); 

// HELLO HERE IS THE PROBLEM !!!!

//the char table behin creates my diferent battery states as shown in the video ;) 

 char batteryFonts [10][5]={

 { 0, 1, 1, 2 }, // this is an empty one  f%*# this does not work !!!
 { 3, 1, 1, 2 },
 { 3, 6, 1, 2 },
 { 3, 7, 1, 2 },// this is a 50 % full charged battery ! 
 
 { 3, 5, 1, 2 },
 { 3, 5, 6, 2 },
 { 3, 5, 7, 2 }, 
 { 3, 5, 5, 2 },
 { 3, 5, 5, 4 },// this is nice full one  
 };
 


 // this sentence behind does not work !!! but only with the raw [0]

 lcd.print( batteryFonts[0]);    // I F***ing want this to display the first raw !!!! 
 lcd.setCursor(0,1 );

  lcd.print(" not working ");
 lcd.setCursor(0,0 );



  
        delay(9300); // this make a short pause  for us so that we can see the result
lcd.setCursor(0,1 );

  lcd.print("    working      ");
 lcd.setCursor(0,0 );
      for (i=0; i=10 ; i+=1 ){
       delay(300);

  lcd.setCursor(6,0 );

  lcd.write(byte(0));   lcd.write(byte(1)); lcd.write(byte(1)); lcd.write(byte(2));
    delay(700); //  batterry 0/8 empty aka discharged


  lcd.setCursor(6,0 );
  lcd.write(byte(3));   lcd.write(byte(1)); lcd.write(byte(1)); lcd.write(byte(2));
    delay(1000); //batterry 1 /8

  lcd.setCursor(6,0 );
  lcd.write(byte(3));   lcd.write(byte(6)); lcd.write(byte(1)); lcd.write(byte(2));
   delay(1000);//batterry 2 /8

  lcd.setCursor(6,0 );
   lcd.write(byte(3));   lcd.write(byte(7)); lcd.write(byte(1)); lcd.write(byte(2)); //batery 3 /8

  delay(1000);

  lcd.setCursor(6,0 );
   lcd.write(byte(3));   lcd.write(byte(5)); lcd.write(byte(1)); lcd.write(byte(2));
  delay(1000); //batery 4 /8

  lcd.setCursor(6,0 );
        lcd.write(byte(3));  lcd.write(byte(5));     lcd.write(byte(6));   lcd.write(byte(2));
  delay(1000); //batery 5 /8

  lcd.setCursor(6,0 );
      lcd.write(byte(3));  lcd.write(byte(5));   lcd.write(byte(7));  lcd.write(byte(2));
        delay(1000); //batery 6 /8

  lcd.setCursor(6,0 );
      lcd.write(byte(3));  lcd.write(byte(5));   lcd.write(byte(5));  lcd.write(byte(2));
      delay(1000); //batery 7 /8

  lcd.setCursor(6,0 );
    lcd.write(byte(3));  lcd.write(byte(5));     lcd.write(byte(5));    lcd.write(byte(4)); //batery 8 /8

    delay(1000); 

      }
 

    lcd.setCursor(15, 1);

    delay(115000);

}



/**************************************************************************/
void loop() {

//This is not interesting here 
  lcd.print(" ~ The end of the code ... thank you for reading ;) ~ ");

}

Good luck ! (you can try the code above it compiles :wink: ???

So it works, but the code is messy?
I've not used an LCD display yet, didn't have content to display, however these are my thoughts:

Doesn't this just print a single byte?

lcd.print( batteryFonts[0]); // I F***ing want this to display the first raw !!!!

If you want a row, you need to loop thru and send a whole row of bytes,
kinda of like you do in these statements:
lcd.setCursor(6,0 );
lcd.write(byte(3));
lcd.write(byte(5));
lcd.write(byte(5));
lcd.write(byte(4)); //batery 8 /8

This looks odd:

char batteryFonts [10][5]={ << array that is 10 x 5 - yet only 9 x 4 is defined below this:

{ 0, 1, 1, 2 }, // this is an empty one f%*# this does not work

And why does one element here have so many bits? 18? That's not a byte.

byte customLcdfont_B [8] = { // B stand for "Binary" and then the pixel ...
B11111,
B00000,
B11001,
B00000,
B000000000000000000,
B00000,
B00000,
B11111
};

I also think you would have more consistent results using this format for binary
0b00011111
0b00000000
0b00011001

as B11001 is just mapped to 0b00011001 in some other background file. Supposed to make it easier on beginners.
Yet we don't use
D5 or D05, or H5 or H05 to represent 0b00000101 for example.
Just 5, and 0x05. So use 0b00000101 to show where the 0s and 1s are.
Sytle perhaps - but also clarity.

First, thank you for replying :sweat_smile:

I've not used an LCD display yet

That's a shame, I hope you will be able to test if you can.

So it works, but the code is messy?

Answer : Yes the code can be executed by the Arduino Uno, but it does not produce the expected result -_-
(I made it also display on the LCD screen when it work's or when it don't work, so that you can easily see when is the problem 8) )

Doesn't this just print a single byte?
lcd.print( batteryFonts[0]);

Answer : No, because it is a 2D array as we can see in the declaration

char batterieFonts [10][5]={{row1},{row2},etc..};

It should print out the first raw,
not the element "0" but the row 0 ? right or false ? I think my problem is here...

And the strange thing is that I can print this row :
lcd.print( batterieFonts[1]);
But not the first raw :
lcd.print( batterieFonts[0]);

This looks odd:

char batteryFonts [10][5]={ << array that is 10 x 5 - yet only 9 x 4 is defined below this:

Answer : Yes you're right ! 5 element per raw : I did it like that so that I can insert the character '\0' at the end of each row but it seems to be useless, and why 10 instead of 9 ? uuh I absolutely don't know why I let it like this.
I forgot to change it ...sorry
I should change it for clarity and to save a bit of memory ::slight_smile:

And why does one element here have so many bits? 18? That's not a byte.

Yes absolutely you found anther mistake :smiley: ,anyway this one is not in my code it's just a typing error (How can I edit/change this in my post ? )

use 0b00000101 to show where the 0s and 1s are.

Oh, I didn't know that yes it's nice ! testing... yes it work's the same way.
It didn't change the behavior of my program so, thanks for that tip :wink:

As you said my post is not very clear, sorry for that, it's my first post around here :confused:
To bad I can't edit it ...

Try this.

//This is a simple program that charges alkaline batteries

//Copyleft
#include <LiquidCrystal.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 13, 7, 4, 3, 2); // why pin 13 and not 12 ? because I love the led attached to it <3


// the empty battery - end
byte customLcdfont_A [8] = { // B stand for "Binary" and then the pixel ...
  B01111,
  B11000,
  B10101,
  B10100,
  B10100,
  B10100,
  B11000,
  B01111

  // the empty battery body with fancy graphics enabled

};
byte customLcdfont_B [8] = { // B stand for "Binary" and then the pixel ...
  B11111,
  B00000,
  B11001,
  B00000,
  B00000,
  B00000,
  B00000,
  B11111
};


// the empty battery + end

byte customLcdfont_C [8] = { // B stand for "Binary" and then the pixel ...
  B11100,
  B00100,
  B10111,
  B00101, //Iloveyourmothersomutch
  B00111,
  B00111,
  B00100,
  B11100
};


// the full battery - end

byte customLcdfont_D [8] = { // B stand for "Binary" and then the pixel ...
  B1111,
  B11111,
  B10110,
  B10111,
  B10111,
  B10111,
  B11111,
  B1111
};


// the FULL battery + end
byte customLcdfont_E [8] = { // B stand for "Binary" and then the pixel ...
  B11100,
  B11100,
  B01111,
  B11101,
  B11111,
  B11111,
  B11100,
  B11100
};

// the full battery  body

byte customLcdfont_F [8] = {
  B11111,
  B11111,
  B00110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111
};

// the 1/3 battery body

byte customLcdfont_G [8] = {
  B11111,
  B11000,
  B00001,
  B11000,
  B11000,
  B11000,
  B11000,
  B11111
};
// the 2/3 battery body

byte customLcdfont_H [8] = {
  B11111,
  B11110,
  B00111,
  B11110,
  B11110,
  B11110,
  B11110,
  B11111
};

 char batteryFonts [10][4] = 
 {
    { 0, 1, 1, 2 }, // this is an empty one  f%*# this does not work !!!
    { 3, 1, 1, 2 },
    { 3, 6, 1, 2 },
    { 3, 7, 1, 2 },// this is a 50 % full charged battery !

    { 3, 5, 1, 2 },
    { 3, 5, 6, 2 },
    { 3, 5, 7, 2 },
    { 3, 5, 5, 2 },
    { 3, 5, 5, 4 },// this is nice full one
  };


/**************************************************************************/
void setup() 
{
  // initialize serial communications at 9600 bps:
  lcd.createChar(0, customLcdfont_A);
  lcd.createChar(1, customLcdfont_B);
  lcd.createChar(2, customLcdfont_C);
  lcd.createChar(3, customLcdfont_D);
  lcd.createChar(4, customLcdfont_E);
  lcd.createChar(5, customLcdfont_F);
  lcd.createChar(6, customLcdfont_G);
  lcd.createChar(7, customLcdfont_H);

  lcd.begin(16, 2);

  delay(9300); // this make a short pause  for us so that we can see the result
  lcd.setCursor(0, 1 );

  lcd.print("    working      ");
  lcd.setCursor(0, 0 );
  
  for (byte i = 0; i < 10; i++ ) 
  {
    delay(1000);
    Status(i, 1); // (state, row) 0 = empty, 
  }
}
/**************************************************************************/
void loop() 
{
  //This is not interesting here
  lcd.print(" ~ The end of the code ... thank you for reading ;) ~ ");
}

void Status(byte state, byte row)
{
  static byte lastState = 255;
  if (state != lastState)
  {
    lastState = state;
    for (byte i = 0; i < 4; i++)
    {
      lcd.write( batteryFonts[state][i]);    // I F***ing want this to display the first raw !!!!
      lcd.setCursor(i, row);
    }
  }
}

Try this

I tryed ! It's a nice code thank you so mutch :grinning:
But the problem is still there ...
Anyway you understood what kind of function I d'like to create and that's very good ^^
Video of What the code you sended me does

I'll test it on my LCD when I get home tonight and figure out what is wrong.

I love you ^^

I found the issue (Hard faceplam. :confused:)

void Status(byte state, byte row)
{
static byte lastState = 255;
if (state != lastState)
{
lastState = state;
for (byte i = 0; i < 4; i++)
{
lcd.write( batteryFonts[state]); // I F***ing want this to display the first raw !!!!
lcd.setCursor(i, row); <- this should be above lcd.write(...), not below it
}
}
}[/quote]
Fixed:
* *void Status(byte state, byte row) {  static byte lastState = 255;  if (state != lastState)  {    lastState = state;    for (byte i = 0; i < 4; i++)    {      lcd.setCursor(i, row);      lcd.write( batteryFonts[state][i]);    // I F***ing want this to display the first raw !!!!    }  } }* *
One other thing. your array batteryFonts, only has 9 elements, so the for loop in the setup() should be this.
* *for (byte i = 0; i < 9; i++ )  {    delay(1000);    Status(i, 1); // (state, row) 0 = empty,  }* *

You and me : :cry:

Thank you very much for this nice function !

I added an "x" to your "row" (y for me) coordinate so here it's how it look like now :

void DisplayBatteryStatus(byte state, byte x, byte y){
  static byte lastState = 255;

  if (state != lastState)  {  
lastState = state;

    for (byte i = 0; i < 4; i++){ 
      lcd.setCursor(i+x, y );
      lcd.write( batteryFonts[state][i]);    
    }
 }  
}

You coded this :

if (state != lastState){
lastState = state; 
etc...

in witch case do you find it usefull ? is it to avoid the screen blinking ?
Thanks !

in witch case do you find it usefull ? is it to avoid the screen blinking ?

Yes, it does prevent the screen from blinking.