Merge pull request #8 from bkosciow/xpt2046

Xpt2046
This commit is contained in:
Bartosz 2017-05-22 16:12:48 +02:00 committed by GitHub
commit 57fdf26347
9 changed files with 156 additions and 147 deletions

View File

@ -6,6 +6,7 @@ class Chip(metaclass=abc.ABCMeta):
"""Chip class""" """Chip class"""
def __init__(self, width, height, driver, auto_flush): def __init__(self, width, height, driver, auto_flush):
self.options = {} self.options = {}
self.rotation = 0
self._width = width self._width = width
self._height = height self._height = height
self.driver = driver self.driver = driver
@ -14,12 +15,18 @@ class Chip(metaclass=abc.ABCMeta):
@property @property
def width(self): def width(self):
"""get width""" """get width"""
return self._width if self.rotation == 0 or self.rotation == 180:
return self._width
else:
return self._height
@property @property
def height(self): def height(self):
"""get height""" """get height"""
return self._height if self.rotation == 0 or self.rotation == 180:
return self._height
else:
return self._width
@abc.abstractmethod @abc.abstractmethod
def _converted_background_color(self): def _converted_background_color(self):

71
gfxlcd/abstract/touch.py Normal file
View File

@ -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

View File

@ -16,7 +16,7 @@ def callback(position):
print('(x,y)', position) print('(x,y)', position)
touch = AD7843(240, 320, 26, callback) touch = AD7843(240, 320, 26, callback)
touch.rotate = 180
touch.init() touch.init()
while True: while True:

View File

@ -15,13 +15,9 @@ lcd_tft.init()
def callback(position): def callback(position):
print('(x,y)', position) print('(x,y)', position)
touch = XPT2046(320, 480, 17, callback, 7) touch = XPT2046(480, 320, 17, callback, 7)
touch.correction = { #touch.rotate = 270
'x': -3394,#364,
'y': -3350,#430,
'ratio_x': 1,
'ratio_y': 1
}
touch.init() touch.init()
while True: while True:

View File

@ -4,18 +4,23 @@ import time
sys.path.append("../../") sys.path.append("../../")
from gfxlcd.driver.ili9325.gpio import GPIO as ILIGPIO from gfxlcd.driver.ili9325.gpio import GPIO as ILIGPIO
from gfxlcd.driver.ili9325.ili9325 import ILI9325 from gfxlcd.driver.ili9325.ili9325 import ILI9325
from gfxlcd.driver.xpt2046.xpt2046 import XPT2046
from gfxlcd.driver.ad7843.ad7843 import AD7843 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) 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() lcd_tft.init()
def callback(position): def callback(position):
print('(x,y)', position) print('(x,y)', position)
touch = AD7843(240, 320) #touch = AD7843(240, 320)
touch = XPT2046(320, 480)
touch.init() touch.init()

View File

@ -1,67 +1,49 @@
import spidev # pylint: disable=I0011,F0401
import RPi.GPIO import RPi.GPIO
from gfxlcd.abstract.touch import Touch
class AD7843(object): class AD7843(Touch):
"""AD7843 class""" """AD7843 class"""
def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000): def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000):
self.width = width super().__init__(width, height, int_pin, callback, cs_pin, spi, speed)
self.height = height
self.spi = spidev.SpiDev()
self.spi.open(spi, 0)
self.spi.max_speed_hz = speed
self.spi.mode = 0
self.correction = { self.correction = {
'x': 364, 'x': 364,
'y': 430, 'y': 430,
'ratio_x': 14.35, 'ratio_x': 14.35,
'ratio_y': 10.59 'ratio_y': 10.59
} }
self.cs_pin = cs_pin
self.int_pin = int_pin
self.callback = callback
self.bouncetime = 500
def init(self): def _get_xy(self, offset_x, offset_y):
"""some init functions""" """correct x and y"""
if self.int_pin: if self.rotate == 0:
RPi.GPIO.setup(self.int_pin, RPi.GPIO.IN) return int((offset_x - self.correction['x']) / self.correction['ratio_x']), \
RPi.GPIO.add_event_detect( int((offset_y - self.correction['y']) / self.correction['ratio_y'])
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): if self.rotate == 90:
"""correct value to x""" return self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']), \
return self.width - int((value - self.correction['x']) / self.correction['ratio_x']) int((offset_x - self.correction['x']) / self.correction['ratio_x'])
def get_y(self, value): if self.rotate == 180:
"""correct value to y""" return self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']), \
return self.height - int((value - self.correction['y']) / self.correction['ratio_y']) self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y'])
def _interrupt(self, channel): if self.rotate == 270:
"""call users callback""" return int((offset_y - self.correction['y']) / self.correction['ratio_y']), \
if self.cs_pin: self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x'])
RPi.GPIO.output(self.cs_pin, 0)
self.callback(self.get_position())
if self.cs_pin:
RPi.GPIO.output(self.cs_pin, 1)
def get_position(self): def get_position(self):
"""get touch coords""" """get touch coords"""
buffer = [] buffer = []
fuse = 40 fuse = 40
while len(buffer) < 20 and fuse > 0: while len(buffer) < 20 and fuse > 0:
# if self.cs_pin: if self.cs_pin:
# RPi.GPIO.output(self.cs_pin, 0) 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: if self.cs_pin:
# RPi.GPIO.output(self.cs_pin, 1) 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
@ -69,30 +51,9 @@ class AD7843(object):
tc_ry = recvy[0] << 5 tc_ry = recvy[0] << 5
tc_ry |= recvy[1] >> 3 tc_ry |= recvy[1] >> 3
pos_x = self.get_x(tc_rx) pos_x, pos_y = self._get_xy(tc_rx, tc_ry)
pos_y = self.get_y(tc_ry) if self._in_bounds(pos_x, pos_y):
print(pos_x, pos_y)
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 fuse -= 1
return self._calculate_avr(buffer) 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

