From ba02d19b3a96ccaecd8f75a8f840defe42f2e9b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Ko=C5=9Bci=C3=B3w?= Date: Thu, 18 May 2017 21:04:16 +0200 Subject: [PATCH 1/3] command sesc --- gfxlcd/driver/ili9486/ili9486.py | 14 +++++++++++++- gfxlcd/driver/ili9486/spi.py | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/gfxlcd/driver/ili9486/ili9486.py b/gfxlcd/driver/ili9486/ili9486.py index 58ed1c3..9a3b63f 100644 --- a/gfxlcd/driver/ili9486/ili9486.py +++ b/gfxlcd/driver/ili9486/ili9486.py @@ -36,27 +36,34 @@ class ILI9486(Area, Chip): Chip.init(self) self.driver.reset() + #Read Display MADCTL self.driver.cmd(0x0b, None) self.driver.data(0x00, None) self.driver.data(0x00, None) + #Sleep OUT self.driver.cmd(0x11, None) + #Interface Pixel Format 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.data(self.rotations[self.rotation], None) + #Power Control 3 (For Normal Mode) self.driver.cmd(0xc2, None) self.driver.data(0x44, None) + #VCOM Control 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) + #PGAMCTRL(Positive Gamma Control) self.driver.cmd(0xe0, None) self.driver.data(0x0F, None) self.driver.data(0x1F, None) @@ -74,6 +81,7 @@ class ILI9486(Area, Chip): self.driver.data(0x0D, None) self.driver.data(0x00, None) + #NGAMCTRL (Negative Gamma Correction) self.driver.cmd(0xe1, None) self.driver.data(0x0F, None) self.driver.data(0x32, None) @@ -91,6 +99,7 @@ class ILI9486(Area, Chip): self.driver.data(0x20, None) self.driver.data(0x00, None) + #Digital Gamma Control 1 self.driver.cmd(0xe2, None) self.driver.data(0x0F, None) self.driver.data(0x32, None) @@ -108,7 +117,10 @@ class ILI9486(Area, Chip): self.driver.data(0x20, None) self.driver.data(0x00, None) + #Sleep OUT self.driver.cmd(0x11, None) + + #Display ON self.driver.cmd(0x29, None) def _set_area(self, pos_x1, pos_y1, pos_x2, pos_y2): diff --git a/gfxlcd/driver/ili9486/spi.py b/gfxlcd/driver/ili9486/spi.py index fab722c..ddfb615 100644 --- a/gfxlcd/driver/ili9486/spi.py +++ b/gfxlcd/driver/ili9486/spi.py @@ -8,7 +8,7 @@ RPi.GPIO.setmode(RPi.GPIO.BCM) class SPI(Driver): """SPI communication driver""" - def __init__(self, spi=0, speed=2000000): + def __init__(self, spi=0, speed=1000000): self.pins = { 'CS': 8, 'RST': 25, From e2e8c9603df3e37288970649d6a13cd482d0d690 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Ko=C5=9Bci=C3=B3w?= Date: Fri, 19 May 2017 16:52:00 +0200 Subject: [PATCH 2/3] fix colors separate touch classes --- gfxlcd/demos/ili9486_image.py | 1 + gfxlcd/demos/{touch.py => touch_240x320.py} | 0 gfxlcd/demos/touch_320x480.py | 34 ++++++++ gfxlcd/driver/ad7843/ad7843.py | 13 ++- gfxlcd/driver/ili9486/ili9486.py | 2 +- gfxlcd/driver/ili9486/spi.py | 2 +- gfxlcd/driver/xpt2046/__init__.py | 2 + gfxlcd/driver/xpt2046/xpt2046.py | 95 +++++++++++++++++++++ 8 files changed, 145 insertions(+), 4 deletions(-) rename gfxlcd/demos/{touch.py => touch_240x320.py} (100%) create mode 100644 gfxlcd/demos/touch_320x480.py create mode 100644 gfxlcd/driver/xpt2046/__init__.py create mode 100644 gfxlcd/driver/xpt2046/xpt2046.py diff --git a/gfxlcd/demos/ili9486_image.py b/gfxlcd/demos/ili9486_image.py index 5c957fd..47dea5a 100644 --- a/gfxlcd/demos/ili9486_image.py +++ b/gfxlcd/demos/ili9486_image.py @@ -9,6 +9,7 @@ RPi.GPIO.setmode(RPi.GPIO.BCM) drv = SPI() lcd_tft = ILI9486(320, 480, drv) +#lcd_tft.rotation = 270 lcd_tft.init() image_file = Image.open("assets/japan_temple_240x320.jpg") diff --git a/gfxlcd/demos/touch.py b/gfxlcd/demos/touch_240x320.py similarity index 100% rename from gfxlcd/demos/touch.py rename to gfxlcd/demos/touch_240x320.py diff --git a/gfxlcd/demos/touch_320x480.py b/gfxlcd/demos/touch_320x480.py new file mode 100644 index 0000000..7fdac2d --- /dev/null +++ b/gfxlcd/demos/touch_320x480.py @@ -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() + diff --git a/gfxlcd/driver/ad7843/ad7843.py b/gfxlcd/driver/ad7843/ad7843.py index 6e107fe..5f5e9e1 100644 --- a/gfxlcd/driver/ad7843/ad7843.py +++ b/gfxlcd/driver/ad7843/ad7843.py @@ -4,7 +4,7 @@ import RPi.GPIO class AD7843(object): """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.height = height self.spi = spidev.SpiDev() @@ -52,11 +52,16 @@ class AD7843(object): def get_position(self): """get touch coords""" 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]) 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 @@ -66,13 +71,17 @@ class AD7843(object): 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: diff --git a/gfxlcd/driver/ili9486/ili9486.py b/gfxlcd/driver/ili9486/ili9486.py index 9a3b63f..c7c3d72 100644 --- a/gfxlcd/driver/ili9486/ili9486.py +++ b/gfxlcd/driver/ili9486/ili9486.py @@ -6,7 +6,7 @@ from gfxlcd.abstract.chip import Chip class ILI9486(Area, Chip): """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): Chip.__init__(self, width, height, driver, True) diff --git a/gfxlcd/driver/ili9486/spi.py b/gfxlcd/driver/ili9486/spi.py index ddfb615..ed7afc9 100644 --- a/gfxlcd/driver/ili9486/spi.py +++ b/gfxlcd/driver/ili9486/spi.py @@ -60,6 +60,6 @@ class SPI(Driver): RPi.GPIO.output(self.pins['RS'], 1) if self.pins['CS']: RPi.GPIO.output(self.pins['CS'], 0) - self.spi.xfer2([data]) + self.spi.xfer2([data >> 8, data]) if self.pins['CS']: RPi.GPIO.output(self.pins['CS'], 1) diff --git a/gfxlcd/driver/xpt2046/__init__.py b/gfxlcd/driver/xpt2046/__init__.py new file mode 100644 index 0000000..d64e5e9 --- /dev/null +++ b/gfxlcd/driver/xpt2046/__init__.py @@ -0,0 +1,2 @@ +"""driver/xpt2046 module""" +__author__ = 'Bartosz Kosciow' diff --git a/gfxlcd/driver/xpt2046/xpt2046.py b/gfxlcd/driver/xpt2046/xpt2046.py new file mode 100644 index 0000000..1235b39 --- /dev/null +++ b/gfxlcd/driver/xpt2046/xpt2046.py @@ -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() + From 9dad2852a06c865f8ce1405408406a7b1e3b5bc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Ko=C5=9Bci=C3=B3w?= Date: Sun, 21 May 2017 13:01:52 +0200 Subject: [PATCH 3/3] doc --- readme.md | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 18c87b4..e04874c 100644 --- a/readme.md +++ b/readme.md @@ -5,14 +5,15 @@ Library for graphical LCDs for Python on Raspberry Pi. Creates a united interfac Supported: -- ili325 via GPIO +- ili9486 via SPI +- ili9325 via GPIO - ssd1306 via SPI - nju6450 via GPIO And for touch panels: - 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. @@ -104,6 +105,15 @@ Custom pins: o = ILI9325(240, 320, drv) 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 === @@ -139,14 +149,14 @@ Touch panels 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): print('(x,y)', position) - touch = AD7843(240, 320, 26, callback) + touch = AD7843(240, 320, 26, callback, 17) touch.init() or without: @@ -236,3 +246,15 @@ Default: CS ------------------------ GND (always selected) (or connect to GPIO pin) REST ------------------------ G25 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 +