PiClock project
This commit is contained in:
119
ht16k33/ht16k33.py
Normal file
119
ht16k33/ht16k33.py
Normal file
@@ -0,0 +1,119 @@
|
||||
class HT16K33:
|
||||
"""
|
||||
A simple, generic driver for the I2C-connected Holtek HT16K33 controller chip.
|
||||
This release supports MicroPython and CircuitPython
|
||||
|
||||
Bus: I2C
|
||||
Author: Tony Smith (@smittytone)
|
||||
License: MIT
|
||||
Copyright: 2023
|
||||
"""
|
||||
|
||||
# *********** CONSTANTS **********
|
||||
|
||||
HT16K33_GENERIC_DISPLAY_ON = 0x81
|
||||
HT16K33_GENERIC_DISPLAY_OFF = 0x80
|
||||
HT16K33_GENERIC_SYSTEM_ON = 0x21
|
||||
HT16K33_GENERIC_SYSTEM_OFF = 0x20
|
||||
HT16K33_GENERIC_DISPLAY_ADDRESS = 0x00
|
||||
HT16K33_GENERIC_CMD_BRIGHTNESS = 0xE0
|
||||
HT16K33_GENERIC_CMD_BLINK = 0x81
|
||||
|
||||
# *********** PRIVATE PROPERTIES **********
|
||||
|
||||
i2c = None
|
||||
address = 0
|
||||
brightness = 15
|
||||
flash_rate = 0
|
||||
|
||||
# *********** CONSTRUCTOR **********
|
||||
|
||||
def __init__(self, i2c, i2c_address):
|
||||
assert 0x00 <= i2c_address < 0x80, "ERROR - Invalid I2C address in HT16K33()"
|
||||
self.i2c = i2c
|
||||
self.address = i2c_address
|
||||
self.power_on()
|
||||
|
||||
# *********** PUBLIC METHODS **********
|
||||
|
||||
def set_blink_rate(self, rate=0):
|
||||
"""
|
||||
Set the display's flash rate.
|
||||
|
||||
Only four values (in Hz) are permitted: 0, 2, 1, and 0,5.
|
||||
|
||||
Args:
|
||||
rate (int): The chosen flash rate. Default: 0Hz (no flash).
|
||||
"""
|
||||
assert rate in (0, 0.5, 1, 2), "ERROR - Invalid blink rate set in set_blink_rate()"
|
||||
self.blink_rate = rate & 0x03
|
||||
self._write_cmd(self.HT16K33_GENERIC_CMD_BLINK | rate << 1)
|
||||
|
||||
def set_brightness(self, brightness=15):
|
||||
"""
|
||||
Set the display's brightness (ie. duty cycle).
|
||||
|
||||
Brightness values range from 0 (dim, but not off) to 15 (max. brightness).
|
||||
|
||||
Args:
|
||||
brightness (int): The chosen flash rate. Default: 15 (100%).
|
||||
"""
|
||||
if brightness < 0 or brightness > 15: brightness = 15
|
||||
self.brightness = brightness
|
||||
self._write_cmd(self.HT16K33_GENERIC_CMD_BRIGHTNESS | brightness)
|
||||
|
||||
def draw(self):
|
||||
"""
|
||||
Writes the current display buffer to the display itself.
|
||||
|
||||
Call this method after updating the buffer to update
|
||||
the LED itself.
|
||||
"""
|
||||
self._render()
|
||||
|
||||
def update(self):
|
||||
"""
|
||||
Alternative for draw() for backwards compatibility
|
||||
"""
|
||||
self._render()
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clear the buffer.
|
||||
|
||||
Returns:
|
||||
The instance (self)
|
||||
"""
|
||||
for i in range(0, len(self.buffer)): self.buffer[i] = 0x00
|
||||
return self
|
||||
|
||||
def power_on(self):
|
||||
"""
|
||||
Power on the controller and display.
|
||||
"""
|
||||
self._write_cmd(self.HT16K33_GENERIC_SYSTEM_ON)
|
||||
self._write_cmd(self.HT16K33_GENERIC_DISPLAY_ON)
|
||||
|
||||
def power_off(self):
|
||||
"""
|
||||
Power on the controller and display.
|
||||
"""
|
||||
self._write_cmd(self.HT16K33_GENERIC_DISPLAY_OFF)
|
||||
self._write_cmd(self.HT16K33_GENERIC_SYSTEM_OFF)
|
||||
|
||||
# ********** PRIVATE METHODS **********
|
||||
|
||||
def _render(self):
|
||||
"""
|
||||
Write the display buffer out to I2C
|
||||
"""
|
||||
buffer = bytearray(len(self.buffer) + 1)
|
||||
buffer[1:] = self.buffer
|
||||
buffer[0] = 0x00
|
||||
self.i2c.writeto(self.address, bytes(buffer))
|
||||
|
||||
def _write_cmd(self, byte):
|
||||
"""
|
||||
Writes a single command to the HT16K33. A private method.
|
||||
"""
|
||||
self.i2c.writeto(self.address, bytes([byte]))
|
||||
162
ht16k33/ht16k33segmentbig.py
Normal file
162
ht16k33/ht16k33segmentbig.py
Normal file
@@ -0,0 +1,162 @@
|
||||
# Import the base class
|
||||
from ht16k33.ht16k33 import HT16K33
|
||||
|
||||
class HT16K33SegmentBig(HT16K33):
|
||||
"""
|
||||
Micro/Circuit Python class for the Adafruit 1.2-in 4-digit,
|
||||
7-segment LED matrix backpack and equivalent Featherwing.
|
||||
|
||||
Bus: I2C
|
||||
Author: Tony Smith (@smittytone)
|
||||
License: MIT
|
||||
Copyright: 2023
|
||||
"""
|
||||
|
||||
# *********** CONSTANTS **********
|
||||
|
||||
HT16K33_SEGMENT_COLON_ROW = 0x04
|
||||
HT16K33_SEGMENT_MINUS_CHAR = 0x10
|
||||
HT16K33_SEGMENT_DEGREE_CHAR = 0x11
|
||||
HT16K33_SEGMENT_SPACE_CHAR = 0x13
|
||||
|
||||
COLON_CENTRE = 0x02
|
||||
COLON_LEFT_UPPER = 0x04
|
||||
COLON_LEFT_LOWER = 0x08
|
||||
COLON_LEFT = 0x0C
|
||||
DECIMAL_POINT = 0x10
|
||||
|
||||
# The positions of the segments within the buffer
|
||||
POS = (0, 2, 6, 8)
|
||||
|
||||
# Bytearray of the key alphanumeric characters we can show:
|
||||
# 0-9, A-F, minus, degree
|
||||
CHARSET = b'\x3F\x06\x5B\x4F\x66\x6D\x7D\x07\x7F\x6F\x5F\x7C\x58\x5E\x7B\x71\x40\x63\x00'
|
||||
|
||||
# *********** CONSTRUCTOR **********
|
||||
|
||||
def __init__(self, i2c, i2c_address=0x70):
|
||||
self.buffer = bytearray(16)
|
||||
self.point_pattern = 0x00
|
||||
super(HT16K33SegmentBig, self).__init__(i2c, i2c_address)
|
||||
|
||||
# *********** PUBLIC METHODS **********
|
||||
|
||||
def set_colon(self, pattern=0x02):
|
||||
"""
|
||||
Set or unset the segment LED display's colon and decimal point lights.
|
||||
|
||||
This method updates the display buffer, but does not send the buffer to the display itself.
|
||||
Call 'draw()' to render the buffer on the display.
|
||||
|
||||
Args:
|
||||
patter (int) An integer indicating which elements to light (OR the values required). Default: 0x00
|
||||
0x00: no colon
|
||||
0x02: centre colon
|
||||
0x04: left colon, lower dot
|
||||
0x08: left colon, upper dot
|
||||
0x10: decimal point (upper)
|
||||
|
||||
Returns:
|
||||
The instance (self)
|
||||
"""
|
||||
# Bail on incorrect pattern values
|
||||
assert 0 <= pattern < 0x1F, "ERROR - bad patter passed to set_colon()"
|
||||
|
||||
self.point_pattern = pattern
|
||||
self.buffer[self.HT16K33_SEGMENT_COLON_ROW] = pattern
|
||||
return self
|
||||
|
||||
def set_glyph(self, glyph, digit=0):
|
||||
"""
|
||||
Present a user-defined character glyph at the specified digit.
|
||||
|
||||
Glyph values are 8-bit integers representing a pattern of set LED segments.
|
||||
The value is calculated by setting the bit(s) representing the segment(s) you want illuminated.
|
||||
Bit-to-segment mapping runs clockwise from the top around the outside of the matrix; the inner segment is bit 6:
|
||||
|
||||
0
|
||||
_
|
||||
5 | | 1
|
||||
| |
|
||||
- <----- 6
|
||||
4 | | 2
|
||||
| _ |
|
||||
3
|
||||
|
||||
This method updates the display buffer, but does not send the buffer to the display itself.
|
||||
Call 'update()' to render the buffer on the display.
|
||||
|
||||
Args:
|
||||
glyph (int): The glyph pattern.
|
||||
digit (int): The digit to show the glyph. Default: 0 (leftmost digit).
|
||||
|
||||
Returns:
|
||||
The instance (self)
|
||||
"""
|
||||
# Bail on incorrect row numbers or character values
|
||||
assert 0 <= digit < 4, "ERROR - Invalid digit (0-3) set in set_glyph()"
|
||||
assert 0 <= glyph < 0x80, "ERROR - Invalid glyph (0x00-0xFF) set in set_glyph()"
|
||||
|
||||
self.buffer[self.POS[digit]] = glyph & 0x7F
|
||||
return self
|
||||
|
||||
def set_number(self, number, digit=0):
|
||||
"""
|
||||
Present single decimal value (0-9) at the specified digit.
|
||||
|
||||
This method updates the display buffer, but does not send the buffer to the display itself.
|
||||
Call 'update()' to render the buffer on the display.
|
||||
|
||||
Args:
|
||||
number (int): The number to show.
|
||||
digit (int): The digit to show the number. Default: 0 (leftmost digit).
|
||||
|
||||
Returns:
|
||||
The instance (self)
|
||||
"""
|
||||
# Bail on incorrect row numbers or character values
|
||||
assert 0 <= digit < 4, "ERROR - Invalid digit (0-3) set in set_number()"
|
||||
assert 0 <= number < 10, "ERROR - Invalid value (0-9) set in set_number()"
|
||||
|
||||
return self.set_character(str(number), digit)
|
||||
|
||||
def set_character(self, char, digit=0):
|
||||
"""
|
||||
Present single alphanumeric character at the specified digit.
|
||||
|
||||
Only characters from the class' character set are available:
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d ,e, f, -.
|
||||
Other characters can be defined and presented using 'set_glyph()'.
|
||||
|
||||
This method updates the display buffer, but does not send the buffer to the display itself.
|
||||
Call 'draw()' to render the buffer on the display.
|
||||
|
||||
Args:
|
||||
char (string): The character to show.
|
||||
digit (int): The digit to show the number. Default: 0 (leftmost digit).
|
||||
has_dot (bool): Whether the decimal point to the right of the digit should be lit. Default: False.
|
||||
|
||||
Returns:
|
||||
The instance (self)
|
||||
"""
|
||||
# Bail on incorrect row numbers
|
||||
assert 0 <= digit < 4, "ERROR - Invalid digit set in set_character()"
|
||||
|
||||
char = char.lower()
|
||||
char_val = 0xFF
|
||||
if char == "deg":
|
||||
char_val = self.HT16K33_SEGMENT_DEGREE_CHAR
|
||||
elif char == '-':
|
||||
char_val = self.HT16K33_SEGMENT_MINUS_CHAR
|
||||
elif char == ' ':
|
||||
char_val = self.HT16K33_SEGMENT_SPACE_CHAR
|
||||
elif char in 'abcdef':
|
||||
char_val = ord(char) - 87
|
||||
elif char in '0123456789':
|
||||
char_val = ord(char) - 48
|
||||
|
||||
# Bail on incorrect character values
|
||||
assert char_val != 0xFF, "ERROR - Invalid char string set in set_character()"
|
||||
|
||||
self.buffer[self.POS[digit]] = self.CHARSET[char_val]
|
||||
return self
|
||||
Reference in New Issue
Block a user