Raspberry Pi Pico
Four Letter pHAT
The Four Letter pHAT is a Raspberry Pi breakout made by the company Pimoroni. It's a segemented alphanumeric display with 14 segements used to display characters. As a result, you can display digits, letters and many punctuation characters and symbols. The breakout uses an HT16K33 integrated cricuit to drive the LED segments. You control the display using i2c.
This is an image showing it connected to a Pico using a Waveshare accessory, which makes the connections easier. The display looks much cooler than this in real life. The high speed refreshing means that the LEDs look less bright in photographs than they appear in real life. The display does look much brighter than this suggests and all segements do appear in the same brightness.
My connections are GP2 and GP3 to pins 2 and 3 on the pHAT. You also need to connect to the 5V, 3V3 and GND pins of the pHAT. You can see a diagram showing the pHAT pins at Gadgetoid's superb Pinout site,https://pinout.xyz/pinout/four_letter_phat.
Here is my library code for interacting with the pHAT. Save it to the Pico as flh.py. There is a font defined that you can use to display strings of four letters. I haven't added any code for scrolling. That leaves a project for you to work on if you wish.
from machine import Pin, I2C class FLH: ADDRESS = 0x70 BLINK_CMD = 0x80 CMD_BRIGHTNESS = 0xE0 DIGITS = { ' ': 0b0000000000000000, '!': 0b0000000000000110, '"': 0b0000001000100000, '#': 0b0001001011001110, '$': 0b0001001011101101, '%': 0b0000110000100100, '&': 0b0010001101011101, '\'': 0b0000010000000000, '(': 0b0010010000000000, ')': 0b0000100100000000, '*': 0b0011111111000000, '+': 0b0001001011000000, ',': 0b0000100000000000, '-': 0b0000000011000000, '.': 0b0000000000000000, '/': 0b0000110000000000, '0': 0b0000110000111111, '1': 0b0000000000000110, '2': 0b0000000011011011, '3': 0b0000000010001111, '4': 0b0000000011100110, '5': 0b0010000001101001, '6': 0b0000000011111101, '7': 0b0000000000000111, '8': 0b0000000011111111, '9': 0b0000000011101111, ':': 0b0001001000000000, ';': 0b0000101000000000, '<': 0b0010010000000000, '=': 0b0000000011001000, '>': 0b0000100100000000, '?': 0b0001000010000011, '@': 0b0000001010111011, 'A': 0b0000000011110111, 'B': 0b0001001010001111, 'C': 0b0000000000111001, 'D': 0b0001001000001111, 'E': 0b0000000011111001, 'F': 0b0000000001110001, 'G': 0b0000000010111101, 'H': 0b0000000011110110, 'I': 0b0001001000000000, 'J': 0b0000000000011110, 'K': 0b0010010001110000, 'L': 0b0000000000111000, 'M': 0b0000010100110110, 'N': 0b0010000100110110, 'O': 0b0000000000111111, 'P': 0b0000000011110011, 'Q': 0b0010000000111111, 'R': 0b0010000011110011, 'S': 0b0000000011101101, 'T': 0b0001001000000001, 'U': 0b0000000000111110, 'V': 0b0000110000110000, 'W': 0b0010100000110110, 'X': 0b0010110100000000, 'Y': 0b0001010100000000, 'Z': 0b0000110000001001, 'a': 0b0001000001011000, 'b': 0b0010000001111000, 'c': 0b0000000011011000, 'd': 0b0000100010001110, 'e': 0b0000100001011000, 'f': 0b0000000001110001, 'g': 0b0000010010001110, 'h': 0b0001000001110000, 'i': 0b0001000000000000, 'j': 0b0000000000001110, 'k': 0b0011011000000000, 'l': 0b0000000000110000, 'm': 0b0001000011010100, 'n': 0b0001000001010000, 'o': 0b0000000011011100, 'p': 0b0000000101110000, 'q': 0b0000010010000110, 'r': 0b0000000001010000, 's': 0b0010000010001000, 't': 0b0000000001111000, 'u': 0b0000000000011100, 'v': 0b0010000000000100, 'w': 0b0010100000010100, 'x': 0b0010100011000000, 'y': 0b0010000000001100, 'z': 0b0000100001001000 } def __init__(self,i, d, c): self.buffer = bytearray([0]*16) self.i2c=I2C(i,sda=Pin(d), scl=Pin(c)) self.i2c.writeto(self.ADDRESS,b'\x21') # 0 to 3 self.blink_rate(0) # 0 to 15 self.set_brightness(15) self.update_display() def set_brightness(self,b): self.i2c.writeto(self.ADDRESS,bytes([self.CMD_BRIGHTNESS | b])) def blink_rate(self, b): self.i2c.writeto(self.ADDRESS,bytes([self.BLINK_CMD | 1 | (b << 1)])) def update_display(self): data = bytearray([0]) + self.buffer self.i2c.writeto(self.ADDRESS,data) def clear(self): self.buffer = bytearray([0]*16) self.update_display() def raw_digit(self, value, position): self.buffer[position*2] = value & 0xFF self.buffer[position*2+1] = (value >> 8) & 0xFF def set_digit(self, value, position): self.raw_digit(self.DIGITS.get(str(value), 0x00), position) def set_decimal(self, decimal, pos): if pos < 0 or pos > 3: return # Set bit 14 if decimal: self.buffer[pos*2+1] |= (1 << 6) else: self.buffer[pos*2+1] &= ~(1 << 6) def print_str(self, value, ralign=True): # Calculate starting position of digits pos = (4-len(value)) if ralign else 0 for i, ch in enumerate(value): self.set_digit(ch,i+pos)
Here is some test code to save as main.py,
from flh import FLH from time import sleep four = FLH(1,2,3) # test word printing four.print_str("Byte") four.update_display() sleep(5) #test decimals for i in range(4): four.set_decimal(True, i) four.update_display() sleep(0.5) four.clear() # test numbers for i in range(10000): four.print_str(str(i), ralign="True") four.update_display() sleep(0.1)