2x16 char LCD display with I2C, no reaction

Hi

Complete Arduino noob here, although I have some programming experience. I'm trying to connect a 2x16 character LCD display to my Arduino board, both given to me by a friend, so I'm not entirely sure what exactly they are. Here's a couple of photos of the setup:

I'm able to upload basic examples to the Arduino; e.g. I get the blinking LED example to work fine. But when it comes to the LCD screen I'm not really getting there.

So, I figured out that the display is a bit different from most others of its kind, in that it has another board soldered to it (an I2C board, please correct me if I'm wrong), so that it has only four pins. As far as I can read in various websites this means that the standard LCD library won't cut it, so I installed fmalpartida's LiquidCrystal library because that seems to support a wide range of boards, and removed the default LiquidCrystal library from /usr/share/arduino/libraries/ (I'm on Ubuntu). This gave me a new examples folder and removed the old one in the Arduino IDE, so that seems to work.

I'm able to Verify/Compile and Upload the various examples following the lib, and I guess the HelloWorld_i2c is the relevant one here:

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>



#define BACKLIGHT_PIN     13

LiquidCrystal_I2C lcd(0x38);  // Set the LCD I2C address

//LiquidCrystal_I2C lcd(0x38, BACKLIGHT_PIN, POSITIVE);  // Set the LCD I2C address


// Creat a set of new characters
const uint8_t charBitmap[][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 }
   
};

void setup()
{
   int charBitmapSize = (sizeof(charBitmap ) / sizeof (charBitmap[0]));

  // Switch on the backlight
  pinMode ( BACKLIGHT_PIN, OUTPUT );
  digitalWrite ( BACKLIGHT_PIN, HIGH );
  
  lcd.begin(16,2);               // initialize the lcd 

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

  lcd.home ();                   // go home
  lcd.print("Hello, ARDUINO ");  
  lcd.setCursor ( 0, 1 );        // go to the next line
  lcd.print (" FORUM - fm   ");
  delay ( 1000 );
}

void loop()
{
   lcd.home ();
   // Do a little animation by writing to the same location
   for ( int i = 0; i < 2; i++ )
   {
      for ( int j = 0; j < 16; j++ )
      {
         lcd.print (char(random(7)));
      }
      lcd.setCursor ( 0, 1 );
   }
   delay (200);
}

The display doesn't react at all, though. It has its backlight on, but it seems to have that all the time. I have two major points that I think may cause this, or it may be something else:

  • The I2C address. I've tried with the default value of 0x38, and some others that I tried Googling for this board: 0x20, 0x27
  • The pins I use to connect on the Arduino board: Currently I have SDA -> digital pin 2 and SCL -> digital pin 3. I have no idea if this is even remotely correct and if not, which ones to use instead. Also I would have expected the code example to include some kind of definition of these pins, but it doesn't seem to.
  • Something completely different, or a mix of the above.

Any ideas?

You are using the wrong descriptor - you need to study fmalpartida's codebase, not the crude tutorials.

Run the I2Cguesser to get the descriptor. Then find some proper code.

Test code - when you substitute the value from the "guesser":

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define lcdAddr 0x20 // set the address of the I2C device the LCD is connected to

// create an lcd instance with correct constructor for how the lcd is wired
//  to the I2C chip.  In this case, the www.mjkdz.com module
LiquidCrystal_I2C lcd(lcdAddr, 4, 5, 6, 0, 1, 2, 3, 7, NEGATIVE); // addr, EN, RW, RS, D4, D5, D6, D7, Backlight, POLARITY


int f=4;                  //set frames per second (fps)
int s;

// the following frams of the 8-bit Mario are made from a orginal 8-bit Mario as reference
// left number is the frame right number is the position (mario xy)
// (1 = top left 2 = bottem left 3 = top right 4 = bottom right)

byte mario11[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00001,
 B00001,
 B00001,
 B00000,

};
byte mario12[8] = {
 B00001,
 B00001,
 B00001,
 B00001,
 B00000,
 B00000,
 B00000,
 B00000
};
byte mario13[8] = {
  B00000,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,

};
byte mario14[8] = {
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11110
};

byte mario15[8] = {
   B00000,
 B00000,
 B11000,
 B00000,
 B11000,
 B11100,
 B11000,
 B10000,

};

byte mario16[8] = {
 B00000,
 B10000,
 B10000,
 B10000,
 B00000,
 B00000,
 B10000,
 B00000
};

byte mario21[8] = {
   B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
};

byte mario22[8] = {
 B00111,
 B00111,
 B00111,
 B00000,
 B00001,
 B00011,
 B00011,
 B00001
};

byte mario23[8] = {
   B00000,
 B01111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B01111,

};

byte mario24[8] = {
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11001,
 B00000,
 B10000
};
byte mario25[8] = {
 B00000,
 B00000,
 B11100,
 B10000,
 B11100,
 B11110,
 B11100,
 B11000,

};

