Merge pull request #7 from bkosciow/ili9486

Ili9486
This commit is contained in:
Bartosz 2017-05-21 13:04:38 +02:00 committed by GitHub
commit 5448753621
9 changed files with 186 additions and 11 deletions

View File

@ -9,6 +9,7 @@ RPi.GPIO.setmode(RPi.GPIO.BCM)
drv = SPI() drv = SPI()
lcd_tft = ILI9486(320, 480, drv) lcd_tft = ILI9486(320, 480, drv)
#lcd_tft.rotation = 270
lcd_tft.init() lcd_tft.init()
image_file = Image.open("assets/japan_temple_240x320.jpg") image_file = Image.open("assets/japan_temple_240x320.jpg")

View File

@ -0,0 +1,34 @@
import RPi.GPIO
import sys
import time
sys.path.append("../../")
from gfxlcd.driver.ili9486.spi import SPI
from gfxlcd.driver.ili9486.ili9486 import ILI9486
from gfxlcd.driver.xpt2046.xpt2046 import XPT2046
RPi.GPIO.setmode(RPi.GPIO.BCM)
lcd_tft = ILI9486(320, 480, SPI())
lcd_tft.init()
def callback(position):
print('(x,y)', position)
touch = XPT2046(320, 480, 17, callback, 7)
touch.correction = {
'x': -3394,#364,
'y': -3350,#430,
'ratio_x': 1,
'ratio_y': 1
}
touch.init()
while True:
try:
time.sleep(1)
except KeyboardInterrupt:
touch.close()
# RPi.GPIO.cleanup()

View File

@ -4,7 +4,7 @@ import RPi.GPIO
class AD7843(object): class AD7843(object):
"""AD7843 class""" """AD7843 class"""
def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=2000000): def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000):
self.width = width self.width = width
self.height = height self.height = height
self.spi = spidev.SpiDev() self.spi = spidev.SpiDev()
@ -52,11 +52,16 @@ class AD7843(object):
def get_position(self): def get_position(self):
"""get touch coords""" """get touch coords"""
buffer = [] buffer = []
while len(buffer) < 20: fuse = 40
while len(buffer) < 20 and fuse > 0:
# if self.cs_pin:
# RPi.GPIO.output(self.cs_pin, 0)
self.spi.xfer2([0xd0]) self.spi.xfer2([0xd0])
recvx = self.spi.readbytes(2) recvx = self.spi.readbytes(2)
self.spi.xfer2([0x90]) self.spi.xfer2([0x90])
recvy = self.spi.readbytes(2) recvy = self.spi.readbytes(2)
# if self.cs_pin:
# RPi.GPIO.output(self.cs_pin, 1)
tc_rx = recvx[0] << 5 tc_rx = recvx[0] << 5
tc_rx |= recvx[1] >> 3 tc_rx |= recvx[1] >> 3
@ -66,13 +71,17 @@ class AD7843(object):
pos_x = self.get_x(tc_rx) pos_x = self.get_x(tc_rx)
pos_y = self.get_y(tc_ry) pos_y = self.get_y(tc_ry)
print(pos_x, pos_y)
if 0 <= pos_x <= self.width and 0 <= pos_y <= self.height: if 0 <= pos_x <= self.width and 0 <= pos_y <= self.height:
buffer.append((pos_x, pos_y)) buffer.append((pos_x, pos_y))
fuse -= 1
return self._calculate_avr(buffer) return self._calculate_avr(buffer)
def _calculate_avr(self, points): def _calculate_avr(self, points):
"""calculate x,y by average""" """calculate x,y by average"""
if len(points) == 0:
return None
sum_x = 0 sum_x = 0
sum_y = 0 sum_y = 0
for point in points: for point in points:

View File

