Skip to content

LED_displays_HD44780 i2c

Micz Flor edited this page Mar 19, 2020 · 1 revision

using LCD displays based on HD44780

Contributed by @SimonChelkowski and @davidfri

Due to licensing issues, we can not commit the code to the code base. See above link for details. You find the referenced files at the end of this document.

This pull request related to the open issue #498.

The following files allow using LCD displays based on HD44780 connected via i2c bus for this project. The following displays have been used for testing:

  • 2x16 display
  • 4x20 display (recommended as more information can be displayed)

Various informations such as artist, album, track_number, track_title, track_time and many more can be displayed see main script for more display options.

The required files are:

  • components/displays/HD44780-i2c/i2c_lcd.py
  • components/displays/HD44780-i2c/i2c_lcd_driver.py
  • components/displays/HD44780-i2c/i2c-lcd.service.default.sample
  • components/displays/HD44780-i2c/README.md

The first file is the main LCD script that makes use of I2C_LCD_driver.py. The second file is the library needed to drive the LCD via i2c, originates from DenisFromHR (Denis Pleic) see http://www.circuitbasics.com/raspberry-pi-i2c-lcd-set-up-and-programming The third is used as sample service file that runs the i2c_lcd.py main script at boot-up if the service is properly installed (install description can be found below.). The fourth file is this file which describes the features, usage and installation of the code.

Installation

  1. You need to install additional python libraries. Run the following two command in the command line:

sudo apt-get install i2c-tools python-smbus python3-numpy python-mpdclient python-mpd

pip install smbus numpy python-mpd2

  1. You need to know which I2C bus your Raspberry Pi has available on GPIOs:

ls /dev/i2c-*

It'll output "/dev/i2c-x", where x is your bus number. Note this bus number as you will need it in step 6.

  1. Now detect the adapter by using the i2cdetect command, inserting your bus number:

sudo i2cdetect -y bus_number

The I2C address of my LCD is 27. Take note of this number, it will be need in step 6.

  1. if i2cdetect is not found install i2c-tools

sudo apt-get update

sudo apt-get install i2c-tools

  1. Next we need to install SMBUS, which gives the Python library we’re going to use access to the I2C bus on the Pi. At the command prompt, enter

sudo apt-get install python-smbus

  1. Modify "i2c_lcd_driver.py" line 19 which reads "I2CBUS = 1" and adapt it to your bus number (see step 2.) Furthermore modify line 22 which reads "ADDRESS = 0x27" and adapt it to your I2C address (see step 3.)

  2. Modify "i2c_lcd.py" to adapt it yo your specific display e.g. 2x16 or 4x20 (default). The lines 15-19 look like the following:

## Display settings                                                                     ##
n_cols = 20                 # EDIT!!!  <-- number of cols your display has              ##
n_rows = 4                  # EDIT!!!  <-- number of rows your display has              ##
val_delay = 0.4             # EDIT!!!  <-- speed of the scolling text                   ##

Check if "n_cols" and "n_rows" need to be changed and modify them if necessary. The "val_delay" constant leave for the time being. Lower values will speed up things but will make the text less visible/readable.

  1. next install and start "i2c-lcd.service"

sudo cp /home/pi/RPi-Jukebox-RFID/components/displays/HD44780-i2c/i2c-lcd.service.default.sample /etc/systemd/system/i2c-lcd.service

  1. register service by running, it will thereby start on the next boot-up

sudo systemctl enable i2c-lcd

  1. reboot and enjoy!

For test purposes you can use the following command to start and stop the service without rebooting

to start the service instantly run

sudo systemctl start i2c-lcd

to stop the service instantly run

sudo systemctl stop i2c-lcd

Files needed:

i2c-lcd.service.default.sample

[Unit]  
Description=LCD Matrix Display Service
After=network.target phoniebox-rfid-reader.service

[Service]
User=pi
Group=pi
Restart=always
WorkingDirectory=/home/pi/RPi-Jukebox-RFID
ExecStart=/home/pi/RPi-Jukebox-RFID/components/displays/HD44780-i2c/i2c_lcd.py

[Install]
WantedBy=multi-user.target