@ -32,7 +32,6 @@ class ILI9325(Area, Chip):
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)
Area.__init__(self, driver) Area.__init__(self, driver)
self.rotation = 0
def _converted_background_color(self): def _converted_background_color(self):
"""color from 8-8-8 to 5-6-5""" """color from 8-8-8 to 5-6-5"""

View File

@ -11,7 +11,6 @@ class ILI9486(Area, Chip):
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)
Area.__init__(self, driver) Area.__init__(self, driver)
self.rotation = 0
def _converted_background_color(self): def _converted_background_color(self):
"""color from 8-8-8 to 5-6-5""" """color from 8-8-8 to 5-6-5"""

View File

@ -1,50 +1,35 @@
import spidev # pylint: disable=I0011,F0401
import RPi.GPIO import RPi.GPIO
from gfxlcd.abstract.touch import Touch
class XPT2046(object): class XPT2046(Touch):
"""XPT2046 class""" """XPT2046 class"""
def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000): def __init__(self, width, height, int_pin=None, callback=None, cs_pin=None, spi=0, speed=1000000):
self.width = width super().__init__(width, height, int_pin, callback, cs_pin, spi, speed)
self.height = height
self.spi = spidev.SpiDev()
self.spi.open(spi, 0)
self.spi.max_speed_hz = speed
self.spi.mode = 0
self.correction = { self.correction = {
'x': 364, 'x': 540,
'y': 430, 'y': 50,
'ratio_x': 14.35, 'ratio_x': 0.94,
'ratio_y': 10.59 'ratio_y': 1.26,
} }
self.cs_pin = cs_pin
self.int_pin = int_pin
self.callback = callback
self.bouncetime = 500
def init(self): def _get_xy(self, offset_x, offset_y):
"""some init functions""" """correct x and y"""
if self.int_pin: if self.rotate == 0:
RPi.GPIO.setup(self.int_pin, RPi.GPIO.IN) return int((offset_x - self.correction['x']) / self.correction['ratio_x']), \
RPi.GPIO.add_event_detect( self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y'])
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): if self.rotate == 90:
"""correct value to x""" return int((offset_y - self.correction['y']) / self.correction['ratio_y']), \
return int((value - self.correction['x']) / self.correction['ratio_x']) int((offset_x - self.correction['x']) / self.correction['ratio_x']),
def get_y(self, value): if self.rotate == 180:
"""correct value to y""" return self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x']), \
return int((value - self.correction['y']) / self.correction['ratio_y']) int((offset_y - self.correction['y']) / self.correction['ratio_y'])
def _interrupt(self, channel): if self.rotate == 270:
"""call users callback""" return self.height - int((offset_y - self.correction['y']) / self.correction['ratio_y']), \
print('bb') self.width - int((offset_x - self.correction['x']) / self.correction['ratio_x'])
self.callback(self.get_position())
def get_position(self): def get_position(self):
"""get touch coords""" """get touch coords"""
@ -53,43 +38,29 @@ class XPT2046(object):
while len(buffer) < 20 and fuse > 0: while len(buffer) < 20 and fuse > 0:
if self.cs_pin: if self.cs_pin:
RPi.GPIO.output(self.cs_pin, 0) RPi.GPIO.output(self.cs_pin, 0)
self.spi.xfer2([0xd0])
recvx = self.spi.readbytes(2) self.spi.xfer2([0x80 | 0x08 | 0x30])
self.spi.xfer2([0x90]) recv = self.spi.readbytes(1)
recvy = self.spi.readbytes(2) 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: if self.cs_pin:
RPi.GPIO.output(self.cs_pin, 1) RPi.GPIO.output(self.cs_pin, 1)
tc_rx = recvx[0] << 5 if tc_rz > 10:
tc_rx |= recvx[1] >> 3 pos_x, pos_y = self._get_xy(tc_rx, tc_ry)
if self._in_bounds(pos_x, pos_y):
tc_ry = recvy[0] << 5 buffer.append((pos_x, pos_y))
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 fuse -= 1
return self._calculate_avr(buffer) 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()