@ -6,7 +6,7 @@ from gfxlcd.abstract.chip import Chip
class ILI9486(Area, Chip): class ILI9486(Area, Chip):
"""Class for ILI9486 based LCD""" """Class for ILI9486 based LCD"""
rotations = {0: 0x80, 90: 0xf0, 180: 0x40, 270: 0x20} rotations = {0: 0x88, 90: 0xf8, 180: 0x48, 270: 0x28}
def __init__(self, width, height, driver): def __init__(self, width, height, driver):
Chip.__init__(self, width, height, driver, True) Chip.__init__(self, width, height, driver, True)
@ -36,27 +36,34 @@ class ILI9486(Area, Chip):
Chip.init(self) Chip.init(self)
self.driver.reset() self.driver.reset()
#Read Display MADCTL
self.driver.cmd(0x0b, None) self.driver.cmd(0x0b, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
#Sleep OUT
self.driver.cmd(0x11, None) self.driver.cmd(0x11, None)
#Interface Pixel Format
self.driver.cmd(0x3a, None) self.driver.cmd(0x3a, None)
self.driver.data(0x55, None) #0x66 self.driver.data(0x55, None) #0x66 5-6-5 / 55 6-6-6
#Memory Access Control (
self.driver.cmd(0x36, None) self.driver.cmd(0x36, None)
self.driver.data(self.rotations[self.rotation], None) self.driver.data(self.rotations[self.rotation], None)
#Power Control 3 (For Normal Mode)
self.driver.cmd(0xc2, None) self.driver.cmd(0xc2, None)
self.driver.data(0x44, None) self.driver.data(0x44, None)
#VCOM Control
self.driver.cmd(0xc5, None) self.driver.cmd(0xc5, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
#PGAMCTRL(Positive Gamma Control)
self.driver.cmd(0xe0, None) self.driver.cmd(0xe0, None)
self.driver.data(0x0F, None) self.driver.data(0x0F, None)
self.driver.data(0x1F, None) self.driver.data(0x1F, None)
@ -74,6 +81,7 @@ class ILI9486(Area, Chip):
self.driver.data(0x0D, None) self.driver.data(0x0D, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
#NGAMCTRL (Negative Gamma Correction)
self.driver.cmd(0xe1, None) self.driver.cmd(0xe1, None)
self.driver.data(0x0F, None) self.driver.data(0x0F, None)
self.driver.data(0x32, None) self.driver.data(0x32, None)
@ -91,6 +99,7 @@ class ILI9486(Area, Chip):
self.driver.data(0x20, None) self.driver.data(0x20, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
#Digital Gamma Control 1
self.driver.cmd(0xe2, None) self.driver.cmd(0xe2, None)
self.driver.data(0x0F, None) self.driver.data(0x0F, None)
self.driver.data(0x32, None) self.driver.data(0x32, None)
@ -108,7 +117,10 @@ class ILI9486(Area, Chip):
self.driver.data(0x20, None) self.driver.data(0x20, None)
self.driver.data(0x00, None) self.driver.data(0x00, None)
#Sleep OUT
self.driver.cmd(0x11, None) self.driver.cmd(0x11, None)
#Display ON
self.driver.cmd(0x29, None) self.driver.cmd(0x29, None)
def _set_area(self, pos_x1, pos_y1, pos_x2, pos_y2): def _set_area(self, pos_x1, pos_y1, pos_x2, pos_y2):

View File

@ -8,7 +8,7 @@ RPi.GPIO.setmode(RPi.GPIO.BCM)
class SPI(Driver): class SPI(Driver):
"""SPI communication driver""" """SPI communication driver"""
def __init__(self, spi=0, speed=2000000): def __init__(self, spi=0, speed=1000000):
self.pins = { self.pins = {
'CS': 8, 'CS': 8,
'RST': 25, 'RST': 25,
@ -60,6 +60,6 @@ class SPI(Driver):
RPi.GPIO.output(self.pins['RS'], 1) RPi.GPIO.output(self.pins['RS'], 1)
if self.pins['CS']: if self.pins['CS']:
RPi.GPIO.output(self.pins['CS'], 0) RPi.GPIO.output(self.pins['CS'], 0)
self.spi.xfer2([data]) self.spi.xfer2([data >> 8, data])
if self.pins['CS']: if self.pins['CS']:
RPi.GPIO.output(self.pins['CS'], 1) RPi.GPIO.output(self.pins['CS'], 1)

View File

@ -0,0 +1,2 @@
"""driver/xpt2046 module"""
__author__ = 'Bartosz Kosciow'

View File

@ -0,0 +1,95 @@
import spidev # pylint: disable=I0011,F0401
import RPi.GPIO
class XPT2046(object):
"""XPT2046 class"""
def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000):
self.width = width
self.height = height
self.spi = spidev.SpiDev()
self.spi.open(spi, 0)
self.spi.max_speed_hz = speed
self.spi.mode = 0
self.correction = {
'x': 364,
'y': 430,
'ratio_x': 14.35,
'ratio_y': 10.59
}
self.cs_pin = cs_pin
self.int_pin = int_pin
self.callback = callback
self.bouncetime = 500
def init(self):
"""some init functions"""
if self.int_pin:
RPi.GPIO.setup(self.int_pin, RPi.GPIO.IN)
RPi.GPIO.add_event_detect(
self.int_pin, RPi.GPIO.BOTH, callback=self._interrupt, bouncetime=self.bouncetime
)
if self.cs_pin:
RPi.GPIO.setup(self.cs_pin, RPi.GPIO.OUT)
RPi.GPIO.output(self.cs_pin, 1)
def get_x(self, value):
"""correct value to x"""
return int((value - self.correction['x']) / self.correction['ratio_x'])
def get_y(self, value):
"""correct value to y"""
return int((value - self.correction['y']) / self.correction['ratio_y'])
def _interrupt(self, channel):
"""call users callback"""
print('bb')
self.callback(self.get_position())
def get_position(self):
"""get touch coords"""
buffer = []
fuse = 40
while len(buffer) < 20 and fuse > 0:
if self.cs_pin:
RPi.GPIO.output(self.cs_pin, 0)
self.spi.xfer2([0xd0])
recvx = self.spi.readbytes(2)
self.spi.xfer2([0x90])
recvy = self.spi.readbytes(2)
if self.cs_pin:
RPi.GPIO.output(self.cs_pin, 1)
tc_rx = recvx[0] << 5
tc_rx |= recvx[1] >> 3
tc_ry = recvy[0] << 5
tc_ry |= recvy[1] >> 3
pos_x = self.get_x(tc_rx)
pos_y = self.get_y(tc_ry)
print(pos_x, pos_y)
if 0 <= pos_x <= self.width and 0 <= pos_y <= self.height:
buffer.append((pos_x, pos_y))
fuse -= 1
return self._calculate_avr(buffer)
def _calculate_avr(self, points):
"""calculate x,y by average"""
if len(points) == 0:
return None
sum_x = 0
sum_y = 0
for point in points:
sum_x += point[0]
sum_y += point[1]
return int(sum_x / len(points)), int(sum_y / len(points))
def close(self):
"""close action"""
if self.int_pin:
RPi.GPIO.remove_event_detect(self.int_pin)
self.spi.close()

View File

@ -5,14 +5,15 @@ Library for graphical LCDs for Python on Raspberry Pi. Creates a united interfac
Supported: Supported:
- ili325 via GPIO - ili9486 via SPI
- ili9325 via GPIO
- ssd1306 via SPI - ssd1306 via SPI
- nju6450 via GPIO - nju6450 via GPIO
And for touch panels: And for touch panels:
- ad7843 via SPI, uses irq or not - ad7843 via SPI, uses irq or not
- WIP ad7866/xpt2046
On NJU and SSD uses buffer to keep current content as help for page operations. On NJU and SSD uses buffer to keep current content as help for page operations.
@ -104,6 +105,15 @@ Custom pins:
o = ILI9325(240, 320, drv) o = ILI9325(240, 320, drv)
o.init() o.init()
## ILI9486
### SPI
from gfxlcd.driver.ili9486.spi import SPI
from gfxlcd.driver.ili9486.ili9486 import ILI9486
drv = SPI()
o = ILI9486(320, 480, drv)
o.rotation = 270
o.init()
Drawing functions Drawing functions
=== ===
@ -139,14 +149,14 @@ Touch panels
Constructor: Constructor:
AD7843(width, height, (T_INT), (callback)) AD7843(width, height, (int_pin), (callback), (cs_pin))
Can be used with T_INT Can be used with int_pin and cs_pin
def callback(position): def callback(position):
print('(x,y)', position) print('(x,y)', position)
touch = AD7843(240, 320, 26, callback) touch = AD7843(240, 320, 26, callback, 17)
touch.init() touch.init()
or without: or without:
@ -236,3 +246,15 @@ Default:
CS ------------------------ GND (always selected) (or connect to GPIO pin) CS ------------------------ GND (always selected) (or connect to GPIO pin)
REST ------------------------ G25 REST ------------------------ G25
LED_A ------------------------ 3.3 (can be connected to GPIO pin) LED_A ------------------------ 3.3 (can be connected to GPIO pin)
## ILI9486 (Waveshare)
### SPI
Default:
RPi Shield
G17 ----------------- TP_IRQ
G24 ----------------- RS
G25 ----------------- RST
G9 ----------------- LCD_CS
G7 ----------------- TP_CS