1
Graphic LCDs / Graphic Issues with Grayscale
« on: April 10, 2015, 02:20:40 PM »
Hi again-
I've got connection and control with my RPi, but something is not right. Most likely it is my implementation of the grayscale. I adapted your examples, but when I send data (each byte 4x) I get a line through the display on the 3rd pixel level (0x04). Sending the data only once moves the line to the first pixel (0x01). Setting all the data to 0xFF shows it is data independent; only the number of times sent affects the lines' locations. Also, the "dark" pixels are not that dark, but the lines are.
I have pictures of the display with the three types of data, but have nowhere to upload it so I can link it.
The code (Python) is below. "#" are comments:
The "I.write(...)" lines at the bottom are the different data trials I have used. The current selected outputs 0xFF four times per byte. Real data are in the lines with the "RC"
Please help me understand how the grayscale SHOULD be used, as I obviously am doing something wrong.
Thanks!
I've got connection and control with my RPi, but something is not right. Most likely it is my implementation of the grayscale. I adapted your examples, but when I send data (each byte 4x) I get a line through the display on the 3rd pixel level (0x04). Sending the data only once moves the line to the first pixel (0x01). Setting all the data to 0xFF shows it is data independent; only the number of times sent affects the lines' locations. Also, the "dark" pixels are not that dark, but the lines are.
I have pictures of the display with the three types of data, but have nowhere to upload it so I can link it.

The code (Python) is below. "#" are comments:
Code: [Select]
[font=courier]import time
import smbus
bus = smbus.SMBus(1) # Bus declaration
#=============================================================================
# I2C
# I2C communication class
# I2C.write(Dev, Length, Reg, Val) - writes to a device via I2C
# I2C.read(Dev, Length, Reg) - reads from a device via I2C
#
# Dev - Device I2C address, Length - "Block"|"Word"|"Byte"|"None"
# Reg - Register address for device, Val - Value to be set in the Dev/Reg
# http://erazor-zone.de/wiki:linux:python:smbus:doc
# https://www.kernel.org/doc/Documentation/i2c/smbus-protocol
#=============================================================================
class I2C(object):
"""I2C Communication Class"""
#-----------------------------------------------------------------------------
# I2C.write
def write(self, Dev, Length, Reg, Val):
if Length == "Block": # Block - uses addressed reg, array
bus.write_block_data(Dev, Reg, Val)
elif Length == "Word": # Word - uses addressed reg, 16-bit
bus.write_word_data(Dev, Reg, Val)
elif Length == "Byte": # Byte - uses addressed reg, 8-bit
bus.write_byte_data(Dev, Reg, Val)
elif Length == "None": # None - no addressed reg, 8-bit
bus.write_quick(Dev)
return -1
#-----------------------------------------------------------------------------
# I2C.read
def read(self, Dev, Length, Reg):
if Length == "Block": # Block - uses addressed reg, array
value = bus.read_block_data(Dev, Reg)
elif Length == "Word": # Word - uses addressed reg, 16-bit
value = bus.read_word_data(Dev, Reg)
elif Length == "Byte": # Byte - uses addressed reg, 8-bit
value = bus.read_byte_data(Dev, Reg)
elif Length == "None": # None - no addressed reg, 8-bit
value = bus.read_byte(Dev)
return value
#=============================================================================
# Main
RC = [0 for x in range(13)] # Initializes RC
I = I2C()
Adr = 0x3F
Com = 0x00
Dat = 0x40
Page = 0xB0
I.write(Adr, "Block", Com, [0xE2, 0xAD, 0xA6]) # Reset, Display off, Rev off
I.write(Adr, "Block", Com, [0x48, 0x00, 0xA1, 0xC0, 0x44, 0x00, 0xAB, \
0x26, 0x81, 0x20, 0x56, 0x64])
# 64 A0/A1 C8/C0
# 1C/20
# ^--- Partial disp duty cycle & data, ADC, SHL, Com0 reg & data, Osc on
# Vreg register, Elec Vol & data, LCD Bias, DC/DC
time.sleep(2)
I.write(Adr, "Block", Com, [0x2C, 0x66]) # Pwr ctrl, DC/DC
time.sleep(2)
I.write(Adr, "Block", Com, [0x2E, 0x67]) # Pwr ctrl, DC/DC
time.sleep(2)
I.write(Adr, "Block", Com, [0x2F, 0xF3, 0x00, 0x96, 0x38, 0x75, 0x97])
# ^--- Pwr ctrl, Prw save & data, FRC/PWM/EXT, Mode & data, FRC/PWM/EXT
# Fill out grayscale table
i = 0
j = 0
gs = [0x00, 0x06, 0x0B, 0x10, 0x15, 0x1A, 0x1E, 0x23, 0x27, 0x2B, \
0x2F, 0x32, 0x35, 0x38, 0x3A, 0x3C] # Grayscale values
for x in range(0x80, 0xC0): # Grayscale addresses
i = i + 1
I.write(0x3F, "Block", Com, [x, gs[j]]) # Send grayscale values
if (i % 4) == 0: # Increment gs value every 4th
j = j + 1
I.write(Adr, "Block", Com, [0x38, 0x74]) # Mode & data
# Open text file, read
text_file = open("/home/pi/Desktop/Python_Programs/Display1.txt", "r")
i = 0 # Line counter init
for line in text_file: # Read each line in
thing = (line.replace("\n","")).split("\t") # Remove \n, split on tabs
hasdata = 0 # Init hasdata to 0
for atom in thing: # For each datum..
if atom != '00': # .. if real data..
hasdata = 1 # .. flag hasdata
break # .. cancel loop
if hasdata == 1: # If line contains data..
RC[i] = thing # .. Add line to RC
i = i + 1 # .. Inc line count
text_file.close() # Close file
for i in range(13): # For all rows
for j in range(160): # For all columns
# Set row, column
I.write(Adr, "Block", Com, [Page, 0x10 + j//16, j%16])
# Write data
I.write(Adr, "Block", Dat, [0xFF, 0xFF, 0xFF, 0xFF])
# I.write(Adr, "Block", Dat, [0x00, 0x00, 0x00, 0x00])
# I.write(Adr, "Block", Dat, [int(RC[i][j],16)])
# I.write(Adr, "Block", Dat, [int(RC[i][j],16), int(RC[i][j],16), \
# int(RC[i][j],16), int(RC[i][j],16)])
Page = Page + 1 # Increment page
I.write(Adr, "Block", Com, [0xAF])[/font]
The "I.write(...)" lines at the bottom are the different data trials I have used. The current selected outputs 0xFF four times per byte. Real data are in the lines with the "RC"
Please help me understand how the grayscale SHOULD be used, as I obviously am doing something wrong.
Thanks!