diff --git a/gfxlcd/abstract/chip.py b/gfxlcd/abstract/chip.py index 03bf3c0..699dd38 100644 --- a/gfxlcd/abstract/chip.py +++ b/gfxlcd/abstract/chip.py @@ -6,6 +6,7 @@ class Chip(metaclass=abc.ABCMeta): """Chip class""" def __init__(self, width, height, driver, auto_flush): self.options = {} + self.rotation = 0 self._width = width self._height = height self.driver = driver @@ -14,12 +15,18 @@ class Chip(metaclass=abc.ABCMeta): @property def width(self): """get width""" - return self._width + if self.rotation == 0 or self.rotation == 180: + return self._width + else: + return self._height @property def height(self): """get height""" - return self._height + if self.rotation == 0 or self.rotation == 180: + return self._height + else: + return self._width @abc.abstractmethod def _converted_background_color(self): diff --git a/gfxlcd/abstract/touch.py b/gfxlcd/abstract/touch.py new file mode 100644 index 0000000..e299262 --- /dev/null +++ b/gfxlcd/abstract/touch.py @@ -0,0 +1,71 @@ +"""Touch panel interface""" +import spidev # pylint: disable=I0011,F0401 +import abc +import RPi.GPIO + + +class Touch(metaclass=abc.ABCMeta): + """Touch 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.cs_pin = cs_pin + self.int_pin = int_pin + self.callback = callback + self.bouncetime = 500 + self.rotate = 0 + self.correction = { + 'x': 0, + 'y': 0, + 'ratio_x': 1, + 'ratio_y': 1, + } + + 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) + + @abc.abstractmethod + def get_position(self): + """returns pressed position""" + return + + def close(self): + """close action""" + if self.int_pin: + RPi.GPIO.remove_event_detect(self.int_pin) + self.spi.close() + + def _interrupt(self, channel): + """call users callback""" + self.callback(self.get_position()) + + 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 _in_bounds(self, pos_x, pos_y): + """checks if point is in range""" + if self.rotate == 0 or self.rotate == 180: + return 0 <= pos_x <= self.width and 0 <= pos_y <= self.height + else: + return 0 <= pos_y <= self.width and 0 <= pos_x <= self.height diff --git a/gfxlcd/demos/touch_240x320.py b/gfxlcd/demos/touch_240x320.py index a63dd56..9681fac 100644 --- a/gfxlcd/demos/touch_240x320.py +++ b/gfxlcd/demos/touch_240x320.py @@ -16,7 +16,7 @@ def callback(position): print('(x,y)', position) touch = AD7843(240, 320, 26, callback) - +touch.rotate = 180 touch.init() while True: diff --git a/gfxlcd/demos/touch_320x480.py b/gfxlcd/demos/touch_480x320.py similarity index 77% rename from gfxlcd/demos/touch_320x480.py rename to gfxlcd/demos/touch_480x320.py index 7fdac2d..d730194 100644 --- a/gfxlcd/demos/touch_320x480.py +++ b/gfxlcd/demos/touch_480x320.py @@ -15,13 +15,9 @@ 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 = XPT2046(480, 320, 17, callback, 7) +#touch.rotate = 270 + touch.init() while True: diff --git a/gfxlcd/demos/touch_loop.py b/gfxlcd/demos/touch_loop.py index a0bb1de..7bb4351 100644 --- a/gfxlcd/demos/touch_loop.py +++ b/gfxlcd/demos/touch_loop.py @@ -4,18 +4,23 @@ import time sys.path.append("../../") from gfxlcd.driver.ili9325.gpio import GPIO as ILIGPIO from gfxlcd.driver.ili9325.ili9325 import ILI9325 +from gfxlcd.driver.xpt2046.xpt2046 import XPT2046 from gfxlcd.driver.ad7843.ad7843 import AD7843 +from gfxlcd.driver.ili9486.spi import SPI +from gfxlcd.driver.ili9486.ili9486 import ILI9486 RPi.GPIO.setmode(RPi.GPIO.BCM) -lcd_tft = ILI9325(240, 320, ILIGPIO()) +# lcd_tft = ILI9325(240, 320, ILIGPIO()) +# lcd_tft.init() +lcd_tft = ILI9486(320, 480, SPI()) lcd_tft.init() - def callback(position): print('(x,y)', position) -touch = AD7843(240, 320) +#touch = AD7843(240, 320) +touch = XPT2046(320, 480) touch.init() diff --git a/gfxlcd/driver/ad7843/ad7843.py b/gfxlcd/driver/ad7843/ad7843.py index 5f5e9e1..1f516c9 100644 --- a/gfxlcd/driver/ad7843/ad7843.py +++ b/gfxlcd/driver/ad7843/ad7843.py @@ -1,67 +1,49 @@ -import spidev # pylint: disable=I0011,F0401 import RPi.GPIO +from gfxlcd.abstract.touch import Touch -class AD7843(object): +class AD7843(Touch): """AD7843 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 + super().__init__(width, height, int_pin, callback, cs_pin, spi, speed) 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_xy(self, offset_x, offset_y): + """correct x and y""" + if self.rotate == 0: + return int((offset_x - self.correction['x']) / self.correction['ratio_x']), \ + int((offset_y - self.correction['y']) / self.correction['ratio_y']) - def get_x(self, value): - """correct value to x""" - return self.width - int((value - self.correction['x']) / self.correction['ratio_x']) + if self.rotate == 90: + return self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']), \ + int((offset_x - self.correction['x']) / self.correction['ratio_x']) - def get_y(self, value): - """correct value to y""" - return self.height - int((value - self.correction['y']) / self.correction['ratio_y']) + if self.rotate == 180: + return self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']), \ + self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']) - def _interrupt(self, channel): - """call users callback""" - if self.cs_pin: - RPi.GPIO.output(self.cs_pin, 0) - self.callback(self.get_position()) - if self.cs_pin: - RPi.GPIO.output(self.cs_pin, 1) + if self.rotate == 270: + return int((offset_y - self.correction['y']) / self.correction['ratio_y']), \ + self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']) 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) + 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) + if self.cs_pin: + RPi.GPIO.output(self.cs_pin, 1) tc_rx = recvx[0] << 5 tc_rx |= recvx[1] >> 3 @@ -69,30 +51,9 @@ class AD7843(object): 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: + pos_x, pos_y = self._get_xy(tc_rx, tc_ry) + if self._in_bounds(pos_x, pos_y): 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() - diff --git a/gfxlcd/driver/ili9325/ili9325.py b/gfxlcd/driver/ili9325/ili9325.py index 27562b5..cf37742 100644 --- a/gfxlcd/driver/ili9325/ili9325.py +++ b/gfxlcd/driver/ili9325/ili9325.py @@ -32,7 +32,6 @@ class ILI9325(Area, Chip): def __init__(self, width, height, driver): Chip.__init__(self, width, height, driver, True) Area.__init__(self, driver) - self.rotation = 0 def _converted_background_color(self): """color from 8-8-8 to 5-6-5""" diff --git a/gfxlcd/driver/ili9486/ili9486.py b/gfxlcd/driver/ili9486/ili9486.py index c7c3d72..cdcafb6 100644 --- a/gfxlcd/driver/ili9486/ili9486.py +++ b/gfxlcd/driver/ili9486/ili9486.py @@ -11,7 +11,6 @@ class ILI9486(Area, Chip): def __init__(self, width, height, driver): Chip.__init__(self, width, height, driver, True) Area.__init__(self, driver) - self.rotation = 0 def _converted_background_color(self): """color from 8-8-8 to 5-6-5""" diff --git a/gfxlcd/driver/xpt2046/xpt2046.py b/gfxlcd/driver/xpt2046/xpt2046.py index 1235b39..44d68a6 100644 --- a/gfxlcd/driver/xpt2046/xpt2046.py +++ b/gfxlcd/driver/xpt2046/xpt2046.py @@ -1,50 +1,35 @@ -import spidev # pylint: disable=I0011,F0401 import RPi.GPIO +from gfxlcd.abstract.touch import Touch -class XPT2046(object): +class XPT2046(Touch): """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 + super().__init__(width, height, int_pin, callback, cs_pin, spi, speed) self.correction = { - 'x': 364, - 'y': 430, - 'ratio_x': 14.35, - 'ratio_y': 10.59 + 'x': 540, + 'y': 50, + 'ratio_x': 0.94, + 'ratio_y': 1.26, } - 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_xy(self, offset_x, offset_y): + """correct x and y""" + if self.rotate == 0: + return int((offset_x - self.correction['x']) / self.correction['ratio_x']), \ + self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']) - def get_x(self, value): - """correct value to x""" - return int((value - self.correction['x']) / self.correction['ratio_x']) + if self.rotate == 90: + return int((offset_y - self.correction['y']) / self.correction['ratio_y']), \ + int((offset_x - 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']) + if self.rotate == 180: + return self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']), \ + int((offset_y - self.correction['y']) / self.correction['ratio_y']) - def _interrupt(self, channel): - """call users callback""" - print('bb') - self.callback(self.get_position()) + if self.rotate == 270: + return self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']), \ + self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']) def get_position(self): """get touch coords""" @@ -53,43 +38,29 @@ class XPT2046(object): 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) + + self.spi.xfer2([0x80 | 0x08 | 0x30]) + recv = self.spi.readbytes(1) + tc_rz = recv[0] & 0x7f + + self.spi.xfer2([0x80 | 0x08 | 0x40]) + recv = self.spi.readbytes(1) + tc_rz += (255-recv[0] & 0x7f) + + self.spi.xfer2([0x80 | 0x10]) + recv = self.spi.readbytes(2) + tc_rx = 1023-((recv[0] << 2)|(recv[1] >> 6)) + + self.spi.xfer2([0x80 | 0x50]) + recv = self.spi.readbytes(2) + tc_ry = ((recv[0] << 2)|(recv[1] >> 6)) 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)) + if tc_rz > 10: + pos_x, pos_y = self._get_xy(tc_rx, tc_ry) + if self._in_bounds(pos_x, pos_y): + 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() -