Mercurial > microbit-ht16k33
changeset 0:a5b7961f0b57 default tip
Initial commit
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Thu, 15 Sep 2016 22:40:47 +0200 |
| parents | |
| children | |
| files | ht16k33.py |
| diffstat | 1 files changed, 115 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ht16k33.py Thu Sep 15 22:40:47 2016 +0200 @@ -0,0 +1,115 @@ +_HT16K33_BLINK_CMD = 0x80 +_HT16K33_BLINK_DISPLAYON = 0x01 +_HT16K33_CMD_BRIGHTNESS = 0xE0 +_HT16K33_OSCILATOR_ON = 0x21 + + +class HT16K33: + """The base class for all HT16K33-based backpacks and wings.""" + + def __init__(self, i2c, address=0x70): + self.i2c = i2c + self.address = address + self._temp = bytearray(1) + self.buffer = bytearray(16 + 1) + self.buffer[0] = 0x00 + self.fill(0) + self._write_cmd(_HT16K33_OSCILATOR_ON) + self.blink_rate(0) + self.brightness(15) + + def _write_cmd(self, byte): + """Send a command.""" + self._temp[0] = byte + self.i2c.write(self.address, self._temp) + + def blink_rate(self, rate=None): + """Get or set the blink rate.""" + if rate is None: + return self._blink_rate + rate = rate & 0x02 + self._blink_rate = rate + self._write_cmd(_HT16K33_BLINK_CMD | + _HT16K33_BLINK_DISPLAYON | rate << 1) + + def brightness(self, brightness): + """Get or set the brightness.""" + if brightness is None: + return self._brightness + brightness = brightness & 0x0F + self._brightness = brightness + self._write_cmd(_HT16K33_CMD_BRIGHTNESS | brightness) + + def show(self): + """Actually send all the changes to the device.""" + self.i2c.write(self.address, self.buffer) + + def fill(self, color): + """Fill the display with given color.""" + fill = 0xff if color else 0x00 + for i in range(16): + self.buffer[i + 1] = fill + + def _pixel(self, x, y, color=None): + """Set a single pixel in the frame buffer to specified color.""" + mask = 1 << x + if color is None: + return bool((self.buffer[y + 1] | self.buffer[y + 2] << 8) & mask) + if color: + self.buffer[y * 2 + 1] |= mask & 0xff + self.buffer[y * 2 + 2] |= mask >> 8 + else: + self.buffer[y * 2 + 1] &= ~(mask & 0xff) + self.buffer[y * 2 + 2] &= ~(mask >> 8) + + +class Matrix16x8(HT16K33): + """The double matrix.""" + + def pixel(self, x, y, color=None): + """Set a single pixel in the frame buffer to specified color.""" + if not 0 <= x <= 15: + return + if not 0 <= y <= 7: + return + if x >= 8: + x -= 8 + y += 8 + return super()._pixel(y, x, color) + + +class Matrix8x8(HT16K33): + """The single matrix.""" + + def pixel(self, x, y, color=None): + """Set a single pixel in the frame buffer to specified color.""" + if not 0 <= x <= 7: + return + if not 0 <= y <= 7: + return + x = (x - 1) % 8 + return super()._pixel(x, y, color) + + +class Matrix8x8x2(HT16K33): + """The bi-color matrix.""" + + def pixel(self, x, y, color=None): + """Set a single pixel to specified color.""" + if not 0 <= x <= 7: + return + if not 0 <= y <= 7: + return + if color is not None: + super()._pixel(y, x, (color & 0x01)) + super()._pixel(y + 8, x, (color >> 1) & 0x01) + else: + return super()._pixel(y, x) | super()._pixel(y + 8, x) << 1 + + def fill(self, color): + """Fill the display with given color.""" + fill1 = 0xff if color & 0x01 else 0x00 + fill2 = 0xff if color & 0x02 else 0x00 + for i in range(8): + self.buffer[i * 2] = fill1 + self.buffer[i * 2 + 1] = fill2
