16x2 I2C LCD Tutorials on C2
This wiki is based on the following magazine.
https://magazine.odroid.com/article/i2c-lcd-module-using-twi-1602-16x2-serial-lcd
Thank you for @Miltiadis Melissas
This tutorial has tested on Ubuntu 18.04 kernel 3.16 version.
Check your kernel and ubuntu version
odroid@odroid:~$ uname -r 3.16.65-39 odroid@odroid:~$ lsb_release -r Release: 18.04 odroid@odroid:~$
Requirements
First, you’ll need to update ODROID-C2 to ensure all the latest packages are installed.
sudo apt update sudo apt upgrade
sudo apt install i2c-tools python3-smbus
If you use python2, install “python-smbus” package instaed of “python3-smbus”
sudo apt install python-smbus
Wiring
Setting for I2C
Run the command below to automatically load the module when the system boots.
echo "aml_i2c" | sudo tee -a /etc/modules echo "blacklist w1_gpio" | sudo tee -a /etc/modprobe.d/blacklist-odroid.conf
To use the i2c devices as user privilege, run this command.
sudo adduser odroid i2c
Reboot to apply all of the above settings.
sudo reboot
After reboot, you can see the below results with “lsmod” command.
odroid@odroid:~$ lsmod Module Size Used by fuse 90892 3 squashfs 32435 0 meson_gpiomem 4040 0 gxbb_wdt 3395 0 sch_fq_codel 7827 2 sx865x 5179 0 aml_i2c 16735 0 ip_tables 17220 0 ipv6 387537 24 autofs4 27592 2 odroid@odroid:~$
Check for connection
If the address shown below is not 0x27, you have to modify the variable “I2C_ADDR” to that address in python source code.
odroid@odroid:~$ sudo i2cdetect -y -r 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- 27 -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- --
Python software
import smbus import time # Define device parameters I2C_ADDR = 0x27 # I2C device address, if any error, # change this address to 0x3f LCD_WIDTH = 16 # Maximum characters per line # Define 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 ENABLE = 0b00000100 # Enable bit # Timing constants E_PULSE = 0.0005 E_DELAY = 0.0005 #Open I2C interface bus = smbus.SMBus(1) # Open I2C interface for ODROID-C2 # Initialise display def lcd_init(): 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) # Send byte to data pins # (#bits = the data, #mode = 1 for data or 0 for command) def lcd_byte(bits, mode): bits_high = mode | (bits & 0xF0) | LCD_BACKLIGHT bits_low = mode | ((bits<<4) & 0xF0) | LCD_BACKLIGHT bus.write_byte(I2C_ADDR, bits_high) # High bits lcd_toggle_enable(bits_high) bus.write_byte(I2C_ADDR, bits_low) # Low bits lcd_toggle_enable(bits_low) # Toggle enable def lcd_toggle_enable(bits): 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) # Send string to display def lcd_string(message,line): message = message.ljust(LCD_WIDTH," ") lcd_byte(line, LCD_CMD) for i in range(LCD_WIDTH): lcd_byte(ord(message[i]),LCD_CHR) # Main program block, # Initialize display def main(): lcd_init() # Send text to I2C TWI 1602 16x2 Serial LCD Module Display while True: lcd_string("***ODROID-C2***",LCD_LINE_1) lcd_string("ODROID-magazine ",LCD_LINE_2) time.sleep(3) lcd_string("***HardKernel***",LCD_LINE_1) lcd_string("*hardkernel.com*",LCD_LINE_2) time.sleep(3) # Handling keyboard interrupts and exception utility if __name__ == '__main__': try: main() except KeyboardInterrupt: pass finally: lcd_byte(0x01, LCD_CMD)