Skip to content

Commit

Permalink
Add support for SSD1325 devices - fixes #108
Browse files Browse the repository at this point in the history
  • Loading branch information
rm-hull committed Dec 24, 2016
1 parent 7e6cf52 commit b65b9d0
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
4 changes: 2 additions & 2 deletions examples/demo_opts.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument('--config', '-f', type=str, help='Load configuration settings from a file')
parser.add_argument('--display', '-d', type=str, default='ssd1306', help='Display type, supports real devices or emulators', choices=["ssd1306", "ssd1331", "sh1106", "capture", "pygame", "gifanim"])
parser.add_argument('--display', '-d', type=str, default='ssd1306', help='Display type, supports real devices or emulators', choices=["ssd1306", "ssd1325", "ssd1331", "sh1106", "capture", "pygame", "gifanim"])
parser.add_argument('--width', type=int, default=128, help='Width of the device in pixels')
parser.add_argument('--height', type=int, default=64, help='Height of the device in pixels')
parser.add_argument('--interface', '-i', type=str, default='i2c', help='Serial interface type', choices=["i2c", "spi"])
Expand Down Expand Up @@ -51,7 +51,7 @@
config = fp.read().replace("\n", " ").split()
args = parser.parse_args(config)

if args.display in ('ssd1306', 'ssd1331', 'sh1106'):
if args.display in ('ssd1306', 'ssd1325', 'ssd1331', 'sh1106'):
if args.interface not in ('i2c', 'spi'):
parser.error('unknown interface %s' % args.interface)

Expand Down
20 changes: 20 additions & 0 deletions oled/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,23 @@ class ssd1331(common):
SETPRECHARGEVOLTAGE = 0xBB
SETROWADDR = 0x75
SETVVOLTAGE = 0xBE


class ssd1325(common):
SETCOLUMNADDR = 0x15
SETROWADDR = 0x75
SETCURRENT = 0x84
SETSTARTLINE = 0xA1
SETOFFSET = 0xA2
NORMALDISPLAY = 0xA4
DISPLAYALLOFF = 0xA6
MASTERCONFIG = 0xAD
SETPRECHARGECOMPENABLE = 0xB0
SETPHASELEN = 0xB1
SETROWPERIOD = 0xB2
SETCLOCK = 0xB3
SETPRECHARGECOMP = 0xB4
SETGRAYTABLE = 0xB8
SETPRECHARGEVOLTAGE = 0xBC
SETVCOMLEVEL = 0xBE
SETVSL = 0xBF
77 changes: 77 additions & 0 deletions oled/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,3 +347,80 @@ def contrast(self, level):
self.command(self._const.SETCONTRASTA, level,
self._const.SETCONTRASTB, level,
self._const.SETCONTRASTC, level)


class ssd1325(device):
"""
Encapsulates the serial interface to the 4-bit greyscale SSD1325 OLED
display hardware. On creation, an initialization sequence is pumped to the
display to properly configure it. Further control commands can then be
called to affect the brightness and other settings.
.. warning::
Direct use of the :func:`command` and :func:`data` methods are
discouraged: Screen updates should be effected through the
:func:`display` method, or preferably with the
:class:`oled.render.canvas` context manager.
"""
def __init__(self, serial_interface=None, width=96, height=64):
super(ssd1325, self).__init__(oled.const.ssd1325, serial_interface)
self.capabilities(width, height, mode="RGB")
self._buffer = [0] * (self.width * self.height // 2)

if width != 128 or height != 64:
raise oled.error.DeviceDisplayModeError(
"Unsupported display mode: {0} x {1}".format(width, height))

self.command(
self._const.DISPLAYOFF,
self._const.SETCLOCK, 0xF1,
self._const.SETMULTIPLEX, 0x3F,
self._const.SETOFFSET, 0x4C,
self._const.SETSTARTLINE, 0x00,
self._const.MASTERCONFIG, 0x02,
self._const.SETREMAP, 0xF0,
self._const.SETCURRENT + 2,
self._const.SETGRAYTABLE, 0x01, 0x11, 0x22, 0x32, 0x43, 0x54, 0x65, 0x76)

self.contrast(0xFF)

self.command(
self._const.SETROWPERIOD, 0x51,
self._const.SETPHASELEN, 0x55,
self._const.SETPRECHARGECOMP, 0x02,
self._const.SETPRECHARGECOMPENABLE, 0x28,
self._const.SETVCOMLEVEL, 0x1C,
self._const.SETVSL, 0x0D | 0x02,
self._const.NORMALDISPLAY)

self.clear()
self.show()

def display(self, image):
"""
Takes a 24-bit RGB :py:mod:`PIL.Image` and dumps it to the SSD1325 OLED
display, converting the image pixels to 4-bit greyscale using a simple
RGB averaging (quicker than Luma calculations).
"""
assert(image.mode == self.mode)
assert(image.size[0] == self.width)
assert(image.size[1] == self.height)

self.command(
self._const.SETCOLUMNADDR, 0x00, self.width - 1,
self._const.SETROWADDR, 0x00, self.height - 1)

i = 0
buf = self._buffer
for r, g, b in image.getdata():
grey = (r + g + b) // 3

if i % 2 == 0:
buf[i // 2] = grey >> 4
else:
buf[i // 2] |= (grey & 0xF0)

i += 1

self.data(buf)

0 comments on commit b65b9d0

Please sign in to comment.