init afer lib extraction from Doton project

This commit is contained in:
Bartosz Kościów 2017-04-24 21:52:38 +02:00
commit 95f2b8c7c9
35 changed files with 1621 additions and 0 deletions

18
.gitignore vendored Normal file
View File

@ -0,0 +1,18 @@
.idea
.vs
*.pyproj
*.sln
*.pyc
*.pyo
*.bak
env/
venv/
ENV/
build/
dist/
sdist/
*.egg-info/
*.egg
.python-version
__pycache__/
.tox

3
.pylintrc Normal file
View File

@ -0,0 +1,3 @@
[REPORTS]
reports=yes
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}

2
CHANGELOG.txt Normal file
View File

@ -0,0 +1,2 @@
0.1.0
- extract library from Doton project

3
CONTRIBUTORS.txt Normal file
View File

@ -0,0 +1,3 @@
List of contributors:
- Bartosz Kościów - kosci1@gmail.com

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
Copyright (c) 2017 Bartosz Kościów <kosci1@gmail.com>
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

5
MANIFEST.in Normal file
View File

@ -0,0 +1,5 @@
include CONTRIBUTORS.txt
include LICENSE
include readme.md
include CHANGELOG.txt

1
gfxlcd/__init__.py Normal file
View File

@ -0,0 +1 @@
__author__ = 'kosci'

View File

@ -0,0 +1 @@
__author__ = 'kosci'

95
gfxlcd/abstract/chip.py Normal file
View File

@ -0,0 +1,95 @@
import abc
class Chip(metaclass=abc.ABCMeta):
def __init__(self, width, height, driver, auto_flush):
self.options = {}
self._width = width
self._height = height
self.driver = driver
self.options['auto_flush'] = auto_flush
@property
def width(self):
"""get width"""
return self._width
@property
def height(self):
"""get height"""
return self._height
@abc.abstractmethod
def _converted_background_color(self):
"""convert RGB background to available color"""
pass
@abc.abstractmethod
def _converted_color(self):
"""convert RGB color to available color"""
pass
@property
def color(self):
return self.options['color']
@color.setter
def color(self, rgb):
self.options['color'] = {
'R': rgb[0], 'G': rgb[1], 'B': rgb[2]
}
@property
def background_color(self):
return self.options['background_color']
@background_color.setter
def background_color(self, rgb):
self.options['background_color'] = {
'R': rgb[0], 'G': rgb[1], 'B': rgb[2]
}
@property
def auto_flush(self):
"""get auto_flush"""
return self.options['auto_flush']
@auto_flush.setter
def auto_flush(self, value):
"""set auto_flush"""
self.options['auto_flush'] = bool(value)
@abc.abstractmethod
def init(self):
"""init a chipset"""
pass
@abc.abstractmethod
def draw_pixel(self, x, y):
"""draw a pixel at x,y"""
pass
@abc.abstractmethod
def draw_line(self, x1, y1, x2, y2):
"""draw a line from point x1,y1 to x2,y2"""
pass
@abc.abstractmethod
def draw_rect(self, x1, y1, x2, y2):
"""draw a rectangle"""
pass
@abc.abstractmethod
def draw_circle(self, x, y, r):
"""draw a circle"""
pass
@abc.abstractmethod
def draw_arc(self, x, y, radius, start, end):
"""draw an arc"""
pass
@abc.abstractmethod
def fill_rect(self, x1, y1, x2, y2):
"""draw a filled rectangle"""
pass

23
gfxlcd/abstract/driver.py Normal file
View File

@ -0,0 +1,23 @@
import abc
class Driver(metaclass=abc.ABCMeta):
@abc.abstractmethod
def init(self):
"""initialize a device"""
pass
@abc.abstractmethod
def reset(self):
"""resets a device"""
pass
@abc.abstractmethod
def cmd(self, data, enable):
"""sends command to device"""
pass
@abc.abstractmethod
def data(self, data, enable):
"""sends data to device"""
pass

62
gfxlcd/demos/ili.py Normal file
View File