i2c_lcd.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import i2c_lcd_driver
from time import *
import time
import subprocess
import numpy
#import datetime
from mpd import MPDClient
### constants
mylcd = i2c_lcd_driver.lcd()
info_at_lines_play = [" "]*4
info_at_lines_pause = [" "]*4
info_at_lines_stop = [" "]*4
info_at_lines_mpd_not_running = [" "]*4
################# CHANGE YOUR SETTINGS HERE!!! ###########################################
## Display settings                                                                     ##
n_cols = 20                 # EDIT!!!  <-- number of cols your display has              ##
n_rows = 4                  # EDIT!!!  <-- number of rows your display has              ##
val_delay = 0.4             # EDIT!!!  <-- speed of the scolling text                   ##
start_stop_sc_delay=4                                                                   ##
use_state_icons="yes"   #choose "yes" if you want to use this                           ##
blinking_icons="no" #its an add-on for "use_state_icons", so "use_state_icons" must be "yes" ##
backlight_off_while_waiting="yes" #not active in state "play" and "pause"               ##
backlight_off_delay= 10 # Delay in seconds                                              ##
#### change the following strings to give your box a personal style                     ##
mpd_not_running_string = "MPD not running"                                              ##
music_stopped_string = "Music stopped!"                                                 ##
music_paused_string = "paused!"                                                         ##
##                                                                                      ##
################## CHANGE YOUR INFOS, WHICH WILL BE SHOWN ON THE DISPLAY #################
##                                                                                      ##
##  You can choose between the following infos:                                         ##
##  'date_and_time', 'artist', 'nothing', 'track_title', 'track_artist_title'           ##
##  'track_time', 'pause_string', 'stop_string', 'mpd_not_running_string'               ##
##  'track_time_and_number'                                                             ##
##                                                                                      ##
##  if you have less than 4 lines, you can leave the unused lines by default            ##
##                                                                                      ##
##  Choose infos while state is "play"                                                  ##
##                                                                                      ##
info_at_lines_play [0] = 'date_and_time' #  <-- Choose your favorite                    ##
info_at_lines_play [1] = 'artist' #  <-- Choose your favorite                           ##
info_at_lines_play [2] = 'title' #  <-- Choose your favorite                            ##
info_at_lines_play [3] = 'track_time_and_number' #  <-- Choose your favorite            ##
##                                                                                      ##
##  Choose infos while state is "pause"                                                 ##
##                                                                                      ##
info_at_lines_pause [0] = 'date_and_time' #  <-- Choose your favorite                   ##
info_at_lines_pause [1] = 'artist' #  <-- Choose your favorite                          ##
info_at_lines_pause [2] = 'title' #  <-- Choose your favorite                           ##
info_at_lines_pause [3] = 'pause_string' #  <-- Choose your favorite                    ##
##                                                                                      ##
##  Choose infos while state is "stop"                                                  ##
##                                                                                      ##
info_at_lines_stop [0] = 'date_and_time' #  <-- Choose your favorite                    ##
info_at_lines_stop [1] = 'nothing' #  <-- Choose your favorite                          ##
info_at_lines_stop [2] = 'nothing' #  <-- Choose your favorite                          ##
info_at_lines_stop [3] = 'stop_string' #  <-- Choose your favorite                      ##
##                                                                                      ##
##  Choose infos while state is "not_running"                                           ##
##                                                                                      ##
info_at_lines_mpd_not_running [0] = 'date_and_time' #  <-- Choose your favorite         ##
info_at_lines_mpd_not_running [1] = 'nothing' #  <-- Choose your favorite               ##
info_at_lines_mpd_not_running [2] = 'nothing' #  <-- Choose your favorite               ##
info_at_lines_mpd_not_running [3] = 'mpd_not_running_string' #  <-- Choose your favorite##
##                                                                                      ##
##########################################################################################

## DO NOT EDIT!!!
clearline = " " * n_cols
string_track_title = " "
string_track_artist_title = " "
string_date_time = " "
track_number = " "
title = " "
playlist_length=" "
last_title = " "
i_counter = 0
state = " "
last_state = "not_running"
track_time = " "
current_time = time.time()
last_time = time.time()
if n_cols >16: # select date_string dependent on how many columns the display has (usually either 16 or 20 rows)
	date_string="%d.%m.%Y %H:%M"
else:
	date_string = "%d.%m.%y %H:%M" # save two character spaces  for displays showing only 16 characters per row

# lines that got to show
lines = [" "*n_cols]*n_rows
last_lines = [" "*n_cols]*n_rows

# User icons
user_icons = [
  [0b10000, # Play
   0b11000,
   0b11100,
   0b11110,
   0b11100,
   0b11000,
   0b10000,
   0b00000],
  [0b00000, # Pause
   0b11011,
   0b11011,
   0b11011,
   0b11011,
   0b11011,
   0b11011,
   0b00000],
  [0b00000, # Stop
   0b11111,
   0b11111,
   0b11111,
   0b11111,
   0b11111,
   0b00000,
   0b00000],
  [0b00000, # Offline
   0b00000,
   0b01010,
   0b00000,
   0b01110,
   0b10001,
   0b00000,
   0b00000]]

