Authorized Online Retailers:
In this lesson, we’ll introduce how to drive IIC (sometimes call I2C) 1602 LCD using Raspberry Pi.
1 * Raspberry Pi
1 * Breadboard
1 * IIC 1602 LCD (16 x 2 characters)
Several jumper wires
Note: In this lesson, we remotely control raspberry pi via PuTTy on PC. To learn how to config raspberry pi, please visit lesson 1: getting started with raspberry pi.
This This 1602 LCD display screen can display 16(each row) x 2 (rows) characters. Generally, LCD 1602 has parallel port, it occupy many GPIO pins. This 1602 LCD comes with a I2C communicate interface using a PCF8574 IC Chip. It means you can realize data display via only 2 wires.
Wiring up IIC 1602 LCD to Pi as following connection graph.
Note: SDA 1 is BCM 2 , SCL 1 is BCM 3 , for detail about GPIO#, read Lesson 2 , these 2 pins normally are used to exchange serial data with external devices.
To use the IIC 1602 LCD,we should enable the I2C port firstly, please follow the steps as followed:
1) Open IIC
sudo nano /boot/config.txt
open the file /boot/config.txt, find the code line”dtparam=i2c_arm”,checking if there is # sign in front of the line, uncomment it (remove the # in front of this line), and make sure the end of the line is”on”, finally the code should look like this:
Press Ctrl+X,and type “Y” to save the file you revised.
2) Load Modules
sudo nano /etc/modules
open /etc/modules file,Add these two lines as below:
i2c-bcm2708
i2c-dev
Press Ctrl+X, and type “Y” to save the file you revised.
3) Install i2c python library and smbus
sudo apt-get install -y python-smbus i2c-tools
Now reboot Pi
reboot
4) Cheking the if library is installed successfully by typing following command:
lsmod | grep i2c
If the terminal will show the message as below if installed successfully,otherwise please repeat above steps.
5) Checking for any components connected to the i2c bus by using i2c detect
sudo i2cdetect -y 1
or port 0 on the older Raspberry Pi
sudo i2cdetect -y 0
Once run the command, A table like below will be shown and if any devices are connected, the address will be shown. Below you can see that a device is connected to the i2c bus which is using the address of 0x3f.
Note: Above code line 5 is to define LCD I2C address. If your LCD does not display properly, you might need change the value from 0x3f to 0x27
For C language user,please take the steps as followed:
1) Download the sample code by typing following terminal command:
cd ~
sudo wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_13/i2c1602_lcd.c
If you want to customize the sample code file , you can use nano editor to edit source code by typing following command in terminal:
sudo nano i2c1602_lcd.c
2) copmlie code
gcc -Wall -o i2c1602_lcd i2c1602_lcd.c -lwiringPi
3) Run the program
sudo ./i2c1602_lcd
Once run the program, the terminal will message as code, while the LCD screen will display the message at the same time.
Note:You can adjust the contrast of the screen by spinning the potentiometer screw in the back of the LCD clockwise or anticlockwise, until the screen displays characters clearly.
C source code and comments:
#include < stdio.h> #include < wiringPi.h> #include < wiringPiI2C.h> #include < string.h> int LCDAddr = 0x3f;//I2c address of LCD, some LCD i2c address might be 0x27 int BLEN = 0;//1--open backlight.0--close backlight int fd;//linux file descriptor //send an 16 bits data to LCD buffer void write_word(int data){ int temp = data; if ( BLEN == 1 ) temp |= 0x08; else temp &= 0xF7; wiringPiI2CWrite(fd, temp); } //send control command to lcd void send_command(int comm){ int buf; // Send bit7-4 firstly buf = comm & 0xF0; buf |= 0x04; // RS = 0, RW = 0, EN = 1 write_word(buf); delay(2); buf &= 0xFB; // Make EN = 0 write_word(buf); // Send bit3-0 secondly buf = (comm & 0x0F) buf |= 0x04; // RS = 0, RW = 0, EN = 1 write_word(buf); delay(2); buf &= 0xFB; // Make EN = 0 write_word(buf); } //send character to lcd void send_data(int data){ int buf; // Send bit7-4 firstly buf = data & 0xF0; buf |= 0x05; // RS = 1, RW = 0, EN = 1 write_word(buf); delay(2); buf &= 0xFB; // Make EN = 0 write_word(buf); // Send bit3-0 secondly buf = (data & 0x0F) buf |= 0x05; // RS = 1, RW = 0, EN = 1 write_word(buf); delay(2); buf &= 0xFB; // Make EN = 0 write_word(buf); } //initialize the lcd void init(){ send_command(0x33); // Must initialize to 8-line mode at first delay(5); send_command(0x32); // Then initialize to 4-line mode delay(5); send_command(0x28); // 2 Lines & 5*7 dots delay(5); send_command(0x0C); // Enable display without cursor delay(5); send_command(0x01); // Clear Screen wiringPiI2CWrite(fd, 0x08); } //clear screen void clear(){ send_command(0x01); //clear Screen } //Print the message on the lcd void write(int x, int y, char data[]){ int addr, i; int tmp; if (x < 0) x = 0; if (x > 15) x = 15; if (y < 0) y = 0; if (y > 1) y = 1; // Move cursor addr = 0x80 + 0x40 * y + x; send_command(addr); tmp = strlen(data); for (i = 0; i < tmp; i++){ send_data(data[i]); } } void print_info() { printf("\n"); printf("|***************************|\n"); printf("| IIC 1602 LCD test |\n"); printf("| --------------------------|\n"); printf("| | LCD | | Pi |\n"); printf("| --------------------------|\n"); printf("| | GND | connect to | GND |\n"); printf("| | VCC | connect to | 5V |\n"); printf("| | SDA | connect to | SDA.1|\n"); printf("| | SCL | connect to | SCL.1|\n"); printf("| --------------------------|\n"); printf("| OSOYOO|\n"); printf("|***************************|\n"); printf("Program is running...\n"); printf("Press Ctrl+C to end the program\n"); } int main(){ //init I2C, assign a buffer handler to variable fd fd = wiringPiI2CSetup(LCDAddr); init(); print_info(); write(0, 0, "Hi man.Welcome "); write(0, 1, "to osoyoo.com"); delay(3000); clear(); while(1){ write(0,0,"This is Lesson13"); write(0,1,"IIC LCD Test"); delay(1000); } return 0; }
1) Download the Python code from osoyoo by typing following commands:
cd ~
sudo wget http://osoyoo.com/driver/pi3_start_learning_kit_lesson_13/i2c1602_lcd.py
Open I2C1602_lcd.py file by typing following command in terminal:
sudo nano i2c1602_lcd.py
find the code line as blow and change the address to your correct I2C address, in this example,the I2C address is 0x3F
2) Run the program
sudo python ./i2c1602_lcd.py
3) Running result
Once run the program, the terminal will message as code, while the LCD screen will display the message at the same time.
Note:You can adjust the contrast of the screen by spinning the potentiometer clockwise or anticlockwise, until the screen displays characters clearly.
Python sample code Analysis:
import smbus import time # Define some device parameters I2C_ADDR = 0x3F # I2C device address, if any error, change this address to 0x27 LCD_WIDTH = 16 # Maximum characters per line # Define some device constants LCD_CHR = 1 # Mode - Sending data LCD_CMD = 0 # Mode - Sending command LCD_LINE_1 = 0x80 # LCD RAM address for the 1st line LCD_LINE_2 = 0xC0 # LCD RAM address for the 2nd line LCD_LINE_3 = 0x94 # LCD RAM address for the 3rd line LCD_LINE_4 = 0xD4 # LCD RAM address for the 4th line LCD_BACKLIGHT = 0x08 # On #LCD_BACKLIGHT = 0x00 # Off ENABLE = 0b00000100 # Enable bit # Timing constants E_PULSE = 0.0005 E_DELAY = 0.0005 #Open I2C interface #bus = smbus.SMBus(0) # Rev 1 Pi uses 0 bus = smbus.SMBus(1) # Rev 2 Pi uses 1 def lcd_init(): # Initialise display lcd_byte(0x33,LCD_CMD) # 110011 Initialise lcd_byte(0x32,LCD_CMD) # 110010 Initialise lcd_byte(0x06,LCD_CMD) # 000110 Cursor move direction lcd_byte(0x0C,LCD_CMD) # 001100 Display On,Cursor Off, Blink Off lcd_byte(0x28,LCD_CMD) # 101000 Data length, number of lines, font size lcd_byte(0x01,LCD_CMD) # 000001 Clear display time.sleep(E_DELAY) def lcd_byte(bits, mode): # Send byte to data pins # bits = the data # mode = 1 for data # 0 for command bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT # High bits bus.write_byte(I2C_ADDR, bits_high) lcd_toggle_enable(bits_high) # Low bits bus.write_byte(I2C_ADDR, bits_low) lcd_toggle_enable(bits_low) def lcd_toggle_enable(bits): # Toggle enable time.sleep(E_DELAY) bus.write_byte(I2C_ADDR, (bits | ENABLE)) time.sleep(E_PULSE) bus.write_byte(I2C_ADDR,(bits & ~ENABLE)) time.sleep(E_DELAY) def lcd_string(message,line): # Send string to display message = message.ljust(LCD_WIDTH," ") lcd_byte(line, LCD_CMD) for i in range(LCD_WIDTH): lcd_byte(ord(message[i]),LCD_CHR) def main(): # Main program block # Initialise display lcd_init() while True: # Send some test lcd_string("Created by <",LCD_LINE_1) lcd_string("Osoyoo.com <",LCD_LINE_2) time.sleep(3) # Send some more text lcd_string("> Tutorial Url:",LCD_LINE_1) lcd_string("> https://osoyoo.com",LCD_LINE_2) time.sleep(3) if __name__ == '__main__': try: main() except KeyboardInterrupt: pass finally: lcd_byte(0x01, LCD_CMD)
DownLoad Url osoyoo.com
You must be logged in to post a comment.
The LCD backlight consumes quite a lot of power. Whats the function to turn off the backlight?
You can turn around the Potentiometer at the back of LCD to adjust LCD backlight
Thats for adjusting contrast. am talking about turning the backlight off from code.
In C language code, Line 6:
“int BLEN = 0;//1–open backlight.0–close backlight”
In Python code,
“LCD_BACKLIGHT = 0x08 # On
#LCD_BACKLIGHT = 0x00 # Off”
Please change “0x08” to “0x00”