PiClock project
This commit is contained in:
127
hybotics_ht16k33/ht16k33.py
Normal file
127
hybotics_ht16k33/ht16k33.py
Normal file
@@ -0,0 +1,127 @@
|
||||
# SPDX-FileCopyrightText: Radomir Dopieralski 2016 for Adafruit Industries
|
||||
# SPDX-FileCopyrightText: Tony DiCola 2016 for Adafruit Industries
|
||||
# SPDX-FileCopyrightText: Dale Weber 2021
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
"""
|
||||
`hybotics_ht16k33.ht16k33`
|
||||
===========================
|
||||
|
||||
* Authors: Radomir Dopieralski & Tony DiCola for Adafruit Industries
|
||||
|
||||
* Ported to Micropython by Dale Weber <hybotics.wy@gmail.com>
|
||||
"""
|
||||
|
||||
__version__ = "0.0.0-auto.0"
|
||||
__repo__ = "https://github.com/hybotics/Hybotics_Micropython_HT16K33.git"
|
||||
|
||||
from micropython import const
|
||||
from utime import sleep
|
||||
|
||||
_HT16K33_BLINK_CMD = const(0x80)
|
||||
_HT16K33_BLINK_DISPLAYON = const(0x01)
|
||||
_HT16K33_CMD_BRIGHTNESS = const(0xE0)
|
||||
_HT16K33_OSCILATOR_ON = const(0x21)
|
||||
|
||||
RETRY_MAX = 10
|
||||
RETRY_WAIT_SEC = 1.0
|
||||
|
||||
class HT16K33:
|
||||
"""The base class for all HT16K33-based backpacks and wings."""
|
||||
|
||||
def __init__(self, i2c, address=0x70, auto_write=True, brightness=1.0):
|
||||
self.i2c = i2c
|
||||
self.address = address
|
||||
self._temp = bytearray(1)
|
||||
self._buffer = bytearray(17)
|
||||
self._auto_write = auto_write
|
||||
self.fill(0)
|
||||
self._write_cmd(_HT16K33_OSCILATOR_ON)
|
||||
self._blink_rate = None
|
||||
self._brightness = None
|
||||
self.blink_rate = 0
|
||||
self.brightness = brightness
|
||||
self.fill(0)
|
||||
|
||||
def _write_cmd(self, byte):
|
||||
self._temp[0] = byte
|
||||
self.i2c.writeto(self.address, self._temp)
|
||||
|
||||
@property
|
||||
def blink_rate(self):
|
||||
"""The blink rate. Range 0-3."""
|
||||
return self._blink_rate
|
||||
|
||||
@blink_rate.setter
|
||||
def blink_rate(self, rate=None):
|
||||
if not 0 <= rate <= 3:
|
||||
raise ValueError("Blink rate must be an integer in the range: 0-3")
|
||||
rate = rate & 0x03
|
||||
self._blink_rate = rate
|
||||
self._write_cmd(_HT16K33_BLINK_CMD | _HT16K33_BLINK_DISPLAYON | rate << 1)
|
||||
|
||||
@property
|
||||
def brightness(self):
|
||||
"""The brightness. Range 0.0-1.0"""
|
||||
return self._brightness
|
||||
|
||||
@brightness.setter
|
||||
def brightness(self, brightness):
|
||||
if not 0.0 <= brightness <= 1.0:
|
||||
raise ValueError(
|
||||
"Brightness must be a decimal number in the range: 0.0-1.0"
|
||||
)
|
||||
|
||||
self._brightness = brightness
|
||||
xbright = round(15 * brightness)
|
||||
xbright = xbright & 0x0F
|
||||
self._write_cmd(_HT16K33_CMD_BRIGHTNESS | xbright)
|
||||
|
||||
@property
|
||||
def auto_write(self):
|
||||
"""Auto write updates to the display."""
|
||||
return self._auto_write
|
||||
|
||||
@auto_write.setter
|
||||
def auto_write(self, auto_write):
|
||||
if isinstance(auto_write, bool):
|
||||
self._auto_write = auto_write
|
||||
else:
|
||||
raise ValueError("Must set to either True or False.")
|
||||
|
||||
def show(self):
|
||||
"""Refresh the display and show the changes."""
|
||||
# Byte 0 is 0x00, address of LED data register. The remaining 16
|
||||
# bytes are the display register data to set.
|
||||
print(self._buffer)
|
||||
self.i2c.writeto(self.address, self._buffer)
|
||||
|
||||
def fill(self, color):
|
||||
"""Fill the whole display with the given color."""
|
||||
fill = 0xFF if color else 0x00
|
||||
for i in range(16):
|
||||
self._buffer[i + 1] = fill
|
||||
if self._auto_write:
|
||||
self.show()
|
||||
|
||||
def _pixel(self, x, y, color=None):
|
||||
addr = 2 * y + x // 8
|
||||
mask = 1 << x % 8
|
||||
if color is None:
|
||||
return bool(self._buffer[addr + 1] & mask)
|
||||
if color:
|
||||
# set the bit
|
||||
self._buffer[addr + 1] |= mask
|
||||
else:
|
||||
# clear the bit
|
||||
self._buffer[addr + 1] &= ~mask
|
||||
if self._auto_write:
|
||||
self.show()
|
||||
return None
|
||||
|
||||
def _set_buffer(self, i, value):
|
||||
self._buffer[i + 1] = value # Offset by 1 to move past register address.
|
||||
|
||||
def _get_buffer(self, i):
|
||||
return self._buffer[i + 1] # Offset by 1 to move past register address.
|
||||
Reference in New Issue
Block a user