def print_changes (string_new,string_old,row):
	for pos in range(len(string_new)):
		if string_new[pos] != string_old[pos]:
			mylcd.lcd_display_string(string_new[pos], row, pos)


def fill_with_spaces(string1,length):
	if len(string1) <= length:
		return (string1 + " " * (length - len(string1)))
	else:
		return string1

def loop_string(string1, string2):
	my_long_string = string2
	title_max_length = n_cols - len(string1) #max_len is dependent by len (track_number)
	position = numpy.clip((i_counter % (len(string2)-(title_max_length-1)+2*start_stop_sc_delay))-start_stop_sc_delay,0,len(string2)-(title_max_length))
	scroll_text = my_long_string[position:(position+title_max_length)]
	return (string1+scroll_text)

def print_nothing():
	return clearline

def print_pause_string():
	return (fill_with_spaces(music_paused_string,n_cols))
def print_stop_string():
	return (fill_with_spaces(music_stopped_string,n_cols))

def print_mpd_not_running_string():
	return (fill_with_spaces(mpd_not_running_string,n_cols))

def print_artist():
	if len(artist)<=n_cols:
		return fill_with_spaces(artist,n_cols)
	else:
		return loop_string("", artist) ### SC version

def print_track_title():
	## Write Track number & Title into the row of the display 
	string_track_title = track_number + ":" + title
	if len(string_track_title)<=n_cols:
		return fill_with_spaces(string_track_title,n_cols)
	else:
		return loop_string(track_number + ":", title) ### SC version
def print_title():
	## Write Title into the row of the display 
	if len(title)<=n_cols:
		return fill_with_spaces(title,n_cols)
	else:
		return loop_string("",title) ### SC version

def print_track_artist_title():
	string_track_artist_title = track_number + ":" + artist + " - "+ title
	if len(string_track_artist_title)<=n_cols:
		return fill_with_spaces(string_track_artist_title,n_cols)
	else:
		return loop_string(track_number+":", artist + " - " + title) ### SC version
def print_artist_title():
	string_artist_title = artist + " - "+ title
	if len(string_artist_title)<=n_cols:
		return fill_with_spaces(string_artist_title,n_cols)
	else:
		return loop_string("", artist + " - " + title) ### SC version
def print_track_time():
	return fill_with_spaces(track_time,n_cols)

def print_track_time_and_number():
	song_of_playlist = track_number + "/" + playlist_length
	return (fill_with_spaces(track_time,n_cols))[:(n_cols-len(song_of_playlist))] + song_of_playlist

def print_date_time():
	return fill_with_spaces(time.strftime(date_string),n_cols)

def choose_line(info_text):
	switcher = {
		'pause_string': print_pause_string(),
		'stop_string': print_stop_string(),
		'mpd_not_running_string': print_mpd_not_running_string(),
		'track_title': print_track_title(),
		'track_artist_title': print_track_artist_title(),
		'artist_title': print_artist_title(),
		'artist': print_artist(),
		'title': print_title(),
		'date_and_time': print_date_time(),
		'nothing': print_nothing(),
		'track_time': print_track_time(),
		'track_time_and_number': print_track_time_and_number()
	}
	return switcher.get(info_text, fill_with_spaces("ERROR",n_cols))

def choose_icon(state):
	switcher = {
		'play': "\x00",
		'pause': "\x01",
		'stop': "\x02",
		'not_running': "\x03",
	}
	return switcher.get(state, " ")

def sec_to_min_and_sec(seconds):
	return (str('%d'%(int(seconds) / 60))+":"+str('%0.2d'%(int(seconds) % 60)))

######### BEGIN OF CODE ################################
##  init mpd-client
try:
	client = MPDClient()
	client.timeout=0.3
	client.connect("localhost", 6600)                               #
except Exception: # if reconnect isn't possible, client is not running  #
	print("mpd not avalible")
if use_state_icons=="yes":
	mylcd.lcd_load_custom_chars(user_icons)