@ -0,0 +1,62 @@
import sys
sys.path.append("../../")
from gfxlcd.driver.ili9325.gpio import GPIO
from gfxlcd.driver.ili9325.ili9325 import ILI9325
def hole(x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
def draw_net(o):
s = 0
while s < o.width-1:
o.draw_line(s, 0, s, o.height-1)
s += 10
s = 0
while s < o.height-1:
o.draw_line(0, s, o.width-1, s)
s += 10
drv = GPIO()
o = ILI9325(240, 320, drv)
o.init()
# for _ in range(0, 50):
# hole(random.randint(2,o.width-3), random.randint(2,o.height-3))
#
# draw_net(o)
o.color = (10, 230, 200)
o.draw_circle(60, 15, 15)
o.color = (0, 250, 20)
o.draw_circle(53, 10, 3)
o.draw_circle(67, 10, 3)
o.color = (250, 150, 20)
o.draw_arc(60, 15, 10, 45, 135)
o.color = (10, 230, 200)
o.draw_line(60, 12, 57, 17)
o.draw_line(60, 12, 63, 17)
o.draw_arc(60, 15, 3, 45, 135)
o.background_color = (200, 0, 120)
o.fill_rect(2, 2, 42, 29)
o.background_color = (20, 200, 120)
o.fill_rect(119, 2, 109, 12)
o.fill_rect(119, 17, 109, 19)
o.background_color = (255, 255, 255)
o.fill_rect(77, 6, 105, 16)
o.background_color = (255, 0, 0)
o.fill_rect(77, 16, 105, 25)

98
gfxlcd/demos/ili_2.py Normal file
View File

@ -0,0 +1,98 @@
import RPi.GPIO
import sys
RPi.GPIO.setmode(RPi.GPIO.BCM)
sys.path.append("../../")
from gfxlcd.driver.ili9325.gpio import GPIO as ILIGPIO
from gfxlcd.driver.ili9325.ili9325 import ILI9325
import random
def hole(o, x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
def draw_points(o):
for _ in range(0, 50):
hole(o, random.randint(2,o.width - 10), random.randint(2,o.height-10))
def draw_net(o):
s = 0
while s < o.width-1:
o.draw_line(s, 0, s, o.height-1)
s += 10
s = 0
while s < o.height-1:
o.draw_line(0, s, o.width-1, s)
s += 10
lcd_tft = ILI9325(240, 320, ILIGPIO())
lcd_tft.init()
# bypass of missing +3v line to power backlight
LED = 6
RPi.GPIO.setup(LED, RPi.GPIO.OUT)
RPi.GPIO.output(LED, 1)
lcd_tft.background_color = (255, 255, 255)
lcd_tft.fill_rect(0, 0, 240, 320)
lcd_tft.color = (0, 255, 1)
lcd_tft.draw_circle(79, 99, 40)
lcd_tft.draw_circle(60, 80, 7)
lcd_tft.draw_circle(100, 80, 7)
lcd_tft.draw_line(79, 90, 70, 100)
lcd_tft.draw_line(79, 90, 88, 100)
lcd_tft.draw_arc(79, 91, 12, 45, 135)
lcd_tft.color = (255, 0, 0)
lcd_tft.draw_arc(79, 90, 40, 45, 135)
lcd_tft.draw_line(51, 117, 105, 117)
lcd_tft.background_color = (255, 127, 127)
lcd_tft.fill_rect(75, 140, 83, 220)
lcd_tft.draw_line(75, 220, 65, 280)
lcd_tft.draw_line(83, 220, 93, 280)
lcd_tft.draw_line(83, 150, 130, 150)
lcd_tft.background_color = (0, 255, 0)
lcd_tft.fill_rect(0, 0, 122, 32)
lcd_tft.color = (0, 0, 0)
lcd_tft.background_color = (0, 0, 0)
lcd_tft.draw_circle(60, 15, 15)
lcd_tft.draw_circle(53, 10, 3)
lcd_tft.draw_circle(67, 10, 3)
lcd_tft.draw_arc(60, 15, 10, 45, 135)
lcd_tft.draw_line(60, 12, 57, 17)
lcd_tft.draw_line(60, 12, 63, 17)
lcd_tft.draw_arc(60, 15, 3, 45, 135)
lcd_tft.fill_rect(2, 2, 42, 29)
lcd_tft.fill_rect(119, 2, 109, 12)
lcd_tft.fill_rect(119, 17, 109, 19)
lcd_tft.draw_rect(77, 6, 105, 16)
lcd_tft.fill_rect(77, 16, 105, 25)
lcd_tft.background_color = (0, 0, 0)
lcd_tft.fill_rect(100, 200, 222, 264)
lcd_tft.color = (43, 212, 255)
lcd_tft.background_color = (43, 212, 255)
lcd_tft.draw_circle(131, 232, 31)
lcd_tft.draw_circle(119, 222, 7)
lcd_tft.draw_circle(143, 222, 7)
lcd_tft.draw_arc(131, 232, 20, 45, 135)
lcd_tft.draw_line(131, 227, 127, 238)
lcd_tft.draw_line(131, 227, 135, 238)
lcd_tft.draw_arc(131, 235, 5, 45, 135)
lcd_tft.fill_rect(195, 204, 205, 210)
lcd_tft.draw_rect(180, 210, 220, 225)
lcd_tft.fill_rect(180, 226, 220, 259)

31
gfxlcd/demos/nju.py Normal file
View File

@ -0,0 +1,31 @@
import random
from gfxlcd.driver.nju6450.gpio import GPIO
from gfxlcd.driver.nju6450.nju6450 import NJU6450
def hole(x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
drv = GPIO()
o = NJU6450(122, 32, drv)
o.init()
o.auto_flush = False
for _ in range(0, 50):
hole(random.randint(2, 115), random.randint(2, 25))
hole(10, 10)
hole(15, 13)
hole(18, 23)
hole(40, 10)
o.flush(True)

60
gfxlcd/demos/nju_2.py Normal file
View File

@ -0,0 +1,60 @@
import RPi.GPIO
import sys
RPi.GPIO.setmode(RPi.GPIO.BCM)
sys.path.append("../../")
from gfxlcd.driver.nju6450.gpio import GPIO
from gfxlcd.driver.nju6450.nju6450 import NJU6450
import random
def hole(o, x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
def draw_points(o):
for _ in range(0, 50):
hole(o, random.randint(2,o.width - 10), random.randint(2,o.height-10))
def draw_net(o):
s = 0
while s < o.width-1:
o.draw_line(s, 0, s, o.height-1)
s += 10
s = 0
while s < o.height-1:
o.draw_line(0, s, o.width-1, s)
s += 10
lcd_nju = NJU6450(122, 32, GPIO())
lcd_nju.init()
lcd_nju.auto_flush = False
lcd_nju.draw_circle(60, 15, 15)
lcd_nju.draw_circle(53, 10, 3)
lcd_nju.draw_circle(67, 10, 3)
lcd_nju.draw_arc(60, 15, 10, 45, 135)
lcd_nju.draw_line(60, 12, 57, 17)
lcd_nju.draw_line(60, 12, 63, 17)
lcd_nju.draw_arc(60, 15, 3, 45, 135)
lcd_nju.fill_rect(2, 2, 42, 29)
lcd_nju.fill_rect(119, 2, 109, 12)
lcd_nju.fill_rect(119, 17, 109, 19)
lcd_nju.draw_rect(77, 6, 105, 16)
lcd_nju.fill_rect(77, 16, 105, 25)
lcd_nju.flush(True)

90
gfxlcd/demos/ssd.py Normal file
View File

@ -0,0 +1,90 @@
import random
from driver.ssd1306.spi import SPI
from driver.ssd1306.ssd1306 import SSD1306
def hole(x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
drv = SPI()
o = SSD1306(128, 64, drv)
o.init()
o.auto_flush = False
for _ in range(0, 50):
hole(random.randint(2,120), random.randint(2,56))
hole(10, 10)
hole(15, 13)
hole(18, 23)
hole(40, 10)
o.flush(True)
# o.fill(0)
#
# o.fill(random.randint(0, 255))
#
# o.draw_pixels(2, 0, 128)
# o.draw_pixels(3, 0, 128)
# o.draw_pixels(7, 0, 128)
# o.draw_pixels(8, 0, 128)
# o.draw_pixels(1, 9, 7)
# o.draw_pixels(9, 9, 7)
# o.draw_pixels(2, 9, 8)
# o.draw_pixels(3, 9, 16)
# o.draw_pixels(4, 9, 33)
# o.draw_pixels(5, 9, 66)
# o.draw_pixels(6, 9, 33)
# o.draw_pixels(7, 9, 16)
# o.draw_pixels(8, 9, 8)
#
# o.draw_pixels(15, 9, 127)
# o.draw_pixels(16, 9, 65)
# o.draw_pixels(17, 9, 65)
# o.draw_pixels(18, 9, 62)
#
# o.draw_pixels(20, 9, 38)
# o.draw_pixels(21, 9, 73)
# o.draw_pixels(22, 9, 73)
# o.draw_pixels(23, 9, 50)
#
# o.draw_pixels(25, 9, 127)
# o.draw_pixels(26, 9, 9)
# o.draw_pixels(27, 9, 9)
# o.draw_pixels(28, 9, 6)
#
# o.draw_pixels(30, 9, 98)
# o.draw_pixels(31, 9, 81)
# o.draw_pixels(32, 9, 73)
# o.draw_pixels(33, 9, 70)
#
# o.draw_pixels(35, 9, 62)
# o.draw_pixels(36, 9, 65)
# o.draw_pixels(37, 9, 65)
# o.draw_pixels(38, 9, 62)
#
# o.draw_pixels(40, 9, 4)
# o.draw_pixels(41, 9, 2+64)
# o.draw_pixels(42, 9, 127)
# o.draw_pixels(43, 9, 64)
#
# o.draw_pixels(40, 9, 4)
# o.draw_pixels(41, 9, 2+64)
# o.draw_pixels(42, 9, 127)
# o.draw_pixels(43, 9, 64)
#
# o.draw_pixels(45, 9, 97)
# o.draw_pixels(46, 9, 25)
# o.draw_pixels(47, 9, 5)
# o.draw_pixels(48, 9, 3)

56
gfxlcd/demos/ssd_2.py Normal file
View File

@ -0,0 +1,56 @@
import RPi.GPIO
import sys
RPi.GPIO.setmode(RPi.GPIO.BCM)
sys.path.append("../../")
from gfxlcd.driver.ssd1306.spi import SPI
from gfxlcd.driver.ssd1306.ssd1306 import SSD1306
import random
def hole(o, x, y):
o.draw_pixel(x+1, y)
o.draw_pixel(x+2, y)
o.draw_pixel(x+3, y)
o.draw_pixel(x+1, y + 4)
o.draw_pixel(x+2, y + 4)
o.draw_pixel(x+3, y + 4)
o.draw_pixel(x, y + 1)
o.draw_pixel(x+4, y + 1)
o.draw_pixel(x, y + 2)
o.draw_pixel(x+4, y + 2)
o.draw_pixel(x, y + 3)
o.draw_pixel(x+4, y + 3)
def draw_points(o):
for _ in range(0, 50):
hole(o, random.randint(2,o.width - 10), random.randint(2,o.height-10))
def draw_net(o):
s = 0
while s < o.width-1:
o.draw_line(s, 0, s, o.height-1)
s += 10
s = 0
while s < o.height-1:
o.draw_line(0, s, o.width-1, s)
s += 10
lcd_oled = SSD1306(128, 64, SPI())
lcd_oled.init()
lcd_oled.auto_flush = False
lcd_oled.draw_circle(31, 32, 31)
lcd_oled.draw_circle(19, 22, 7)
lcd_oled.draw_circle(43, 22, 7)
lcd_oled.draw_arc(31, 32, 20, 45, 135)
lcd_oled.draw_line(31, 27, 27, 38)
lcd_oled.draw_line(31, 27, 35, 38)
lcd_oled.draw_arc(31, 35, 5, 45, 135)
lcd_oled.fill_rect(95, 4, 105, 10)
lcd_oled.draw_rect(80, 10, 120, 25)
lcd_oled.fill_rect(80, 26, 120, 59)
lcd_oled.flush(True)

View File

@ -0,0 +1 @@
__author__ = 'kosci'

115
gfxlcd/drawing/area.py Normal file
View File

@ -0,0 +1,115 @@
import itertools
from gfxlcd.drawing.pixel import Pixel
class Area(Pixel):
"""Page drawing algorithm"""
def __init__(self):
Pixel.__init__(self)
def init(self):
pass
def draw_pixel(self, x, y):
"""draw one pixel"""
self._set_area(x, y, x, y)
self.driver.data(self._converted_color(), None)
def _set_area(self, x1, y1, x2, y2):
"""select area to work with"""
self.driver.cmd_data(0x0020, x1)
self.driver.cmd_data(0x0021, y1)
self.driver.cmd_data(0x0050, x1)
self.driver.cmd_data(0x0052, y1)
self.driver.cmd_data(0x0051, x2)
self.driver.cmd_data(0x0053, y2)
self.driver.cmd(0x0022, None)
def _draw_vertical_line(self, x, y, length):
"""draw vertical line"""
self._set_area(x, y, x, y + length)
color = self._converted_color()
for _ in itertools.repeat(None, length):
self.driver.data(color, None)
def _draw_horizontal_line(self, x, y, length):
"""draw horizontal line"""
self._set_area(x, y, x + length, y)
color = self._converted_color()
for _ in itertools.repeat(None, length):
self.driver.data(color, None)
def _calculate_steps(self, length, step, required_length):
"""calculate lineparts - helper"""
steps = [length for _ in range(0, step)]
if step * length < required_length:
for idx in range(0, required_length - step * length):
steps[idx] += 1
return steps
def draw_line(self, x1, y1, x2, y2):
"""draw diagonal line"""
width = abs(x2 - x1)
height = abs(y2 - y1)
if x1 == x2:
steps = [height]
horizontal = False
offset_x = offset_y = 0
elif y1 == y2:
steps = [width]
horizontal = True
offset_x = offset_y = 0
elif width > height:
if x2 < x1:
x1, x2 = x2, x1
y1, y2 = y2, y1
offset_y = 1 if y2 > y1 else -1
offset_x = 1 if x2 > x1 else -1
horizontal = True
step = height
length = width / step
steps = self._calculate_steps(length, step, width)
else:
if y2 < y1:
x1, x2 = x2, x1
y1, y2 = y2, y1
offset_y = 1 if y2 > y1 else -1
offset_x = 1 if x2 > x1 else -1
horizontal = False
step = width
length = height / step
steps = self._calculate_steps(length, step, height)
dy = 0
dx = 0
for idx, step in enumerate(steps):
if horizontal:
self._draw_horizontal_line(
int(x1 + dx),
int(y1 + (idx * offset_y)),
int(step)
)
dx += step * offset_x
else:
self._draw_vertical_line(
int(x1 + (idx * offset_x)),
int(y1 + dy),
int(step)
)
dy += step * offset_y
def fill_rect(self, x1, y1, x2, y2):
"""fill an area"""
size = (abs(x2 - x1) + 1) * (abs(y2 - y1) + 1)
self._set_area(
min(x1, x2),
min(y1, y2),
max(x1, x2),
max(y1, y2)
)
color = self._converted_background_color()
for _ in range(0, size):
self.driver.data(color, None)

114
gfxlcd/drawing/page.py Normal file
View File

@ -0,0 +1,114 @@
import abc
from gfxlcd.drawing.pixel import Pixel
class Page(Pixel, metaclass=abc.ABCMeta):
"""Page drawing algorithm"""
def __init__(self):
Pixel.__init__(self)
self.buffer = []
def init(self):
"""init page"""
self.buffer = [[0] * (self.height // 8) for x in range(self.width)]
def draw_pixel(self, x, y):
"""draw a pixel at x,y"""
self.buffer[x][y//8] |= 1 << (y % 8)
self.flush()
def _calculate_steps(self, length, step, required_length):
"""calculate lineparts - helper"""
steps = [length for _ in range(0, step)]
if step * length < required_length:
for idx in range(0, required_length - step * length):
steps[idx] += 1
return steps
def draw_line(self, x1, y1, x2, y2):
"""draw diagonal line"""
width = abs(x2 - x1)
height = abs(y2 - y1)
if x1 == x2:
steps = [height]
horizontal = False
offset_x = offset_y = 0
elif y1 == y2:
steps = [width]
horizontal = True
offset_x = offset_y = 0
elif width > height:
if x2 < x1:
x1, x2 = x2, x1
y1, y2 = y2, y1
offset_y = 1 if y2 > y1 else -1
offset_x = 1 if x2 > x1 else -1
horizontal = True
step = height
length = width / step
steps = self._calculate_steps(length, step, width)
else:
if y2 < y1:
x1, x2 = x2, x1
y1, y2 = y2, y1
offset_y = 1 if y2 > y1 else -1
offset_x = 1 if x2 > x1 else -1
horizontal = False
step = width
length = height / step
steps = self._calculate_steps(length, step, height)
dy = 0
dx = 0
for idx, step in enumerate(steps):
if horizontal:
for appendix in range(int(step)+1):
self.draw_pixel(
int(x1 + dx + appendix),
int(y1 + (idx * offset_y))
)
dx += step * offset_x
else:
for appendix in range(int(step)+1):
self.draw_pixel(
int(x1 + (idx * offset_x)),
int(y1 + dy + appendix)
)
dy += step * offset_y
def fill_rect(self, x1, y1, x2, y2):
"""draw a filled rectangle"""
if y2 < y1:
y1, y2 = y2, y1
if x2 < x1:
x1, x2 = x2, x1
start_page = y1 // 8
start_bit = y1 % 8
end_page = y2 // 8
end_bit = y2 % 8
rows = []
first_page = int(('0' * start_bit).rjust(8, '1'), 2)
last_page = int('1' * (end_bit+1), 2)
if start_page != end_page:
rows.append(first_page)
for _ in range(end_page - start_page - 1):
rows.append(255)
rows.append(last_page)
else:
rows.append(first_page & last_page)
page = start_page
for v in rows:
for x in range(x2-x1+1):
self.buffer[x1+x][page] |= v
page += 1
def get_page_value(self, column, page):
"""returns value"""
return self.buffer[column][page]
@abc.abstractmethod
def flush(self, force=None):
"""flush buffer to the screen"""
pass

73
gfxlcd/drawing/pixel.py Normal file
View File

@ -0,0 +1,73 @@
import math
class Pixel(object):
def __init__(self):
self.options['color'] = {
'R': 255, 'G': 255, 'B': 255
}
self.options['background_color'] = {
'R': 0, 'G': 0, 'B': 0,
}
def draw_rect(self, x1, y1, x2, y2):
"""draw a rectangle"""
self.draw_line(x1, y1, x2, y1)
self.draw_line(x1, y2, x2, y2)
self.draw_line(x1, y1, x1, y2)
self.draw_line(x2, y1, x2, y2)
def draw_circle(self, x, y, radius):
"""draw a circle"""
err = 0
offset_x = radius
offset_y = 0
while offset_x >= offset_y:
self.draw_pixel(x + offset_x, y + offset_y)
self.draw_pixel(x + offset_y, y + offset_x)
self.draw_pixel(x - offset_y, y + offset_x)
self.draw_pixel(x - offset_x, y + offset_y)
self.draw_pixel(x - offset_x, y - offset_y)
self.draw_pixel(x - offset_y, y - offset_x)
self.draw_pixel(x + offset_y, y - offset_x)
self.draw_pixel(x + offset_x, y - offset_y)
if err <= 0:
offset_y += 1
err += 2*offset_y + 1
else:
offset_x -= 1
err -= 2*offset_x + 1
def draw_arc(self, x, y, radius, start, end):
"""draw an arc"""
start = start * math.pi / 180
end = end * math.pi / 180
err = 0
offset_x = radius
offset_y = 0
while offset_x >= offset_y:
if start <= math.atan2(offset_y, offset_x) <= end:
self.draw_pixel(x + offset_x, y + offset_y)
if start <= math.atan2(offset_x, offset_y) <= end:
self.draw_pixel(x + offset_y, y + offset_x)
if start <= math.atan2(offset_x, -offset_y) <= end:
self.draw_pixel(x - offset_y, y + offset_x)
if start <= math.atan2(offset_y, -offset_x) <= end:
self.draw_pixel(x - offset_x, y + offset_y)
if start <= math.atan2(-offset_y, -offset_x) + 2*math.pi <= end:
self.draw_pixel(x - offset_x, y - offset_y)
if start <= math.atan2(-offset_x, -offset_y) + 2*math.pi <= end:
self.draw_pixel(x - offset_y, y - offset_x)
if start <= math.atan2(-offset_x, offset_y) + 2*math.pi <= end:
self.draw_pixel(x + offset_y, y - offset_x)
if start <= math.atan2(-offset_y, offset_x) + 2*math.pi <= end:
self.draw_pixel(x + offset_x, y - offset_y)
if err <= 0:
offset_y += 1
err += 2*offset_y + 1
else:
offset_x -= 1
err -= 2*offset_x + 1

View File

@ -0,0 +1 @@
__author__ = 'kosci'

View File

@ -0,0 +1 @@
__author__ = 'kosci'

View File

@ -0,0 +1,72 @@
import time
import RPi.GPIO
from gfxlcd.abstract.driver import Driver
RPi.GPIO.setmode(RPi.GPIO.BCM)
class GPIO(Driver):
def __init__(self):
self.pins = {
'RS': 27,
'W': 17,
'DB8': 22,
'DB9': 23,
'DB10': 24,
'DB11': 5,
'DB12': 12,
'DB13': 16,
'DB14': 20,
'DB15': 21,
'RST': 25,
}
self.data_pins = [
'DB8', 'DB9', 'DB10', 'DB11', 'DB12', 'DB13', 'DB14', 'DB15',
]
def init(self):
"""initialize pins"""
for pin in self.pins:
RPi.GPIO.setup(self.pins[pin], RPi.GPIO.OUT)
RPi.GPIO.output(self.pins[pin], 0)
def reset(self):
"""reset a display"""
RPi.GPIO.output(self.pins['RST'], 1)
time.sleep(0.005)
RPi.GPIO.output(self.pins['RST'], 0)
time.sleep(0.005)
RPi.GPIO.output(self.pins['RST'], 1)
time.sleep(0.005)
def _set_pins(self, bits):
"""set rpi pins"""
for pin in self.data_pins:
value = bits & 0x01
RPi.GPIO.output(self.pins[pin], value)
bits >>= 1
def cmd(self, char, enable):
"""send command to display"""
RPi.GPIO.output(self.pins['RS'], 0)
self.send(char, enable)
def send(self, char, enable):
"""send 16bit as 2*8bit"""
self._set_pins(char >> 8)
RPi.GPIO.output(self.pins['W'], 0)
RPi.GPIO.output(self.pins['W'], 1)
self._set_pins(char)
RPi.GPIO.output(self.pins['W'], 0)
RPi.GPIO.output(self.pins['W'], 1)
def data(self, data, enable):
"""send data to display"""
RPi.GPIO.output(self.pins['RS'], 1)
self.send(data, enable)
def cmd_data(self, cmd, data):
RPi.GPIO.output(self.pins['RS'], 0)
self.send(cmd, None)
RPi.GPIO.output(self.pins['RS'], 1)
self.send(data, None)

View File

@ -0,0 +1,174 @@
import time
from gfxlcd.drawing.area import Area
from gfxlcd.abstract.chip import Chip
class ILI9325(Area, Chip):
"""CLass for ILI9325 based LCD"""
def __init__(self, width, height, driver):
Chip.__init__(self, width, height, driver, True)
Area.__init__(self)
def _converted_background_color(self):
"""color from 8-8-8 to 5-6-5"""
rgb = self.options['background_color']['R'] << 16 | \
self.options['background_color']['G'] << 8 | \
self.options['background_color']['B']
return ((rgb & 0x00f80000) >> 8) | ((rgb & 0x0000fc00) >> 5) | ((rgb & 0x000000f8) >> 3)
def _converted_color(self):
"""color from 8-8-8 to 5-6-5"""
rgb = self.options['color']['R'] << 16 | \
self.options['color']['G'] << 8 | \
self.options['color']['B']
return ((rgb & 0x00f80000) >> 8) | ((rgb & 0x0000fc00) >> 5) | ((rgb & 0x000000f8) >> 3)
def init(self):
"""init display"""
self.driver.init()
Area.init(self)
Chip.init(self)
self.driver.reset()
# ************* ILI9325C/D **********
# set SS and SM bit
self.driver.cmd(0x0001, None)
self.driver.data(0x0100, None)
# set 1 line inversion
self.driver.cmd(0x0002, None)
self.driver.data(0x0200, None)
# set GRAM write direction and BGR=1
self.driver.cmd(0x0003, None)
self.driver.data(0x1030, None)
# Resize register
self.driver.cmd(0x0004, None)
self.driver.data(0x0000, None)
# set the back porch and front porch
self.driver.cmd(0x0008, None)
self.driver.data(0x0207, None)
# set non-display area refresh cycle ISC[3:0]
self.driver.cmd(0x0009, None)
self.driver.data(0x0000, None)
# FMARK function
self.driver.cmd(0x000A, None)
self.driver.data(0x0000, None)
# RGB interface setting
self.driver.cmd(0x000C, None)
self.driver.data(0x0000, None)
# Frame marker Position
self.driver.cmd(0x000D, None)
self.driver.data(0x0000, None)
# RGB interface polarity
self.driver.cmd(0x000F, None)
self.driver.data(0x0000, None)
# ************* Power On sequence ****************
# SAP, BT[3:0], AP, DSTB, SLP, STB
self.driver.cmd(0x0010, None)
self.driver.data(0x0000, None)
# DC1[2:0], DC0[2:0], VC[2:0]
self.driver.cmd(0x0011, None)
self.driver.data(0x0007, None)
# VREG1OUT voltage
self.driver.cmd(0x0012, None)
self.driver.data(0x0000, None)
# VDV[4:0] for VCOM amplitude
self.driver.cmd(0x0013, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0007, None)
self.driver.data(0x0001, None)
time.sleep(0.2) # Dis-charge capacitor power voltage
# SAP, BT[3:0], AP, DSTB, SLP, STB
self.driver.cmd(0x0010, None)
self.driver.data(0x1690, None)
# Set DC1[2:0], DC0[2:0], VC[2:0]
self.driver.cmd(0x0011, None)
self.driver.data(0x0227, None)
time.sleep(0.05)
self.driver.cmd(0x0012, None)
self.driver.data(0x000D, None)
time.sleep(0.05)
# VDV[4:0] for VCOM amplitude
self.driver.cmd(0x0013, None)
self.driver.data(0x1200, None)
# 04 VCM[5:0] for VCOMH
self.driver.cmd(0x0029, None)
self.driver.data(0x000A, None)
# Set Frame Rate
self.driver.cmd(0x002B, None)
self.driver.data(0x000D, None)
time.sleep(0.05)
# GRAM horizontal Address
self.driver.cmd(0x0020, None)
self.driver.data(0x0000, None)
# GRAM Vertical Address
self.driver.cmd(0x0021, None)
self.driver.data(0x0000, None)
# ************* Adjust the Gamma Curve *************
self.driver.cmd(0x0030, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0031, None)
self.driver.data(0x0404, None)
self.driver.cmd(0x0032, None)
self.driver.data(0x0003, None)
self.driver.cmd(0x0035, None)
self.driver.data(0x0405, None)
self.driver.cmd(0x0036, None)
self.driver.data(0x0808, None)
self.driver.cmd(0x0037, None)
self.driver.data(0x0407, None)
self.driver.cmd(0x0038, None)
self.driver.data(0x0303, None)
self.driver.cmd(0x0039, None)
self.driver.data(0x0707, None)
self.driver.cmd(0x003C, None)
self.driver.data(0x0504, None)
self.driver.cmd(0x003D, None)
self.driver.data(0x0808, None)
# ************* Set GRAM area *************
# Horizontal GRAM Start Address
self.driver.cmd(0x0050, None)
self.driver.data(0x0000, None)
# Horizontal GRAM End Address
self.driver.cmd(0x0051, None)
self.driver.data(0x00EF, None)
# Vertical GRAM Start Address
self.driver.cmd(0x0052, None)
self.driver.data(0x0000, None)
# Vertical GRAM Start Address
self.driver.cmd(0x0053, None)
self.driver.data(0x013F, None)
# Gate Scan Line
self.driver.cmd(0x0060, None)
self.driver.data(0xA700, None)
# NDL, VLE, REV
self.driver.cmd(0x0061, None)
self.driver.data(0x0001, None)
# set scrolling line
self.driver.cmd(0x006A, None)
self.driver.data(0x0000, None)
# ************* Partial Display Control *************
self.driver.cmd(0x0080, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0081, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0082, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0083, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0084, None)
self.driver.data(0x0000, None)
self.driver.cmd(0x0085, None)
self.driver.data(0x0000, None)
# ************* Panel Control *************
self.driver.cmd(0x0090, None)
self.driver.data(0x0010, None)
self.driver.cmd(0x0092, None)
self.driver.data(0x0000, None)
# 262K color and display ON
self.driver.cmd(0x0007, None)
self.driver.data(0x0133, None)

View File

@ -0,0 +1 @@
__author__ = 'kosci'

View File

@ -0,0 +1,69 @@
import time
import RPi.GPIO
from gfxlcd.abstract.driver import Driver
RPi.GPIO.setmode(RPi.GPIO.BCM)
class GPIO(Driver):
def __init__(self):
self.pins = {
'A0': 17,
'E1': 22,
'E2': 21,
'D0': 23,
'D1': 24,
'D2': 25,
'D3': 12,
'D4': 16,
'D5': 20,
'D6': 26,
'D7': 19,
'RST': 5,
}
self.data_pins = [
'D0', 'D1', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7'
]
def init(self):
"""init a device"""
for pin in self.pins:
RPi.GPIO.setup(self.pins[pin], RPi.GPIO.OUT)
RPi.GPIO.output(self.pins[pin], 0)
def reset(self):
"""resets a device"""
RPi.GPIO.output(self.pins['RST'], 1)
time.sleep(0.025)
RPi.GPIO.output(self.pins['RST'], 0)
time.sleep(0.025)
RPi.GPIO.output(self.pins['RST'], 1)
time.sleep(0.025)
RPi.GPIO.output(self.pins['A0'], 0)
RPi.GPIO.output(self.pins['E1'], 1)
RPi.GPIO.output(self.pins['E2'], 1)
def cmd(self, char, enable):
"""send command"""
RPi.GPIO.output(self.pins['A0'], 0)
self.send(char, enable)
def data(self, char, enable):
"""send data"""
RPi.GPIO.output(self.pins['A0'], 1)
self.send(char, enable)
def send(self, data, enable):
"""Write to gpio"""
RPi.GPIO.output(self.pins['E1'], 0)
RPi.GPIO.output(self.pins['E2'], 0)
for i in self.data_pins:
value = data & 0x01
RPi.GPIO.output(self.pins[i], value)
data >>= 1
RPi.GPIO.output(self.pins['E'+str(enable+1)], 1)
time.sleep(0.00025)
RPi.GPIO.output(self.pins['E1'], 0)
RPi.GPIO.output(self.pins['E2'], 0)

View File

@ -0,0 +1,53 @@
from gfxlcd.drawing.page import Page
from gfxlcd.abstract.chip import Chip
class NJU6450(Page, Chip):
"""Class for an LCD with NJU6450 chip"""
def __init__(self, width, height, driver, auto_flush=True):
Chip.__init__(self, width, height, driver, auto_flush)
Page.__init__(self)
def init(self):
"""initialize display"""
self.driver.init()
Page.init(self)
Chip.init(self)
self.driver.reset()
init_sequence = [0xae, 0xa4, 0xa9, 0xe2, 0xa0, 0xaf]
for cmd in init_sequence:
self.driver.cmd(cmd, 0)
self.driver.cmd(cmd, 1)
def set_xy(self, x, y):
"""set xy pos"""
if x < self.width/2:
self.driver.cmd(0xB8 | y, 0)
self.driver.cmd(0x00 | x, 0)
else:
self.driver.cmd(0xB8 | y, 1)
self.driver.cmd(0x00 | (x - self.width//2), 1)
def _converted_background_color(self):
"""convert RGB background to available color"""
return 1
def _converted_color(self):
"""convert RGB color to available color"""
return 1
def flush(self, force=None):
"""flush buffer to device
:force - boolean|None"""
if force is None:
force = self.options['auto_flush']
if force:
for j in range(0, self.height//8):
for i in range(0, self.width):
self.set_xy(i, j)
if i < self.width/2:
self.driver.data(self.get_page_value(i, j), 0)
else:
self.driver.data(self.get_page_value(i, j), 1)

View File

@ -0,0 +1 @@
__author__ = 'kosci'

View File

@ -0,0 +1,49 @@
import spidev
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
import time
from gfxlcd.abstract.driver import Driver
class SPI(Driver):
def __init__(self):
self.pins = {
'RST': 13,
'DC': 6,
}
self.spi = None
def init(self):
"""init sequence"""
for pin in self.pins:
GPIO.setup(self.pins[pin], GPIO.OUT)
GPIO.output(self.pins[pin], 0)
spi = spidev.SpiDev()
spi.open(0,0)
spi.max_speed_hz = 8000000
spi.mode = 0
self.spi = spi
def reset(self):
"""reset device"""
GPIO.output(self.pins['RST'], 1)
time.sleep(0.025)
GPIO.output(self.pins['RST'], 0)
time.sleep(0.025)
GPIO.output(self.pins['RST'], 1)
time.sleep(0.025)
def cmd(self, data, enable=None):
"""send command to device"""
GPIO.output(self.pins['DC'], 0)
self.spi.xfer2([data])
def data(self, data, enable=None):
"""send data to device"""
GPIO.output(self.pins['DC'], 1)
self.spi.xfer2([data])
GPIO.output(self.pins['DC'], 0)

View File

@ -0,0 +1,80 @@
from gfxlcd.drawing.page import Page
from gfxlcd.abstract.chip import Chip
class SSD1306(Page, Chip):
"""Class for an LCD with SSD306 chip"""
def __init__(self, width, height, driver, auto_flush=True):
Chip.__init__(self, width, height, driver, auto_flush)
Page.__init__(self)
def init(self):
"""inits a device"""
self.driver.init()
Page.init(self)
Chip.init(self)
self.driver.reset()
self.driver.cmd(0xae) # turn off panel
self.driver.cmd(0x00) # set low column address
self.driver.cmd(0x10) # set high column address
self.driver.cmd(0x40) # set start line address
self.driver.cmd(0x20) # addr mode
self.driver.cmd(0x02) # horizontal
self.driver.cmd(0xb0) # set page address
self.driver.cmd(0x81) # set contrast control register
self.driver.cmd(0xff)
self.driver.cmd(0xa1) # a0/a1 set segment re-map 127 to 0 a0:0 to seg127
self.driver.cmd(0xc8) # c8/c0 set com(N-1)to com0 c0:com0 to com(N-1)
self.driver.cmd(0xa6) # set normal display, a6 - normal, a7 - inverted
self.driver.cmd(0xa8) # set multiplex ratio(16to63)
self.driver.cmd(0x3f) # 1/64 duty
self.driver.cmd(0xd3) # set display offset
self.driver.cmd(0x00) # not offset
self.driver.cmd(0xd5) # set display clock divide ratio/oscillator frequency
self.driver.cmd(0x80) # set divide ratio
self.driver.cmd(0xd9) # set pre-charge period
self.driver.cmd(0xf1)
self.driver.cmd(0xda) # set com pins hardware configuration
self.driver.cmd(0x12)
self.driver.cmd(0xdb) # set vcomh
self.driver.cmd(0x40)
self.driver.cmd(0x8d) # charge pump
self.driver.cmd(0x14) # enable charge pump
self.driver.cmd(0xaf) # turn on panel
def _converted_background_color(self):
"""convert RGB background to available color"""
return 1
def _converted_color(self):
"""convert RGB color to available color"""
return 1
def flush(self, force=None):
"""flush buffer to device
:force - boolean|None"""
if force is None:
force = self.options['auto_flush']
if force:
for j in range(0, self.height//8):
self.set_area(0, j, self.width-1, j+1)
for i in range(0, self.width):
self.driver.data(self.get_page_value(i, j))
def set_area(self, x1, y1, x2, y2):
"""set area to work on"""
self.driver.cmd(0x22)
self.driver.cmd(0xb0 + y1)
self.driver.cmd(0xb0 + y2)
self.driver.cmd(0x21)
self.driver.cmd(x1)
self.driver.cmd(x2)

183
readme.md Normal file
View File

@ -0,0 +1,183 @@
What it is
===
Library for graphical LCDs for Python on Raspberry Pi. Creates a united interface for supported devices
Supported:
- ili325 via GPIO
- ssd1306 via SPI
- nju6450 via GPIO
On NJU and SSD uses buffer to keep current content as help for page operations.
Wiring is below
Initialization
===
##SSD1306
### SPI
from driver.ssd1306.spi import SPI
from driver.ssd1306.ssd1306 import SSD1306
drv = SPI()
o = SSD1306(128, 64, drv)
o.init()
If you want to set your own pins:
drv = SPI()
drv.pins = {
'RST': 13,
'DC': 6,
}
o = SSD1306(128, 64, drv)
o.init()
##NJU6450
### GPIO
from gfxlcd.driver.nju6450.gpio import GPIO
from gfxlcd.driver.nju6450.nju6450 import NJU6450
drv = GPIO()
o = NJU6450(122, 32, drv)
o.init()
Custom wiring:
from gfxlcd.driver.nju6450.gpio import GPIO
from gfxlcd.driver.nju6450.nju6450 import NJU6450
drv = GPIO()
drv.pins = {
'A0': 17,
'E1': 22,
'E2': 21,
'D0': 23,
'D1': 24,
'D2': 25,
'D3': 12,
'D4': 16,
'D5': 20,
'D6': 26,
'D7': 19,
'RST': 5,
}
o = NJU6450(122, 32, drv)
o.init()
##ILI9325
### GPIO
from gfxlcd.driver.ili9325.gpio import GPIO
from gfxlcd.driver.ili9325.ili9325 import ILI9325
drv = GPIO()
o = ILI9325(240, 320, drv)
o.init()
Custom pins:
from gfxlcd.driver.ili9325.gpio import GPIO
from gfxlcd.driver.ili9325.ili9325 import ILI9325
drv = GPIO()
drv.pins = {
'RS': 27,
'W': 17,
'DB8': 22,
'DB9': 23,
'DB10': 24,
'DB11': 5,
'DB12': 12,
'DB13': 16,
'DB14': 20,
'DB15': 21,
'RST': 25,
}
o = ILI9325(240, 320, drv)
o.init()
Drawing functions
===
draw_pixel
draw_line
draw_rect
draw_circle
draw_arc
fill_rect
Colours
===
lcd.color = (r, g, b)
lcd.background_color = (r, g ,b)
Wiring
===
##SSD1306
### SPI
SPI wiring + 2 additional pins. Defaults:
LCD Raspberry Pi
GND ----------- GND
+3.3V ----------- +3.3V
SCL ----------- G11
SDA ----------- G10
RST ----------- G13
D/C ----------- G6
##NJU6450
### GPIO
Default wiring:
LCD Raspberry Pi
1 (Vss) ------- GND
2 (Vdd) ------- +5V
3 (V0) ---[-\-] 10k
\--- GND
4 (A0) ---------------------- G17
5 (E1) ---------------------- G22
6 (E2) ---------------------- G21
7 (R/W) ------- GND
8 (D0) ---------------------- G23
9 (D1) ---------------------- G24
10 (D2) ---------------------- G25
11 (D3) ---------------------- G12
12 (D4) ---------------------- G16
13 (D5) ---------------------- G20
14 (D6) ---------------------- G26
15 (D7) ---------------------- G19
16 (RST) ------- +5V
17 (A) ------- +5V
18 (K) ------- GND
##ILI9325
### GPIO
Default:
TFT Raspberry Pi 2B
GND ------------------------ GND
Vcc ------------------------ 3.3
RS ------------------------ G27 (data[H]/cmd[L])
WR ------------------------ G17
RD ------------------------ 3.3 (never read from screen)
DB8 ------------------------ G22
DB9 ------------------------ G23
DB10 ------------------------ G24
DB11 ------------------------ G5
DB12 ------------------------ G12
DB13 ------------------------ G16
DB14 ------------------------ G20
DB15 ------------------------ G21
CS ------------------------ GND (always selected)
REST ------------------------ G25
LED_A ------------------------ 3.3

4
setup.cfg Normal file
View File

@ -0,0 +1,4 @@
[bdist_wheel]
universal = 1
[metadata]
description-file = readme.md

39
setup.py Normal file
View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
"""setup for GfxLCD package"""
import os
from setuptools import setup, find_packages
def read(*paths):
"""Build a file path from *paths* and return the contents."""
with open(os.path.join(*paths), 'r') as file_handler:
return file_handler.read()
setup(
name='gfxlcd',
version='0.1.0',
description='gfxlcd is a handler for grpahical lcds: ILI9328, SSD1306, NJU6450 @ Raspberry Pi.',
keywords=['gfxlcd', 'raspberry pi' ,'ili9328' ,'ssd1306', 'nju6450', 'lcd', 'graphical lcd'],
long_description=(read('readme.md')),
url='https://bitbucket.org/kosci/charlcd.git',
license='MIT',
author='Bartosz Kościów',
author_email='kosci1@gmail.com',
py_modules=['gfxlcd'],
include_package_data=True,
classifiers=[
'Development Status :: 4 - Beta',
'Environment :: Console',
'Intended Audience :: Developers',
'Natural Language :: English',
'License :: OSI Approved :: MIT License',
'Operating System :: OS Independent',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Topic :: Software Development :: Libraries :: Python Modules',
'Topic :: Home Automation'
],
packages=find_packages(exclude=['tests*']),
)

2
tests3 Normal file
View File

@ -0,0 +1,2 @@
chmod 644 gfxlcd/tests/*.py
python3 -m nose --with-specplugin

20
tox.ini Normal file
View File

@ -0,0 +1,20 @@
[tox]
envlist = py35
skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
deps=
nose
mock
future
flake8
pylint
whitelist_externals = /bin/bash
commands= nosetests --with-xunit --xunit-file=junit-{envname}.xml charlcd/tests
rm flake8-{envname}.log
/bin/bash -c "flake8 --output-file=flake8-{envname}.log gfxlcd || :"
/bin/bash -c "pylint gfxlcd > pylint-{envname}.log || :"
[flake8]
show-source = True
exclude = .git,.venv,.tox,dist,doc,build,*egg,*/tests/*