byte mario26[8] = {
 B11111,
 B11111,
 B10110,
 B11110,
 B11110,
 B11110,
 B00000,
 B00000,
};

byte mario31[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,

};


byte mario32[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00011,
 B00011,
 B00111,
 B00000
};


byte mario33[8] = {
 B00000,
 B00000,
 B00111,
 B01111,
 B01111,
 B11111,
 B11111,
 B11111,

};

byte mario34[8] = {
 B01111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B00111,
 B00111
};

byte mario35[8] = {
 B00000,
 B00000,
 B10000,
 B11110,
 B11000,
 B11110,
 B11111,
 B11110,

};

byte mario36[8] = {
 B11100,
 B11110,
 B11100,
 B11000,
 B11000,
 B10000,
 B00000,
 B10000,
};

byte mario41[8] = {
 B00000,
 B00011,
 B00111,
 B00111,
 B01111,
 B01111,
 B01111,
 B00011,

};


byte mario42[8] = {
 B01111,
 B01111,
 B01111,
 B01111,
 B00111,
 B00011,
 B00011,
 B00011
};

byte mario43[8] = {
 B00000,
 B11000,
 B11111,
 B11100,
 B11111,
 B11111,
 B11111,
 B11110,
};

byte mario44[8] = {
 B11100,
 B11110,
 B11110,
 B11110,
 B11100,
 B11100,
 B11110,
 B10000
};


byte mario51[8] = {
 B00000,
 B00001,
 B00011,
 B00011,
 B00111,
 B00111,
 B00111,
 B00001,
};

byte mario52[8] = {
 B11111,
 B11111,
 B11011,
 B00111,
 B01111,
 B11111,
 B11100,
 B01110,
};
 
byte mario53[8] = {
 B00000,
 B11100,
 B11111,
 B11110,
 B11111,
 B11111,
 B11111,
 B11111,
};

byte mario54[8] = {
 B11111,
 B11111,
 B11110,
 B11111,
 B11111,
 B01111,
 B00000,
 B00000,
};



byte mario55[8] = {
 B00000,
 B00000,
 B10000,
 B00000,
 B00000,
 B10000,
 B00000,
 B00000,
};


byte mario56[8] = {
 B11000,
 B11000,
 B10000,
 B10000,
 B10000,
 B10000,
 B00000,
 B00000,
};


byte mario61[8] = {
 B00000,
 B00000,
 B00000,
 B00001,
 B00001,
 B00011,
 B00011,
 B00011,
};

byte mario62[8] = {
 B00001,
 B00011,
 B00111,
 B01111,
 B01111,
 B11111,
 B11000,
 B00000,
};



byte mario63[8] = {
 B00000,
 B00000,
 B11110,
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
};

byte mario64[8] = {
 B11111,
 B11111,
 B11111,
 B11111,
 B11111,
 B11110,
 B11100,
 B11110,
};

byte mario65[8] = {
 B00000,
 B00000,
 B00000,
 B10000,
 B00000,
 B10000,
 B11000,
 B10000,
};


byte mario66[8] = {
 B00000,
 B10000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
};

byte clean[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
 B00000,
};

byte coin1[8] = {

 B00000,
 B00000,
 B00000,
 B00000,
 B00111,
 B01000,
 B10001,
 B10010,
};

byte coin2[8] = {
 
 B10010,
 B10010,
 B10010,
 B10010,
 B10001,
 B01000,
 B00111,
B00000,
};


byte coin3[8] = {
 B00000,
 B00000,
 B00000,
 B00000,
 B10000,
 B01000,
 B00100,
 B10100,
};

byte coin4[8] = {
 B10100,
 B10100,
 B10100,
 B00100,
 B00100,
 B01000,
 B10000,
 B00000,
};

 void setup() {
 lcd.begin(16,2);
 lcd.clear();
 
 s=1000/f;            //fps to ms

}