try:
	while True:
		##################### RESET ALL VALUES ##########################################
		mpd_info = " "                                                                  #
		track_number = "0"                                                              #
		title = " "                                                                     #
		album = " "                                                                     #
		artist = " "                                                                    #
		track_time = "0.0/0.0"                                                          #
		#################################################################################

		########################## GET STATE ############################################
		try:                                                                            #
			client.ping() # test if client is up                                    #
			status=client.status()                                                  #
			state=status['state']                                                   #
			current_song_infos=client.currentsong()                                 #
		except Exception:                                                               #
			try: # if client is not connected, try to reconnect                     #
				client = MPDClient()                                            #
				client.timeout=0.3                                              #
				client.connect("localhost", 6600)                               #
				status=client.status()                                          #
				state=status['state']                                           #
				current_song_infos=client.currentsong()                         #
			except Exception: # if reconnect isn't possible, client is not running  #
				state="not_running"                                             #
		# it is running, get more details                                               #
		#################################################################################
		########### RESTART COUNTER, IF STATE CHANGED####################################
                                                                                                #
		if last_state != state: # if state changed, the scrolltext starts at position 0 #
			i_counter = 0                                                           #
			mylcd.backlight (1)
		#################################################################################

		########### GET INFOS, IF STATE IS "NOT_RUNNING" ################################
		if state == "not_running":                                                      #
			for row in range(n_rows):                                               #
				lines[row] = choose_line(info_at_lines_mpd_not_running [row])   #
		#################################################################################

		########### GET INFOS, IF STATE IS "STOP" #######################################
		elif state == "stop":                                                           #
			for row in range(n_rows):                                               #
				lines[row] = choose_line(info_at_lines_stop [row])              #
		#################################################################################


		else:
			########## GET MORE SONG-INFOS ####################################################
			# This section reads in certain album informations                                #
			#                                                                                 #
			## read in track number                                                           #
			try:                                                                              #
				track_number = current_song_infos['track']                                #
			except KeyError:                                                                  #
				track_number = "1"                                                        #
			## read in playlistlength                                                         #
			try:                                                                              #
				playlist_length = status['playlistlength']                                #
			except KeyError:                                                                  #
				playlist_length = "1"                                                     #
			## read in track title                                                            #
			try:                                                                              #
				title = current_song_infos['title']                                       #
				title = title.replace("\n", "").replace("Γ€", "\341").replace("ΓΆ", "\357").replace("ΓΌ", "\365").replace("ß", "\342").replace("Γ„", "\341").replace("Γ–", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125				#
			except KeyError:                                                                  #
				title = ""                                                                #
			## read in album title                                                            #
			try:                                                                              #
				album = current_song_infos['album']                                       #
				album = album.replace("\n", "").replace("Γ€", "\341").replace("ΓΆ", "\357").replace("ΓΌ", "\365").replace("ß", "\342").replace("Γ„", "\341").replace("Γ–", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125				#
			except KeyError:                                                                  #
				album = ""                                                                #
			## read in artist info                                                            #
			try:                                                                              #
				artist = current_song_infos['artist']                                     #
				artist = artist.replace("\n", "").replace("Γ€", "\341").replace("ΓΆ", "\357").replace("ΓΌ", "\365").replace("ß", "\342").replace("Γ„", "\341").replace("Γ–", "\357").replace("Ü", "\365") # weitere codes siehe https://www.mikrocontroller.net/topic/293125				#
			except KeyError:                                                                  #
				artist = ""                                                               #
			if (client.mpd_version) >= "0.20":
				try:                                                                              #
					elapsed=status['elapsed'].split(".")[0]                                   #
					duration=status['duration'].split(".")[0]                                 #
					track_time = sec_to_min_and_sec(elapsed)+"/"+sec_to_min_and_sec(duration) #
				except KeyError:                                                                  #
					track_time = ""                                                           #
			else:                                                                                     #
				track_time = subprocess.check_output('mpc | head -n2 | tail -n1 | sed "s/  \+/ /g" | cut -d" " -f3', shell=True)
				track_time = track_time.replace("\n", "")                                         #
			###########################################################################################

			############# RESET GLOBAL COUNTER, IF TITLE CHANGED ############################
			if last_title != title: # if title changed, the scrolltext starts at position 0 #
				i_counter = 0                                                           #
			#################################################################################

			########### GET INFOS, IF STATE IS "PAUSE" ######################################
			if state == "pause":                                                            #
				for row in range(n_rows):                                               #
					lines[row] = choose_line(info_at_lines_pause [row])             #
			#################################################################################

			########### GET INFOS, IF STATE IS "PLAY" #######################################
			if state == "play":                                                             #
				for row in range(n_rows):                                               #
					lines[row] = choose_line(info_at_lines_play [row])              #
			#################################################################################


		################## EXACT CYCLE TIME ##################################################
		current_time=time.time()                                                             #
		# calculate real sleep-time - if cycle to long, use 0.0                              #
		extra_sleep=(max(val_delay-(current_time-last_time),0.0)) # calculate real sleep     #
		time.sleep(extra_sleep) # time the display stays as is before re-running the loop    #
		current_time=time.time() # get current time after sleep                              #
		# print ("Cycle-time:"+str(current_time-last_time)) #only for debugging              #
		last_time=current_time # save time for next cycle                                    #
                ######################################################################################

		######################## ADD STATE ICONS #############################################
		## add blinking state icon in first row                                              #
		if use_state_icons=="yes":                                                           #
			if blinking_icons =="yes":                                                   #
				if i_counter%2==0:                                                   #
					icon=choose_icon(state)                                      #
				else:                                                                #
					icon=" "                                                     #
			else:                                                                        #
				icon=choose_icon(state)                                              #
			lines[0]= lines[0][:n_cols-2]+" "+icon                                       #
                ######################################################################################

		######################## DISPLAY OFF AFTER A WHILE ################################
		if (i_counter*val_delay)>=backlight_off_delay and backlight_off_while_waiting == "yes" and (state != "play" and state != "pause"):
			mylcd.backlight (0)
		else:
		######################################################################################
		######################## PRINT ALL CHANGES ON DISPLAY ################################
			for row in range(n_rows):                                                            #
				print_changes (lines[row],last_lines[row],row+1)                             #
		######################################################################################


		####################### UPDATE COUNTER ###############################################
		i_counter += 1                                                                       #
		if i_counter >= 65000:                                                               #
			i_counter = 1000  #<-- not 0, cause the display could be off                 #
		######################################################################################


		####################### REMIND STUFF FOR NEXT CYCLE #################################
		last_state=state                                                                     #
		last_title=title                                                                     #
		for row in range(n_rows):                                                            #
			last_lines[row]=lines[row]                                                   #
                ######################################################################################


except KeyboardInterrupt:
	lines[0]=print_date_time()
	lines[1]=print_nothing()
	if n_rows >= 3:
		lines[2]=print_nothing()
	if n_rows >= 4:
		lines[3]=print_nothing()
	for row in range(n_rows):
		print_changes (lines[row],last_lines[row],row+1)
	client.close()                     # send the close command
	client.disconnect()                # disconnect from the server

i2c_lcd_driver.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Original code found at:
# https://gist.github.com/DenisFromHR/cc863375a6e19dce359d

"""
Compiled, mashed and generally mutilated 2014-2015 by Denis Pleic
Made available under GNU GENERAL PUBLIC LICENSE
# Modified Python I2C library for Raspberry Pi
# as found on http://www.recantha.co.uk/blog/?p=4849
# Joined existing 'i2c_lib.py' and 'lcddriver.py' into a single library
# added bits and pieces from various sources
# By DenisFromHR (Denis Pleic)
# 2015-02-10, ver 0.1
"""

# i2c bus (0 -- original Pi, 1 -- Rev 2 Pi)
I2CBUS = 1

# LCD Address
ADDRESS = 0x27

import smbus
from time import sleep

class i2c_device:
   def __init__(self, addr, port=I2CBUS):
      self.addr = addr
      self.bus = smbus.SMBus(port)

# Write a single command
   def write_cmd(self, cmd):
      self.bus.write_byte(self.addr, cmd)
      sleep(0.0001)

# Write a command and argument
   def write_cmd_arg(self, cmd, data):
      self.bus.write_byte_data(self.addr, cmd, data)
      sleep(0.0001)

# Write a block of data
   def write_block_data(self, cmd, data):
      self.bus.write_block_data(self.addr, cmd, data)
      sleep(0.0001)

# Read a single byte
   def read(self):
      return self.bus.read_byte(self.addr)

# Read
   def read_data(self, cmd):
      return self.bus.read_byte_data(self.addr, cmd)

# Read a block of data
   def read_block_data(self, cmd):
      return self.bus.read_block_data(self.addr, cmd)


# commands
LCD_CLEARDISPLAY = 0x01
LCD_RETURNHOME = 0x02
LCD_ENTRYMODESET = 0x04
LCD_DISPLAYCONTROL = 0x08
LCD_CURSORSHIFT = 0x10
LCD_FUNCTIONSET = 0x20
LCD_SETCGRAMADDR = 0x40
LCD_SETDDRAMADDR = 0x80

# flags for display entry mode
LCD_ENTRYRIGHT = 0x00
LCD_ENTRYLEFT = 0x02
LCD_ENTRYSHIFTINCREMENT = 0x01
LCD_ENTRYSHIFTDECREMENT = 0x00

# flags for display on/off control
LCD_DISPLAYON = 0x04
LCD_DISPLAYOFF = 0x00
LCD_CURSORON = 0x02
LCD_CURSOROFF = 0x00
LCD_BLINKON = 0x01
LCD_BLINKOFF = 0x00

# flags for display/cursor shift
LCD_DISPLAYMOVE = 0x08
LCD_CURSORMOVE = 0x00
LCD_MOVERIGHT = 0x04
LCD_MOVELEFT = 0x00

# flags for function set
LCD_8BITMODE = 0x10
LCD_4BITMODE = 0x00
LCD_2LINE = 0x08
LCD_1LINE = 0x00
LCD_5x10DOTS = 0x04
LCD_5x8DOTS = 0x00

# flags for backlight control
LCD_BACKLIGHT = 0x08
LCD_NOBACKLIGHT = 0x00

En = 0b00000100 # Enable bit
Rw = 0b00000010 # Read/Write bit
Rs = 0b00000001 # Register select bit

class lcd:
   #initializes objects and lcd
   def __init__(self):
      self.lcd_device = i2c_device(ADDRESS)

      self.lcd_write(0x03)
      self.lcd_write(0x03)
      self.lcd_write(0x03)
      self.lcd_write(0x02)

      self.lcd_write(LCD_FUNCTIONSET | LCD_2LINE | LCD_5x8DOTS | LCD_4BITMODE)
      self.lcd_write(LCD_DISPLAYCONTROL | LCD_DISPLAYON)
      self.lcd_write(LCD_CLEARDISPLAY)
      self.lcd_write(LCD_ENTRYMODESET | LCD_ENTRYLEFT)
      sleep(0.2)


   # clocks EN to latch command
   def lcd_strobe(self, data):
      self.lcd_device.write_cmd(data | En | LCD_BACKLIGHT)
      sleep(.0005)
      self.lcd_device.write_cmd(((data & ~En) | LCD_BACKLIGHT))
      sleep(.0001)

   def lcd_write_four_bits(self, data):
      self.lcd_device.write_cmd(data | LCD_BACKLIGHT)
      self.lcd_strobe(data)

   # write a command to lcd
   def lcd_write(self, cmd, mode=0):
      self.lcd_write_four_bits(mode | (cmd & 0xF0))
      self.lcd_write_four_bits(mode | ((cmd << 4) & 0xF0))

   # write a character to lcd (or character rom) 0x09: backlight | RS=DR<
   # works!
   def lcd_write_char(self, charvalue, mode=1):
      self.lcd_write_four_bits(mode | (charvalue & 0xF0))
      self.lcd_write_four_bits(mode | ((charvalue << 4) & 0xF0))

   # put string function with optional char positioning
   def lcd_display_string(self, string, line=1, pos=0):
    if line == 1:
      pos_new = pos
    elif line == 2:
      pos_new = 0x40 + pos
    elif line == 3:
      pos_new = 0x14 + pos
    elif line == 4:
      pos_new = 0x54 + pos

    self.lcd_write(0x80 + pos_new)

    for char in string:
      self.lcd_write(ord(char), Rs)

   # clear lcd and set to home
   def lcd_clear(self):
      self.lcd_write(LCD_CLEARDISPLAY)
      self.lcd_write(LCD_RETURNHOME)

   # define backlight on/off (lcd.backlight(1); off= lcd.backlight(0)
   def backlight(self, state): # for state, 1 = on, 0 = off
      if state == 1:
         self.lcd_device.write_cmd(LCD_BACKLIGHT)
      elif state == 0:
         self.lcd_device.write_cmd(LCD_NOBACKLIGHT)

   # add custom characters (0 - 7)
   def lcd_load_custom_chars(self, fontdata):
      self.lcd_write(0x40);
      for char in fontdata:
         for line in char:
            self.lcd_write_char(line)   

Home

πŸ”₯ Version 3

Version 3 Pages

Nothing yet

🎢 Version 2

Version 2 Pages

Installation

Specials

RFID Reader

Sound card configurations

Hardware Buttons

Displays (LED, LCD, Matrix, etc.)

Hacks

Bluetooth

AirPlay

MPD tricks

For Developers

Clone this wiki locally