mirror of
https://github.com/wahyd4/Adafruit_Python_SSD1306.git
synced 2026-08-09 04:46:43 +10:00
Python 3 support tweaks, support for pillow library.
This commit is contained in:
+273
-272
@@ -18,6 +18,7 @@
|
||||
# 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.
|
||||
from __future__ import division
|
||||
import logging
|
||||
import time
|
||||
|
||||
@@ -26,7 +27,7 @@ import Adafruit_GPIO.SPI as SPI
|
||||
|
||||
|
||||
# Constants
|
||||
SSD1306_I2C_ADDRESS = 0x3C # 011110+SA0+RW - 0x3C or 0x3D
|
||||
SSD1306_I2C_ADDRESS = 0x3C # 011110+SA0+RW - 0x3C or 0x3D
|
||||
SSD1306_SETCONTRAST = 0x81
|
||||
SSD1306_DISPLAYALLON_RESUME = 0xA4
|
||||
SSD1306_DISPLAYALLON = 0xA5
|
||||
@@ -64,296 +65,296 @@ SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A
|
||||
|
||||
|
||||
class SSD1306Base(object):
|
||||
"""Base class for SSD1306-based OLED displays. Implementors should subclass
|
||||
and provide an implementation for the _initialize function.
|
||||
"""
|
||||
"""Base class for SSD1306-based OLED displays. Implementors should subclass
|
||||
and provide an implementation for the _initialize function.
|
||||
"""
|
||||
|
||||
def __init__(self, width, height, rst, dc=None, sclk=None, din=None, cs=None,
|
||||
gpio=None, spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
self._log = logging.getLogger('Adafruit_SSD1306.SSD1306Base')
|
||||
self._spi = None
|
||||
self._i2c = None
|
||||
self.width = width
|
||||
self.height = height
|
||||
self._pages = height/8
|
||||
self._buffer = [0]*(width*self._pages)
|
||||
# Default to platform GPIO if not provided.
|
||||
self._gpio = gpio
|
||||
if self._gpio is None:
|
||||
self._gpio = GPIO.get_platform_gpio()
|
||||
# Setup reset pin.
|
||||
self._rst = rst
|
||||
self._gpio.setup(self._rst, GPIO.OUT)
|
||||
# Handle hardware SPI
|
||||
if spi is not None:
|
||||
self._log.debug('Using hardware SPI')
|
||||
self._spi = spi
|
||||
self._spi.set_clock_hz(8000000)
|
||||
# Handle software SPI
|
||||
elif sclk is not None and din is not None and cs is not None:
|
||||
self._log.debug('Using software SPI')
|
||||
self._spi = SPI.BitBang(self._gpio, sclk, din, None, cs)
|
||||
# Handle hardware I2C
|
||||
elif i2c is not None:
|
||||
self._log.debug('Using hardware I2C with custom I2C provider.')
|
||||
self._i2c = i2c.get_i2c_device(i2c_address)
|
||||
else:
|
||||
self._log.debug('Using hardware I2C with platform I2C provider.')
|
||||
import Adafruit_GPIO.I2C as I2C
|
||||
if i2c_bus is None:
|
||||
self._i2c = I2C.get_i2c_device(i2c_address)
|
||||
else:
|
||||
self._i2c = I2C.get_i2c_device(i2c_address, busnum=i2c_bus)
|
||||
# Initialize DC pin if using SPI.
|
||||
if self._spi is not None:
|
||||
if dc is None:
|
||||
raise ValueError('DC pin must be provided when using SPI.')
|
||||
self._dc = dc
|
||||
self._gpio.setup(self._dc, GPIO.OUT)
|
||||
|
||||
def _initialize(self):
|
||||
raise NotImplementedError
|
||||
def __init__(self, width, height, rst, dc=None, sclk=None, din=None, cs=None,
|
||||
gpio=None, spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
self._log = logging.getLogger('Adafruit_SSD1306.SSD1306Base')
|
||||
self._spi = None
|
||||
self._i2c = None
|
||||
self.width = width
|
||||
self.height = height
|
||||
self._pages = height//8
|
||||
self._buffer = [0]*(width*self._pages)
|
||||
# Default to platform GPIO if not provided.
|
||||
self._gpio = gpio
|
||||
if self._gpio is None:
|
||||
self._gpio = GPIO.get_platform_gpio()
|
||||
# Setup reset pin.
|
||||
self._rst = rst
|
||||
self._gpio.setup(self._rst, GPIO.OUT)
|
||||
# Handle hardware SPI
|
||||
if spi is not None:
|
||||
self._log.debug('Using hardware SPI')
|
||||
self._spi = spi
|
||||
self._spi.set_clock_hz(8000000)
|
||||
# Handle software SPI
|
||||
elif sclk is not None and din is not None and cs is not None:
|
||||
self._log.debug('Using software SPI')
|
||||
self._spi = SPI.BitBang(self._gpio, sclk, din, None, cs)
|
||||
# Handle hardware I2C
|
||||
elif i2c is not None:
|
||||
self._log.debug('Using hardware I2C with custom I2C provider.')
|
||||
self._i2c = i2c.get_i2c_device(i2c_address)
|
||||
else:
|
||||
self._log.debug('Using hardware I2C with platform I2C provider.')
|
||||
import Adafruit_GPIO.I2C as I2C
|
||||
if i2c_bus is None:
|
||||
self._i2c = I2C.get_i2c_device(i2c_address)
|
||||
else:
|
||||
self._i2c = I2C.get_i2c_device(i2c_address, busnum=i2c_bus)
|
||||
# Initialize DC pin if using SPI.
|
||||
if self._spi is not None:
|
||||
if dc is None:
|
||||
raise ValueError('DC pin must be provided when using SPI.')
|
||||
self._dc = dc
|
||||
self._gpio.setup(self._dc, GPIO.OUT)
|
||||
|
||||
def command(self, c):
|
||||
"""Send command byte to display."""
|
||||
if self._spi is not None:
|
||||
# SPI write.
|
||||
self._gpio.set_low(self._dc)
|
||||
self._spi.write([c])
|
||||
else:
|
||||
# I2C write.
|
||||
control = 0x00 # Co = 0, DC = 0
|
||||
self._i2c.write8(control, c)
|
||||
def _initialize(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def data(self, c):
|
||||
"""Send byte of data to display."""
|
||||
if self._spi is not None:
|
||||
# SPI write.
|
||||
self._gpio.set_high(self._dc)
|
||||
self._spi.write([c])
|
||||
else:
|
||||
# I2C write.
|
||||
control = 0x40 # Co = 0, DC = 0
|
||||
self._i2c.write8(control, c)
|
||||
def command(self, c):
|
||||
"""Send command byte to display."""
|
||||
if self._spi is not None:
|
||||
# SPI write.
|
||||
self._gpio.set_low(self._dc)
|
||||
self._spi.write([c])
|
||||
else:
|
||||
# I2C write.
|
||||
control = 0x00 # Co = 0, DC = 0
|
||||
self._i2c.write8(control, c)
|
||||
|
||||
def begin(self, vccstate=SSD1306_SWITCHCAPVCC):
|
||||
"""Initialize display."""
|
||||
# Save vcc state.
|
||||
self._vccstate = vccstate
|
||||
# Reset and initialize display.
|
||||
self.reset()
|
||||
self._initialize()
|
||||
# Turn on the display.
|
||||
self.command(SSD1306_DISPLAYON)
|
||||
def data(self, c):
|
||||
"""Send byte of data to display."""
|
||||
if self._spi is not None:
|
||||
# SPI write.
|
||||
self._gpio.set_high(self._dc)
|
||||
self._spi.write([c])
|
||||
else:
|
||||
# I2C write.
|
||||
control = 0x40 # Co = 0, DC = 0
|
||||
self._i2c.write8(control, c)
|
||||
|
||||
def reset(self):
|
||||
"""Reset the display."""
|
||||
# Set reset high for a millisecond.
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.001)
|
||||
# Set reset low for 10 milliseconds.
|
||||
self._gpio.set_low(self._rst)
|
||||
time.sleep(0.010)
|
||||
# Set reset high again.
|
||||
self._gpio.set_high(self._rst)
|
||||
def begin(self, vccstate=SSD1306_SWITCHCAPVCC):
|
||||
"""Initialize display."""
|
||||
# Save vcc state.
|
||||
self._vccstate = vccstate
|
||||
# Reset and initialize display.
|
||||
self.reset()
|
||||
self._initialize()
|
||||
# Turn on the display.
|
||||
self.command(SSD1306_DISPLAYON)
|
||||
|
||||
def display(self):
|
||||
"""Write display buffer to physical display."""
|
||||
self.command(SSD1306_COLUMNADDR)
|
||||
self.command(0) # Column start address. (0 = reset)
|
||||
self.command(self.width-1) # Column end address.
|
||||
self.command(SSD1306_PAGEADDR)
|
||||
self.command(0) # Page start address. (0 = reset)
|
||||
self.command(self._pages-1) # Page end address.
|
||||
# Write buffer data.
|
||||
if self._spi is not None:
|
||||
# Set DC high for data.
|
||||
self._gpio.set_high(self._dc)
|
||||
# Write buffer.
|
||||
self._spi.write(self._buffer)
|
||||
else:
|
||||
for i in range(0, len(self._buffer), 16):
|
||||
control = 0x40 # Co = 0, DC = 0
|
||||
self._i2c.writeList(control, self._buffer[i:i+16])
|
||||
def reset(self):
|
||||
"""Reset the display."""
|
||||
# Set reset high for a millisecond.
|
||||
self._gpio.set_high(self._rst)
|
||||
time.sleep(0.001)
|
||||
# Set reset low for 10 milliseconds.
|
||||
self._gpio.set_low(self._rst)
|
||||
time.sleep(0.010)
|
||||
# Set reset high again.
|
||||
self._gpio.set_high(self._rst)
|
||||
|
||||
def image(self, image):
|
||||
"""Set buffer to value of Python Imaging Library image. The image should
|
||||
be in 1 bit mode and a size equal to the display size.
|
||||
"""
|
||||
if image.mode != '1':
|
||||
raise ValueError('Image must be in mode 1.')
|
||||
imwidth, imheight = image.size
|
||||
if imwidth != self.width or imheight != self.height:
|
||||
raise ValueError('Image must be same dimensions as display ({0}x{1}).' \
|
||||
.format(self.width, self.height))
|
||||
# Grab all the pixels from the image, faster than getpixel.
|
||||
pix = image.load()
|
||||
# Iterate through the memory pages
|
||||
index = 0
|
||||
for page in range(self._pages):
|
||||
# Iterate through all x axis columns.
|
||||
for x in range(self.width):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
bits = 0
|
||||
# Don't use range here as it's a bit slow
|
||||
for bit in [0, 1, 2, 3, 4, 5, 6, 7]:
|
||||
bits = bits << 1
|
||||
bits |= 0 if pix[(x, page*8+7-bit)] == 0 else 1
|
||||
# Update buffer byte and increment to next byte.
|
||||
self._buffer[index] = bits
|
||||
index += 1
|
||||
def display(self):
|
||||
"""Write display buffer to physical display."""
|
||||
self.command(SSD1306_COLUMNADDR)
|
||||
self.command(0) # Column start address. (0 = reset)
|
||||
self.command(self.width-1) # Column end address.
|
||||
self.command(SSD1306_PAGEADDR)
|
||||
self.command(0) # Page start address. (0 = reset)
|
||||
self.command(self._pages-1) # Page end address.
|
||||
# Write buffer data.
|
||||
if self._spi is not None:
|
||||
# Set DC high for data.
|
||||
self._gpio.set_high(self._dc)
|
||||
# Write buffer.
|
||||
self._spi.write(self._buffer)
|
||||
else:
|
||||
for i in range(0, len(self._buffer), 16):
|
||||
control = 0x40 # Co = 0, DC = 0
|
||||
self._i2c.writeList(control, self._buffer[i:i+16])
|
||||
|
||||
def clear(self):
|
||||
"""Clear contents of image buffer."""
|
||||
self._buffer = [0]*(self.width*self._pages)
|
||||
def image(self, image):
|
||||
"""Set buffer to value of Python Imaging Library image. The image should
|
||||
be in 1 bit mode and a size equal to the display size.
|
||||
"""
|
||||
if image.mode != '1':
|
||||
raise ValueError('Image must be in mode 1.')
|
||||
imwidth, imheight = image.size
|
||||
if imwidth != self.width or imheight != self.height:
|
||||
raise ValueError('Image must be same dimensions as display ({0}x{1}).' \
|
||||
.format(self.width, self.height))
|
||||
# Grab all the pixels from the image, faster than getpixel.
|
||||
pix = image.load()
|
||||
# Iterate through the memory pages
|
||||
index = 0
|
||||
for page in range(self._pages):
|
||||
# Iterate through all x axis columns.
|
||||
for x in range(self.width):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
bits = 0
|
||||
# Don't use range here as it's a bit slow
|
||||
for bit in [0, 1, 2, 3, 4, 5, 6, 7]:
|
||||
bits = bits << 1
|
||||
bits |= 0 if pix[(x, page*8+7-bit)] == 0 else 1
|
||||
# Update buffer byte and increment to next byte.
|
||||
self._buffer[index] = bits
|
||||
index += 1
|
||||
|
||||
def set_contrast(self, contrast):
|
||||
"""Sets the contrast of the display. Contrast should be a value between
|
||||
0 and 255."""
|
||||
if contrast < 0 or contrast > 255:
|
||||
raise ValueError('Contrast must be a value from 0 to 255 (inclusive).')
|
||||
self.command(SSD1306_SETCONTRAST)
|
||||
self.command(contrast)
|
||||
def clear(self):
|
||||
"""Clear contents of image buffer."""
|
||||
self._buffer = [0]*(self.width*self._pages)
|
||||
|
||||
def dim(self, dim):
|
||||
"""Adjusts contrast to dim the display if dim is True, otherwise sets the
|
||||
contrast to normal brightness if dim is False.
|
||||
"""
|
||||
# Assume dim display.
|
||||
contrast = 0
|
||||
# Adjust contrast based on VCC if not dimming.
|
||||
if not dim:
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
contrast = 0x9F
|
||||
else:
|
||||
contrast = 0xCF
|
||||
def set_contrast(self, contrast):
|
||||
"""Sets the contrast of the display. Contrast should be a value between
|
||||
0 and 255."""
|
||||
if contrast < 0 or contrast > 255:
|
||||
raise ValueError('Contrast must be a value from 0 to 255 (inclusive).')
|
||||
self.command(SSD1306_SETCONTRAST)
|
||||
self.command(contrast)
|
||||
|
||||
def dim(self, dim):
|
||||
"""Adjusts contrast to dim the display if dim is True, otherwise sets the
|
||||
contrast to normal brightness if dim is False.
|
||||
"""
|
||||
# Assume dim display.
|
||||
contrast = 0
|
||||
# Adjust contrast based on VCC if not dimming.
|
||||
if not dim:
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
contrast = 0x9F
|
||||
else:
|
||||
contrast = 0xCF
|
||||
|
||||
|
||||
class SSD1306_128_64(SSD1306Base):
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_128_64, self).__init__(128, 64, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_128_64, self).__init__(128, 64, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
|
||||
def _initialize(self):
|
||||
# 128x64 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x80) # the suggested ratio 0x80
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x3F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x12)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x9F)
|
||||
else:
|
||||
self.command(0xCF)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
def _initialize(self):
|
||||
# 128x64 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x80) # the suggested ratio 0x80
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x3F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x12)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x9F)
|
||||
else:
|
||||
self.command(0xCF)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
|
||||
|
||||
class SSD1306_128_32(SSD1306Base):
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_128_32, self).__init__(128, 32, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_128_32, self).__init__(128, 32, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
|
||||
def _initialize(self):
|
||||
# 128x32 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x80) # the suggested ratio 0x80
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x1F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x02)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
self.command(0x8F)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
def _initialize(self):
|
||||
# 128x32 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x80) # the suggested ratio 0x80
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x1F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x02)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
self.command(0x8F)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
|
||||
|
||||
class SSD1306_96_16(SSD1306Base):
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_96_16, self).__init__(96, 16, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
def __init__(self, rst, dc=None, sclk=None, din=None, cs=None, gpio=None,
|
||||
spi=None, i2c_bus=None, i2c_address=SSD1306_I2C_ADDRESS,
|
||||
i2c=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_96_16, self).__init__(96, 16, rst, dc, sclk, din, cs,
|
||||
gpio, spi, i2c_bus, i2c_address, i2c)
|
||||
|
||||
def _initialize(self):
|
||||
# 128x32 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x60) # the suggested ratio 0x60
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x0F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x02)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
self.command(0x8F)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
def _initialize(self):
|
||||
# 128x32 pixel specific initialization.
|
||||
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||
self.command(0x60) # the suggested ratio 0x60
|
||||
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||
self.command(0x0F)
|
||||
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||
self.command(0x0) # no offset
|
||||
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x10)
|
||||
else:
|
||||
self.command(0x14)
|
||||
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||
self.command(0x00) # 0x0 act like ks0108
|
||||
self.command(SSD1306_SEGREMAP | 0x1)
|
||||
self.command(SSD1306_COMSCANDEC)
|
||||
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||
self.command(0x02)
|
||||
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||
self.command(0x8F)
|
||||
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||
self.command(0x22)
|
||||
else:
|
||||
self.command(0xF1)
|
||||
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||
self.command(0x40)
|
||||
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||
|
||||
@@ -1 +1 @@
|
||||
from SSD1306 import *
|
||||
from .SSD1306 import *
|
||||
|
||||
+34
-34
@@ -24,9 +24,9 @@ import time
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
import Adafruit_SSD1306
|
||||
|
||||
import Image
|
||||
import ImageFont
|
||||
import ImageDraw
|
||||
from PIL import Image
|
||||
from PIL import ImageFont
|
||||
from PIL import ImageDraw
|
||||
|
||||
|
||||
# Raspberry Pi pin configuration:
|
||||
@@ -91,36 +91,36 @@ velocity = -2
|
||||
startpos = width
|
||||
|
||||
# Animate text moving in sine wave.
|
||||
print 'Press Ctrl-C to quit.'
|
||||
print('Press Ctrl-C to quit.')
|
||||
pos = startpos
|
||||
while True:
|
||||
# Clear image buffer by drawing a black filled box.
|
||||
draw.rectangle((0,0,width,height), outline=0, fill=0)
|
||||
# Enumerate characters and draw them offset vertically based on a sine wave.
|
||||
x = pos
|
||||
for i, c in enumerate(text):
|
||||
# Stop drawing if off the right side of screen.
|
||||
if x > width:
|
||||
break
|
||||
# Calculate width but skip drawing if off the left side of screen.
|
||||
if x < -10:
|
||||
char_width, char_height = draw.textsize(c, font=font)
|
||||
x += char_width
|
||||
continue
|
||||
# Calculate offset from sine wave.
|
||||
y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi))
|
||||
# Draw text.
|
||||
draw.text((x, y), c, font=font, fill=255)
|
||||
# Increment x position based on chacacter width.
|
||||
char_width, char_height = draw.textsize(c, font=font)
|
||||
x += char_width
|
||||
# Draw the image buffer.
|
||||
disp.image(image)
|
||||
disp.display()
|
||||
# Move position for next frame.
|
||||
pos += velocity
|
||||
# Start over if text has scrolled completely off left side of screen.
|
||||
if pos < -maxwidth:
|
||||
pos = startpos
|
||||
# Pause briefly before drawing next frame.
|
||||
time.sleep(0.1)
|
||||
# Clear image buffer by drawing a black filled box.
|
||||
draw.rectangle((0,0,width,height), outline=0, fill=0)
|
||||
# Enumerate characters and draw them offset vertically based on a sine wave.
|
||||
x = pos
|
||||
for i, c in enumerate(text):
|
||||
# Stop drawing if off the right side of screen.
|
||||
if x > width:
|
||||
break
|
||||
# Calculate width but skip drawing if off the left side of screen.
|
||||
if x < -10:
|
||||
char_width, char_height = draw.textsize(c, font=font)
|
||||
x += char_width
|
||||
continue
|
||||
# Calculate offset from sine wave.
|
||||
y = offset+math.floor(amplitude*math.sin(x/float(width)*2.0*math.pi))
|
||||
# Draw text.
|
||||
draw.text((x, y), c, font=font, fill=255)
|
||||
# Increment x position based on chacacter width.
|
||||
char_width, char_height = draw.textsize(c, font=font)
|
||||
x += char_width
|
||||
# Draw the image buffer.
|
||||
disp.image(image)
|
||||
disp.display()
|
||||
# Move position for next frame.
|
||||
pos += velocity
|
||||
# Start over if text has scrolled completely off left side of screen.
|
||||
if pos < -maxwidth:
|
||||
pos = startpos
|
||||
# Pause briefly before drawing next frame.
|
||||
time.sleep(0.1)
|
||||
|
||||
+3
-3
@@ -23,7 +23,7 @@ import time
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
import Adafruit_SSD1306
|
||||
|
||||
import Image
|
||||
from PIL import Image
|
||||
|
||||
|
||||
# Raspberry Pi pin configuration:
|
||||
@@ -61,9 +61,9 @@ disp.display()
|
||||
|
||||
# Load image based on OLED display height. Note that image is converted to 1 bit color.
|
||||
if disp.height == 64:
|
||||
image = Image.open('happycat_oled_64.ppm').convert('1')
|
||||
image = Image.open('happycat_oled_64.ppm').convert('1')
|
||||
else:
|
||||
image = Image.open('happycat_oled_32.ppm').convert('1')
|
||||
image = Image.open('happycat_oled_32.ppm').convert('1')
|
||||
|
||||
# Alternatively load a different format image, resize it, and convert to 1 bit color.
|
||||
#image = Image.open('happycat.png').resize((disp.width, disp.height), Image.ANTIALIAS).convert('1')
|
||||
|
||||
+3
-3
@@ -23,9 +23,9 @@ import time
|
||||
import Adafruit_GPIO.SPI as SPI
|
||||
import Adafruit_SSD1306
|
||||
|
||||
import Image
|
||||
import ImageDraw
|
||||
import ImageFont
|
||||
from PIL import Image
|
||||
from PIL import ImageDraw
|
||||
from PIL import ImageFont
|
||||
|
||||
|
||||
# Raspberry Pi pin configuration:
|
||||
|
||||
@@ -2,13 +2,23 @@ from ez_setup import use_setuptools
|
||||
use_setuptools()
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(name = 'Adafruit_SSD1306',
|
||||
version = '1.5.0',
|
||||
author = 'Tony DiCola',
|
||||
author_email = 'tdicola@adafruit.com',
|
||||
description = 'Python library to use SSD1306-based 128x64 or 128x32 pixel OLED displays with a Raspberry Pi or Beaglebone Black.',
|
||||
license = 'MIT',
|
||||
url = 'https://github.com/adafruit/Adafruit_Python_SSD1306/',
|
||||
dependency_links = ['https://github.com/adafruit/Adafruit_Python_GPIO/tarball/master#egg=Adafruit-GPIO-0.6.5'],
|
||||
install_requires = ['Adafruit-GPIO>=0.6.5'],
|
||||
packages = find_packages())
|
||||
classifiers = ['Development Status :: 4 - Beta',
|
||||
'Operating System :: POSIX :: Linux',
|
||||
'License :: OSI Approved :: MIT License',
|
||||
'Intended Audience :: Developers',
|
||||
'Programming Language :: Python :: 2.7',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Software Development',
|
||||
'Topic :: System :: Hardware']
|
||||
|
||||
setup(name = 'Adafruit_SSD1306',
|
||||
version = '1.6.0',
|
||||
author = 'Tony DiCola',
|
||||
author_email = 'tdicola@adafruit.com',
|
||||
description = 'Python library to use SSD1306-based 128x64 or 128x32 pixel OLED displays with a Raspberry Pi or Beaglebone Black.',
|
||||
license = 'MIT',
|
||||
classifiers = classifiers,
|
||||
url = 'https://github.com/adafruit/Adafruit_Python_SSD1306/',
|
||||
dependency_links = ['https://github.com/adafruit/Adafruit_Python_GPIO/tarball/master#egg=Adafruit-GPIO-0.6.5'],
|
||||
install_requires = ['Adafruit-GPIO>=0.6.5'],
|
||||
packages = find_packages())
|
||||
|
||||
Reference in New Issue
Block a user