void loop() {
  
 lcd.setCursor(0,0);            //intro
 lcd.print("  8-Bit Mario");
 lcd.setCursor(0,1);
 lcd.print(" Run Animation");
 delay(2000);
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print("    By");
 lcd.setCursor(0,1);
 lcd.print("Jan Stapler");

 
 lcd.createChar(1, coin1);       //coin frames for the intro
 lcd.createChar(2, coin2);
 lcd.createChar(3, coin3);
 lcd.createChar(4, coin4);
 
 lcd.setCursor(11,0);
 lcd.write(1);
 lcd.setCursor(11,1);
 lcd.write(2);
 lcd.setCursor(12,0);
 lcd.write(3);
 lcd.setCursor(12,1);
 lcd.write(4);
  lcd.setCursor(14,0);
 lcd.write(1);
 lcd.setCursor(14,1);
 lcd.write(2);
 lcd.setCursor(15,0);
 lcd.write(3);
 lcd.setCursor(15,1);
 lcd.write(4);
 delay(2000);
 lcd.clear();
 
 
for (int a=0; a<16;a++)     //for loop to repeat marios animation until the end of the display
 {
 int b=a+1;
 int c=a+2;
 int d=a+3;
 int e=a+4; 
  
 lcd.createChar(1, mario11);
 lcd.createChar(2, mario12);
 lcd.createChar(3, mario13);
 lcd.createChar(4, mario14);
 lcd.createChar(5, mario15);
 lcd.createChar(6, mario16);
 lcd.createChar(7, clean);
 
 lcd.setCursor(a,0);
 lcd.write(1);
 lcd.setCursor(a,1);
 lcd.write(2);
 lcd.setCursor(b,0);
 lcd.write(3);
 lcd.setCursor(b,1);
 lcd.write(4);
 lcd.setCursor(c,0);
 lcd.write(5);
 lcd.setCursor(c,1);
 lcd.write(6);
 delay(s);
 
 lcd.createChar(1, mario21);
 lcd.createChar(2, mario22);
 lcd.createChar(3, mario23);
 lcd.createChar(4, mario24);
 lcd.createChar(5, mario25);
 lcd.createChar(6, mario26);

 lcd.setCursor(a,0);
 lcd.write(1);
 lcd.setCursor(a,1);
 lcd.write(2);
 lcd.setCursor(b,0);
 lcd.write(3);
 lcd.setCursor(b,1);
 lcd.write(4);
 lcd.setCursor(c,0);
 lcd.write(5);
 lcd.setCursor(c,1);
 lcd.write(6);

 delay(s);
 
  lcd.createChar(1, mario31);
 lcd.createChar(2, mario32);
 lcd.createChar(3, mario33);
 lcd.createChar(4, mario34);
 lcd.createChar(5, mario35);
 lcd.createChar(6, mario36);

 lcd.setCursor(a,0);
 lcd.write(1);
 lcd.setCursor(a,1);
 lcd.write(2);
 lcd.setCursor(b,0);
 lcd.write(3);
 lcd.setCursor(b,1);
 lcd.write(4);
 lcd.setCursor(c,0);
 lcd.write(5);
 lcd.setCursor(c,1);
 lcd.write(6);
 
 delay(s);
 
 lcd.createChar(1, mario41);
 lcd.createChar(2, mario42);
 lcd.createChar(3, mario43);
 lcd.createChar(4, mario44);
 lcd.createChar(7, clean);
  lcd.setCursor(a,0);
 lcd.write(7);
 lcd.setCursor(a,1);
 lcd.write(7);
 lcd.setCursor(b,0);
 lcd.write(1);
 lcd.setCursor(b,1);
 lcd.write(2);
 lcd.setCursor(c,0);
 lcd.write(3);
 lcd.setCursor(c,1);
 lcd.write(4);


 delay(s);
 
 
 lcd.createChar(1, mario51);
 lcd.createChar(2, mario52);
 lcd.createChar(3, mario53);
 lcd.createChar(4, mario54);
 lcd.createChar(5, mario55);
 lcd.createChar(6, mario56);
 lcd.createChar(7, clean);
 lcd.setCursor(a,0);
 lcd.write(7);
 lcd.setCursor(a,1);
 lcd.write(7);
 lcd.setCursor(b,0);
 lcd.write(1);
 lcd.setCursor(b,1);
 lcd.write(2);
 lcd.setCursor(c,0);
 lcd.write(3);
 lcd.setCursor(c,1);
 lcd.write(4);
 lcd.setCursor(d,0);
 lcd.write(5);
 lcd.setCursor(d,1);
 lcd.write(6);
 
 delay(s);
 
  lcd.createChar(1, mario61);
 lcd.createChar(2, mario62);
 lcd.createChar(3, mario63);
 lcd.createChar(4, mario64);
 lcd.createChar(5, mario65);
 lcd.createChar(6, mario66);
 lcd.setCursor(b,0);
 lcd.write(1);
 lcd.setCursor(b,1);
 lcd.write(2);
 lcd.setCursor(c,0);
 lcd.write(3);
 lcd.setCursor(c,1);
 lcd.write(4);
 lcd.setCursor(d,0);
 lcd.write(5);
 lcd.setCursor(d,1);
 lcd.write(6);
 
 delay(s);
 }
 
}

Paul__B:
Run the I2Cguesser to get the descriptor. Then find some proper code.

Thanks. And it doesn't matter to which pins SDA and SCL are connected on the Arduino?

knahrvorn:
Thanks. And it doesn't matter to which pins SDA and SCL are connected on the Arduino?

It does matter. As you have an UNO board, you must connect the SDA to the A4 pin and the SCL to the A5 pin (as you may see here). The other 2 pins are +5V and GND.

That works indeed! Thank you!