From charlesreid1

This page covers how to use a SainSmart LCD 2004 display with an Arduino.

Sainsmart.jpg

Similar link: https://learn.adafruit.com/adafruit-arduino-lesson-11-lcd-displays-1

Overview

So far we've covered some really simple circuits with single components. We're not doing a whole lot with the voltages in our system, or with the microcontroller. This project will introduce a more advanced output device for the Arduino, namely, an LCD display for printing simple text messages.

The LCD Display

To begin with, we can note a couple of things about the LCD display:

First, the display has its own microcontroller on-board, meaning it has hardware dedicated to turning voltage signals on the microcontroller board (coming from the Arduino) into the right output signals for its LCD display. All of that circuitry and the details of connecting an Arduino to the Sainsmart LCD 2004 are covered on the Sainsmart website (scroll down to the documents section, they link to a zip file that contains a bunch of example sketches and

What is I2C?

We've already noticed there's a separate integrated circuit onboard the LCD display. That means we'll be using something called I2C, which stands for Inter-Integrated Circuit. It's a way for integrated circuits (microprocessors) to talk to each other.

I2C Pins on Arduino

In order to use I2C, you'll need to use special I2C pins onboard the Arduino. There are two wires - one is labeled SDA (System Data) and the other is labeled SCL (System Clock). They're labeled SDA and SCL on the Sainsmart's board, so that side will be clear. But which pins they'll plug into on the Arduino board depends on the type of board.

This site lists the SDA/SCL pins for a couple of boards, and I've added a few:

Board Type SDA Pin SCL Pin Reference
Micro 1 2 Arduino.cc website - Arduino Micro
Uno A4 A5 An excellent and very thorough I2C example
Leonardo 2 3 Robotic-Controls.com
Mega2560 20 21 Robotic-Controls.com
Due 20 21 Robotic-Controls.com
Raspberry Pi 3 5 SparkFun.com

The Circuit

Breadboard Diagram

The breadboard diagram below is a diagram of what I'm doing. I couldn't find the LCD 2004 in the Fritzing library, but the hookups on the LCD side are so obvious that you shouldn't need a diagram for them.

Bb LCD.png

The two signal wires (SDA and SCL) hook up to pins 2 and 3 on the Micro, and the red and black voltage pins hook up to the Arduino Micro's red and black voltage pins.

Breadboard Photo

Here's what the breadboard wiring looks like on the Arduino side: red and black pulling 5 V.

Photo Sainsmart1.jpg

We have the 5V and ground wires (red and black), and the SDA and SCL wires (green and yellow).

The other side is hooked up in a straightforward way:

Photo Sainsmart2.jpg

Hello World Sainsmart Sketch Code

To display static information on the display, Sainsmart provides the following "Hello World" app:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
 
#define I2C_ADDR    0x3F 
#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);
 
void setup() {
  lcd.begin(20,4);        // 20 columns by 4 rows on display
 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.setCursor(3,0);
  lcd.print("Hello, world!");
  lcd.setCursor(2,1);
  lcd.print("SainSmart for UNO");
   lcd.setCursor(2,2);
  lcd.print("SainSmart LCM IIC");
   lcd.setCursor(1,3);
  lcd.print("Design By SainSmart");
}
 
void loop()
{
}

and a photo of the finished product:

Photo staticlcd.jpg

Photo staticlcd2.jpg

Note that you'll find a couple of different I2C addresses floating around, like 0x20 and 0x27. I'm not sure where people are getting those from, but the 0x3F value comes from Sainsmart's website, and it works right out of the box.

Hello World Counter

Here's another quick sketch, this one updates a value on the display with a counter to make things slightly more interesting. It also initializes the LCD object slightly differently, specifying more pins. Not sure why, but at least I know how to do it.

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

#define I2C_ADDR    0x3F

#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);

void setup() {
  lcd.begin(20,4);        // 20 columns by 4 rows on display

  lcd.setBacklight(HIGH); // Turn on backlight, LOW for off

  lcd.setCursor ( 0, 0 );            // go to the top left corner
  lcd.print("robotic-controls.com"); // write this string on the top row
  lcd.setCursor ( 0, 1 );            // go to the 2nd row
  lcd.print("  HD44780 / LCD2004 "); // pad string with spaces for centering
  lcd.setCursor ( 0, 2 );            // go to the third row
  lcd.print("  20x4 i2c display  "); // pad with spaces for centering
  lcd.setCursor ( 0, 3 );            // go to the fourth row
  lcd.print("Test increment: ");
}

int n = 1; // a global variable to track number of display refreshes

void loop() {
  lcd.setCursor (16,3);         // go to col 16 of the last row
  lcd.print(n++,DEC);           // update the display with a new number
                                // - overwrites previous characters
                                // - be sure new number is more digits
  delay(500);                   // wait half a second before another update
}

and pictures of it working:

Photo LCDCounter.jpg

References