HUB75 Scrolling wavy text and clock demo

This commit is contained in:
Phil Howard 2021-12-01 19:28:16 +00:00
parent 8ae311e3a5
commit 4dc3f9b9c4
10 changed files with 476 additions and 16 deletions

View File

@ -77,7 +77,7 @@ Hub75::Hub75(uint width, uint height, Pixel *buffer, PanelType panel_type, bool
}
}
void Hub75::set_rgb(uint x, uint y, uint8_t r, uint8_t g, uint8_t b) {
void Hub75::set_color(uint x, uint y, uint32_t c) {
int offset = 0;
if(x >= width || y >= height) return;
if(y >= height / 2) {
@ -87,20 +87,15 @@ void Hub75::set_rgb(uint x, uint y, uint8_t r, uint8_t g, uint8_t b) {
} else {
offset = (y * width + x) * 2;
}
front_buffer[offset] = Pixel(r, g, b);
front_buffer[offset].color = c;
}
void Hub75::set_rgb(uint x, uint y, uint8_t r, uint8_t g, uint8_t b) {
set_color(x, y, Pixel(r, g, b).color);
}
void Hub75::set_hsv(uint x, uint y, float h, float s, float v) {
int offset = 0;
if(x >= width || y >= height) return;
if(y >= height / 2) {
y -= height / 2;
offset = (y * width + x) * 2;
offset += 1;
} else {
offset = (y * width + x) * 2;
}
front_buffer[offset] = hsv_to_rgb(h, s, v);
set_color(x, y, hsv_to_rgb(h, s, v).color);
}
void Hub75::FM6126A_write_register(uint16_t value, uint8_t position) {

View File

@ -37,6 +37,7 @@ constexpr uint16_t GAMMA_10BIT[256] = {
struct Pixel {
uint32_t color;
constexpr Pixel() : color(0) {};
constexpr Pixel(uint32_t color) : color(color) {};
constexpr Pixel(uint8_t r, uint8_t g, uint8_t b) : color((GAMMA_10BIT[b] << 20) | (GAMMA_10BIT[g] << 10) | GAMMA_10BIT[r]) {};
};
@ -45,6 +46,8 @@ enum PanelType {
PANEL_FM6126A,
};
Pixel hsv_to_rgb(float h, float s, float v);
class Hub75 {
public:
uint width;
@ -113,6 +116,7 @@ class Hub75 {
void FM6126A_write_register(uint16_t value, uint8_t position);
void FM6126A_setup();
void set_color(uint x, uint y, uint32_t c);
void set_rgb(uint x, uint y, uint8_t r, uint8_t g, uint8_t b);
void set_hsv(uint x, uint y, float r, float g, float b);
void display_update();

View File

@ -0,0 +1,100 @@
letter_width = 10
letter_height = 14
font = [
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # " "
[0x0ffc, 0x0a04, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "!"
[0x007c, 0x0044, 0x007c, 0x0044, 0x007c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # """
[0x03f0, 0x02d0, 0x0edc, 0x0804, 0x0edc, 0x0edc, 0x0804, 0x0edc, 0x02d0, 0x03f0], # "#"
[0x0ef8, 0x0b8c, 0x1b76, 0x1002, 0x1b76, 0x0cd4, 0x079c, 0x0000, 0x0000, 0x0000], # "$"
[0x0038, 0x006c, 0x0f54, 0x09ec, 0x0e78, 0x079c, 0x0de4, 0x0abc, 0x0d80, 0x0700], # "%"
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "&"
[0x007c, 0x0044, 0x007c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "'"
[0x03f0, 0x0e1c, 0x19e6, 0x173a, 0x1c0e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "("
[0x1c0e, 0x173a, 0x19e6, 0x0e1c, 0x03f0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ")"
[0x00fc, 0x00b4, 0x00cc, 0x00cc, 0x00b4, 0x00fc, 0x0000, 0x0000, 0x0000, 0x0000], # "*"
[0x01c0, 0x0140, 0x0770, 0x0410, 0x0770, 0x0140, 0x01c0, 0x0000, 0x0000, 0x0000], # "+"
[0x1c00, 0x1700, 0x1900, 0x0f00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ","
[0x01c0, 0x0140, 0x0140, 0x0140, 0x0140, 0x0140, 0x01c0, 0x0000, 0x0000, 0x0000], # "-"
[0x0e00, 0x0a00, 0x0e00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "."
[0x1e00, 0x1380, 0x1ce0, 0x0738, 0x01ce, 0x0072, 0x001e, 0x0000, 0x0000, 0x0000], # "/"
[0x07f8, 0x0c0c, 0x0bf4, 0x0a14, 0x0bf4, 0x0c0c, 0x07f8, 0x0000, 0x0000, 0x0000], # "0"
[0x0e70, 0x0a58, 0x0bec, 0x0804, 0x0bfc, 0x0a00, 0x0e00, 0x0000, 0x0000, 0x0000], # "1"
[0x0e38, 0x0b2c, 0x09b4, 0x0ad4, 0x0b74, 0x0b8c, 0x0ef8, 0x0000, 0x0000, 0x0000], # "2"
[0x0738, 0x0d2c, 0x0b34, 0x0bf4, 0x0b34, 0x0ccc, 0x07f8, 0x0000, 0x0000, 0x0000], # "3"
[0x03c0, 0x0270, 0x0298, 0x0eec, 0x0804, 0x0efc, 0x0380, 0x0000, 0x0000, 0x0000], # "4"
[0x0efc, 0x0a84, 0x0ab4, 0x0ab4, 0x0bb4, 0x0c74, 0x07dc, 0x0000, 0x0000, 0x0000], # "5"
[0x07f8, 0x0c0c, 0x0bb4, 0x0ab4, 0x0bb4, 0x0c74, 0x07dc, 0x0000, 0x0000, 0x0000], # "6"
[0x001c, 0x0014, 0x0f94, 0x08f4, 0x0f34, 0x01c4, 0x007c, 0x0000, 0x0000, 0x0000], # "7"
[0x07f8, 0x0c4c, 0x0bb4, 0x0ab4, 0x0bb4, 0x0c4c, 0x07f8, 0x0000, 0x0000, 0x0000], # "8"
[0x0ef8, 0x0b8c, 0x0b74, 0x0b54, 0x0b74, 0x0c0c, 0x07f8, 0x0000, 0x0000, 0x0000], # "9"
[0x0e1c, 0x0a14, 0x0e1c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ":"
[0x1c00, 0x171c, 0x1914, 0x0f1c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ";"
[0x0380, 0x06c0, 0x0d60, 0x0ba0, 0x0ee0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "<"
[0x0ee0, 0x0aa0, 0x0aa0, 0x0aa0, 0x0aa0, 0x0aa0, 0x0aa0, 0x0ee0, 0x0000, 0x0000], # "="
[0x0ee0, 0x0ba0, 0x0d60, 0x06c0, 0x0380, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ">"
[0x0000, 0x001c, 0x0fd4, 0x0a74, 0x0fb4, 0x00cc, 0x0078, 0x0000, 0x0000, 0x0000], # "?"
[0x0ff0, 0x1818, 0x37ec, 0x2c74, 0x2bb4, 0x2bb4, 0x3c0c, 0x07f8, 0x0000, 0x0000], # "@"
[0x0f80, 0x08f0, 0x0f1c, 0x0164, 0x0f1c, 0x08f0, 0x0f80, 0x0000, 0x0000, 0x0000], # "A"
[0x0ffc, 0x0804, 0x0bb4, 0x0bb4, 0x0c4c, 0x07f8, 0x0000, 0x0000, 0x0000, 0x0000], # "B"
[0x07f8, 0x0c0c, 0x0bf4, 0x0a14, 0x0a14, 0x0e1c, 0x0000, 0x0000, 0x0000, 0x0000], # "C"
[0x0ffc, 0x0804, 0x0bf4, 0x0bf4, 0x0c0c, 0x07f8, 0x0000, 0x0000, 0x0000, 0x0000], # "D"
[0x0ffc, 0x0804, 0x0bb4, 0x0ab4, 0x0ab4, 0x0efc, 0x0000, 0x0000, 0x0000, 0x0000], # "E"
[0x0ffc, 0x0804, 0x0fb4, 0x00b4, 0x00f4, 0x001c, 0x0000, 0x0000, 0x0000, 0x0000], # "F"
[0x07f8, 0x0c0c, 0x0bf4, 0x0bd4, 0x0b54, 0x0c5c, 0x07c0, 0x0000, 0x0000, 0x0000], # "G"
[0x0ffc, 0x0804, 0x0fbc, 0x00a0, 0x0fbc, 0x0804, 0x0ffc, 0x0000, 0x0000, 0x0000], # "H"
[0x0e1c, 0x0a14, 0x0bf4, 0x0804, 0x0bf4, 0x0a14, 0x0e1c, 0x0000, 0x0000, 0x0000], # "I"
[0x0e1c, 0x0a14, 0x0bf4, 0x0c04, 0x07f4, 0x0014, 0x001c, 0x0000, 0x0000, 0x0000], # "J"
[0x0ffc, 0x0804, 0x0fbc, 0x0e5c, 0x09e4, 0x0f3c, 0x0000, 0x0000, 0x0000, 0x0000], # "K"
[0x0ffc, 0x0804, 0x0bfc, 0x0a00, 0x0a00, 0x0e00, 0x0000, 0x0000, 0x0000, 0x0000], # "L"
[0x0ffc, 0x0804, 0x0fec, 0x00d8, 0x00b0, 0x00b0, 0x00d8, 0x0fec, 0x0804, 0x0ffc], # "M"
[0x0ffc, 0x0804, 0x0fcc, 0x0738, 0x0cfc, 0x0804, 0x0ffc, 0x0000, 0x0000, 0x0000], # "N"
[0x07f8, 0x0c0c, 0x0bf4, 0x0a14, 0x0a14, 0x0bf4, 0x0c0c, 0x07f8, 0x0000, 0x0000], # "O"
[0x0ffc, 0x0804, 0x0f74, 0x0174, 0x018c, 0x00f8, 0x0000, 0x0000, 0x0000, 0x0000], # "P"
[0x07f8, 0x0c0c, 0x0bf4, 0x0a14, 0x0a14, 0x1bf4, 0x140c, 0x17f8, 0x1c00, 0x0000], # "Q"
[0x0ffc, 0x0804, 0x0f74, 0x0e74, 0x098c, 0x0ff8, 0x0000, 0x0000, 0x0000, 0x0000], # "R"
[0x0ef8, 0x0b8c, 0x0b74, 0x0b54, 0x0cd4, 0x079c, 0x0000, 0x0000, 0x0000, 0x0000], # "S"
[0x001c, 0x0014, 0x0ff4, 0x0804, 0x0ff4, 0x0014, 0x001c, 0x0000, 0x0000, 0x0000], # "T"
[0x07fc, 0x0c04, 0x0bfc, 0x0a00, 0x0bfc, 0x0c04, 0x07fc, 0x0000, 0x0000, 0x0000], # "U"
[0x01fc, 0x0704, 0x0cfc, 0x0b80, 0x0cfc, 0x0704, 0x01fc, 0x0000, 0x0000, 0x0000], # "V"
[0x01fc, 0x0704, 0x0cfc, 0x0bc0, 0x0c40, 0x0bc0, 0x0cfc, 0x0704, 0x01fc, 0x0000], # "W"
[0x0f3c, 0x09e4, 0x0edc, 0x0330, 0x0edc, 0x09e4, 0x0f3c, 0x0000, 0x0000, 0x0000], # "X"
[0x003c, 0x00e4, 0x0f9c, 0x0870, 0x0f9c, 0x00e4, 0x003c, 0x0000, 0x0000, 0x0000], # "Y"
[0x0f1c, 0x0994, 0x0af4, 0x0b34, 0x0bd4, 0x0a64, 0x0e3c, 0x0000, 0x0000, 0x0000], # "Z"
[0x0ffc, 0x0804, 0x0bf4, 0x0a14, 0x0e1c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "["
[0x001e, 0x0072, 0x01ce, 0x0738, 0x1ce0, 0x1380, 0x1e00, 0x0000, 0x0000, 0x0000], # "\"
[0x0e1c, 0x0a14, 0x0bf4, 0x0804, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "]"
[0x0070, 0x0058, 0x006c, 0x0034, 0x006c, 0x0058, 0x0070, 0x0000, 0x0000, 0x0000], # "^"
[0x1c00, 0x1400, 0x1400, 0x1400, 0x1400, 0x1400, 0x1400, 0x1c00, 0x0000, 0x0000], # "_"
[0x000e, 0x001a, 0x0036, 0x002c, 0x0038, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "`"
[0x07c0, 0x0c60, 0x0ba0, 0x0aa0, 0x0ba0, 0x0c60, 0x0bc0, 0x0e00, 0x0000, 0x0000], # "a"
[0x0ffc, 0x0804, 0x0bbc, 0x0ba0, 0x0c60, 0x07c0, 0x0000, 0x0000, 0x0000, 0x0000], # "b"
[0x07c0, 0x0c60, 0x0ba0, 0x0aa0, 0x0ee0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "c"
[0x07c0, 0x0c60, 0x0ba0, 0x0bbc, 0x0804, 0x0ffc, 0x0000, 0x0000, 0x0000, 0x0000], # "d"
[0x07c0, 0x0c60, 0x0aa0, 0x0aa0, 0x0b60, 0x0fc0, 0x0000, 0x0000, 0x0000, 0x0000], # "e"
[0x0ff8, 0x080c, 0x0fb4, 0x00f4, 0x001c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "f"
[0x1fc0, 0x3660, 0x2da0, 0x2da0, 0x2da0, 0x3060, 0x1fc0, 0x0000, 0x0000, 0x0000], # "g"
[0x0ffc, 0x0804, 0x0fbc, 0x0fa0, 0x0860, 0x0fc0, 0x0000, 0x0000, 0x0000, 0x0000], # "h"
[0x0ff8, 0x0828, 0x0ff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "i"
[0x1c00, 0x1400, 0x17f8, 0x1828, 0x0ff8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "j"
[0x0ffc, 0x0804, 0x0efc, 0x0d60, 0x0ba0, 0x0ee0, 0x0000, 0x0000, 0x0000, 0x0000], # "k"
[0x07fc, 0x0c04, 0x0bfc, 0x0a00, 0x0e00, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "l"
[0x0fc0, 0x0860, 0x0fa0, 0x07a0, 0x0460, 0x07a0, 0x0fa0, 0x0860, 0x0fc0, 0x0000], # "m"
[0x0fc0, 0x0860, 0x0fa0, 0x0fa0, 0x0860, 0x0fc0, 0x0000, 0x0000, 0x0000, 0x0000], # "n"
[0x07c0, 0x0c60, 0x0ba0, 0x0aa0, 0x0ba0, 0x0c60, 0x07c0, 0x0000, 0x0000, 0x0000], # "o"
[0x3fe0, 0x2020, 0x3da0, 0x05a0, 0x0660, 0x03c0, 0x0000, 0x0000, 0x0000, 0x0000], # "p"
[0x03c0, 0x0660, 0x05a0, 0x3da0, 0x2020, 0x37e0, 0x1c00, 0x0000, 0x0000, 0x0000], # "q"
[0x0fc0, 0x0860, 0x0fa0, 0x00a0, 0x00e0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "r"
[0x0fc0, 0x0b60, 0x0aa0, 0x0da0, 0x07e0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "s"
[0x01c0, 0x0770, 0x0c10, 0x0b70, 0x0bc0, 0x0e00, 0x0000, 0x0000, 0x0000, 0x0000], # "t"
[0x07e0, 0x0c20, 0x0be0, 0x0be0, 0x0c20, 0x07e0, 0x0000, 0x0000, 0x0000, 0x0000], # "u"
[0x01e0, 0x0720, 0x0ce0, 0x0b80, 0x0ce0, 0x0720, 0x01e0, 0x0000, 0x0000, 0x0000], # "v"
[0x01e0, 0x0720, 0x0ce0, 0x0b80, 0x0c80, 0x0b80, 0x0ce0, 0x0720, 0x01e0, 0x0000], # "w"
[0x0ee0, 0x0ba0, 0x0d60, 0x06c0, 0x0d60, 0x0ba0, 0x0ee0, 0x0000, 0x0000, 0x0000], # "x"
[0x1de0, 0x1720, 0x1ae0, 0x0d80, 0x06e0, 0x0320, 0x01e0, 0x0000, 0x0000, 0x0000], # "y"
[0x0ee0, 0x0ba0, 0x09a0, 0x0aa0, 0x0b20, 0x0ba0, 0x0ee0, 0x0000, 0x0000, 0x0000], # "z"
[0x01e0, 0x0f3c, 0x18c6, 0x17fa, 0x1c0e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "{"
[0x1ffe, 0x1002, 0x1ffe, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "|"
[0x1c0e, 0x17fa, 0x18c6, 0x0f3c, 0x01e0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # "}"
[0x0380, 0x02c0, 0x0340, 0x0340, 0x02c0, 0x02c0, 0x0340, 0x01c0, 0x0000, 0x0000], # "~"
[0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000], # ""
]

View File

@ -0,0 +1,100 @@
letter_width = 8
letter_height = 12
font = [
[0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # " "
[0x2fc, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "!"
[0x01c, 0x000, 0x01c, 0x000, 0x000, 0x000, 0x000, 0x000], # """
[0x090, 0x090, 0x3fc, 0x090, 0x090, 0x3fc, 0x090, 0x090], # "#"
[0x238, 0x244, 0x7fe, 0x244, 0x184, 0x000, 0x000, 0x000], # "$"
[0x008, 0x014, 0x308, 0x0c0, 0x030, 0x10c, 0x280, 0x100], # "%"
[0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "&"
[0x01c, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "'"
[0x0f0, 0x30c, 0x402, 0x000, 0x000, 0x000, 0x000, 0x000], # "("
[0x402, 0x30c, 0x0f0, 0x000, 0x000, 0x000, 0x000, 0x000], # ")"
[0x024, 0x018, 0x018, 0x024, 0x000, 0x000, 0x000, 0x000], # "*"
[0x040, 0x040, 0x1f0, 0x040, 0x040, 0x000, 0x000, 0x000], # "+"
[0x400, 0x300, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # ","
[0x040, 0x040, 0x040, 0x040, 0x040, 0x000, 0x000, 0x000], # "-"
[0x200, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "."
[0x600, 0x180, 0x060, 0x018, 0x006, 0x000, 0x000, 0x000], # "/"
[0x1f8, 0x204, 0x204, 0x204, 0x1f8, 0x000, 0x000, 0x000], # "0"
[0x210, 0x208, 0x3fc, 0x200, 0x200, 0x000, 0x000, 0x000], # "1"
[0x208, 0x304, 0x284, 0x244, 0x238, 0x000, 0x000, 0x000], # "2"
[0x108, 0x204, 0x204, 0x264, 0x198, 0x000, 0x000, 0x000], # "3"
[0x0c0, 0x0b0, 0x088, 0x3fc, 0x080, 0x000, 0x000, 0x000], # "4"
[0x23c, 0x224, 0x224, 0x224, 0x1c4, 0x000, 0x000, 0x000], # "5"
[0x1f8, 0x224, 0x224, 0x224, 0x1c4, 0x000, 0x000, 0x000], # "6"
[0x004, 0x004, 0x384, 0x064, 0x01c, 0x000, 0x000, 0x000], # "7"
[0x1d8, 0x224, 0x224, 0x224, 0x1d8, 0x000, 0x000, 0x000], # "8"
[0x238, 0x244, 0x244, 0x244, 0x1f8, 0x000, 0x000, 0x000], # "9"
[0x204, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # ":"
[0x400, 0x304, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # ";"
[0x080, 0x140, 0x220, 0x000, 0x000, 0x000, 0x000, 0x000], # "<"
[0x220, 0x220, 0x220, 0x220, 0x220, 0x220, 0x000, 0x000], # "="
[0x220, 0x140, 0x080, 0x000, 0x000, 0x000, 0x000, 0x000], # ">"
[0x000, 0x004, 0x2c4, 0x024, 0x018, 0x000, 0x000, 0x000], # "?"
[0x3f0, 0x408, 0x9c4, 0xa24, 0xa24, 0x1f8, 0x000, 0x000], # "@"
[0x380, 0x070, 0x04c, 0x070, 0x380, 0x000, 0x000, 0x000], # "A"
[0x3fc, 0x224, 0x224, 0x1d8, 0x000, 0x000, 0x000, 0x000], # "B"
[0x1f8, 0x204, 0x204, 0x204, 0x000, 0x000, 0x000, 0x000], # "C"
[0x3fc, 0x204, 0x204, 0x1f8, 0x000, 0x000, 0x000, 0x000], # "D"
[0x3fc, 0x224, 0x224, 0x224, 0x000, 0x000, 0x000, 0x000], # "E"
[0x3fc, 0x024, 0x024, 0x004, 0x000, 0x000, 0x000, 0x000], # "F"
[0x1f8, 0x204, 0x204, 0x244, 0x1c0, 0x000, 0x000, 0x000], # "G"
[0x3fc, 0x020, 0x020, 0x020, 0x3fc, 0x000, 0x000, 0x000], # "H"
[0x204, 0x204, 0x3fc, 0x204, 0x204, 0x000, 0x000, 0x000], # "I"
[0x204, 0x204, 0x1fc, 0x004, 0x004, 0x000, 0x000, 0x000], # "J"
[0x3fc, 0x020, 0x0d0, 0x30c, 0x000, 0x000, 0x000, 0x000], # "K"
[0x3fc, 0x200, 0x200, 0x200, 0x000, 0x000, 0x000, 0x000], # "L"
[0x3fc, 0x008, 0x010, 0x020, 0x020, 0x010, 0x008, 0x3fc], # "M"
[0x3fc, 0x018, 0x060, 0x180, 0x3fc, 0x000, 0x000, 0x000], # "N"
[0x1f8, 0x204, 0x204, 0x204, 0x204, 0x1f8, 0x000, 0x000], # "O"
[0x3fc, 0x044, 0x044, 0x038, 0x000, 0x000, 0x000, 0x000], # "P"
[0x1f8, 0x204, 0x204, 0x204, 0x204, 0x5f8, 0x400, 0x000], # "Q"
[0x3fc, 0x044, 0x0c4, 0x338, 0x000, 0x000, 0x000, 0x000], # "R"
[0x238, 0x244, 0x244, 0x184, 0x000, 0x000, 0x000, 0x000], # "S"
[0x004, 0x004, 0x3fc, 0x004, 0x004, 0x000, 0x000, 0x000], # "T"
[0x1fc, 0x200, 0x200, 0x200, 0x1fc, 0x000, 0x000, 0x000], # "U"
[0x07c, 0x180, 0x200, 0x180, 0x07c, 0x000, 0x000, 0x000], # "V"
[0x07c, 0x180, 0x200, 0x1c0, 0x200, 0x180, 0x07c, 0x000], # "W"
[0x30c, 0x090, 0x060, 0x090, 0x30c, 0x000, 0x000, 0x000], # "X"
[0x00c, 0x030, 0x3c0, 0x030, 0x00c, 0x000, 0x000, 0x000], # "Y"
[0x304, 0x284, 0x264, 0x214, 0x20c, 0x000, 0x000, 0x000], # "Z"
[0x3fc, 0x204, 0x204, 0x000, 0x000, 0x000, 0x000, 0x000], # "["
[0x006, 0x018, 0x060, 0x180, 0x600, 0x000, 0x000, 0x000], # "\"
[0x204, 0x204, 0x3fc, 0x000, 0x000, 0x000, 0x000, 0x000], # "]"
[0x010, 0x008, 0x004, 0x008, 0x010, 0x000, 0x000, 0x000], # "^"
[0x400, 0x400, 0x400, 0x400, 0x400, 0x400, 0x000, 0x000], # "_"
[0x002, 0x004, 0x008, 0x000, 0x000, 0x000, 0x000, 0x000], # "`"
[0x1c0, 0x220, 0x220, 0x220, 0x1c0, 0x200, 0x000, 0x000], # "a"
[0x3fc, 0x220, 0x220, 0x1c0, 0x000, 0x000, 0x000, 0x000], # "b"
[0x1c0, 0x220, 0x220, 0x000, 0x000, 0x000, 0x000, 0x000], # "c"
[0x1c0, 0x220, 0x220, 0x3fc, 0x000, 0x000, 0x000, 0x000], # "d"
[0x1c0, 0x2a0, 0x2a0, 0x240, 0x000, 0x000, 0x000, 0x000], # "e"
[0x3f8, 0x024, 0x004, 0x000, 0x000, 0x000, 0x000, 0x000], # "f"
[0x4c0, 0x920, 0x920, 0x920, 0x7c0, 0x000, 0x000, 0x000], # "g"
[0x3fc, 0x020, 0x020, 0x3c0, 0x000, 0x000, 0x000, 0x000], # "h"
[0x3e8, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "i"
[0x400, 0x400, 0x3e8, 0x000, 0x000, 0x000, 0x000, 0x000], # "j"
[0x3fc, 0x080, 0x140, 0x220, 0x000, 0x000, 0x000, 0x000], # "k"
[0x1fc, 0x200, 0x200, 0x000, 0x000, 0x000, 0x000, 0x000], # "l"
[0x3c0, 0x020, 0x020, 0x1c0, 0x020, 0x020, 0x3c0, 0x000], # "m"
[0x3c0, 0x020, 0x020, 0x3c0, 0x000, 0x000, 0x000, 0x000], # "n"
[0x1c0, 0x220, 0x220, 0x220, 0x1c0, 0x000, 0x000, 0x000], # "o"
[0xfe0, 0x120, 0x120, 0x0c0, 0x000, 0x000, 0x000, 0x000], # "p"
[0x0c0, 0x120, 0x120, 0xfe0, 0x400, 0x000, 0x000, 0x000], # "q"
[0x3c0, 0x020, 0x020, 0x000, 0x000, 0x000, 0x000, 0x000], # "r"
[0x240, 0x2a0, 0x120, 0x000, 0x000, 0x000, 0x000, 0x000], # "s"
[0x040, 0x1f0, 0x240, 0x200, 0x000, 0x000, 0x000, 0x000], # "t"
[0x1e0, 0x200, 0x200, 0x1e0, 0x000, 0x000, 0x000, 0x000], # "u"
[0x060, 0x180, 0x200, 0x180, 0x060, 0x000, 0x000, 0x000], # "v"
[0x060, 0x180, 0x200, 0x180, 0x200, 0x180, 0x060, 0x000], # "w"
[0x220, 0x140, 0x080, 0x140, 0x220, 0x000, 0x000, 0x000], # "x"
[0x460, 0x280, 0x100, 0x080, 0x060, 0x000, 0x000, 0x000], # "y"
[0x220, 0x320, 0x2a0, 0x260, 0x220, 0x000, 0x000, 0x000], # "z"
[0x060, 0x39c, 0x402, 0x000, 0x000, 0x000, 0x000, 0x000], # "{"
[0x7fe, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # "|"
[0x402, 0x39c, 0x060, 0x000, 0x000, 0x000, 0x000, 0x000], # "}"
[0x080, 0x040, 0x040, 0x080, 0x080, 0x040, 0x000, 0x000], # "~"
[0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000], # ""
]

View File

@ -0,0 +1,53 @@
from time import ticks_ms
import math
from machine import RTC
import hub75
# from font_8x12 import font, letter_width, letter_height
from font_10x14 import font, letter_width, letter_height
WIDTH, HEIGHT = 128, 64
rtc = RTC()
hub = hub75.Hub75(WIDTH, HEIGHT, stb_invert=True)
hub.start()
hub.clear()
t_s = ticks_ms()
f_s = ticks_ms() / 1000.0
frames = 0
def scroll_text(text, y, t):
text_length = len(text)
x = int(t)
letter = int((x / letter_width) % text_length)
pixel = x % letter_width
char = ord(text[letter])
for s_x in range(WIDTH):
col = font[char - 32][pixel]
s_y = y + int(math.sin((t / 3.0) + s_x / 30.0) * 8)
hub.set_color_masked(s_x, s_y, col, hub75.color_hsv((t + s_x) / WIDTH, 1.0, 1.0))
pixel += 1
if pixel == letter_width:
pixel = 0
letter += 1
if letter == text_length:
letter = 0
char = ord(text[letter])
while True:
year, month, day, wd, hour, minute, second, _ = rtc.datetime()
text = " {:02}:{:02}:{:02} {:04}/{:02}/{:02}".format(hour, minute, second, year, month, day)
hub.clear()
t = (ticks_ms() - t_s) / 50.0
scroll_text(text, int(HEIGHT / 2) - int(letter_height / 2), t)
hub.flip()
frames += 1
if frames % 60 == 0:
f_e = ticks_ms() / 1000.0
print(frames / (f_e - f_s))

View File

@ -0,0 +1,50 @@
from time import ticks_ms
import math
import hub75
# from font_8x12 import font, letter_width, letter_height
from font_10x14 import font, letter_width, letter_height
WIDTH, HEIGHT = 64, 64
hub = hub75.Hub75(WIDTH, HEIGHT, stb_invert=True)
hub.start()
hub.clear()
text = " Hello World!"
t_s = ticks_ms()
f_s = ticks_ms() / 1000.0
frames = 0
def scroll_text(text, y, t):
text_length = len(text)
x = int(t)
letter = int((x / letter_width) % text_length)
pixel = x % letter_width
char = ord(text[letter])
for s_x in range(WIDTH):
col = font[char - 32][pixel]
s_y = y + int(math.sin((t / 3.0) + s_x / 30.0) * 8)
hub.set_color_masked(s_x, s_y, col, hub75.color_hsv(s_x / WIDTH, 1.0, 1.0))
pixel += 1
if pixel == letter_width:
pixel = 0
letter += 1
if letter == text_length:
letter = 0
char = ord(text[letter])
while True:
hub.clear()
t = (ticks_ms() - t_s) / 50.0
scroll_text(text, int(HEIGHT / 2) - int(letter_height / 2), t)
hub.flip()
frames += 1
if frames % 60 == 0:
f_e = ticks_ms() / 1000.0
print(frames / (f_e - f_s))

View File

@ -0,0 +1,70 @@
# Interstate 75 <!-- omit in toc -->
The Interstate 75 library is intended for the Interstate 75 "HUB75" matrix panel driver board.
It can, in theory, be used with your own custom wiring, though custom pin assignments are not supported yet.
- [Notes On PIO Limitations](#notes-on-pio-limitations)
- [Getting Started](#getting-started)
- [FM6216A Panels](#fm6216a-panels)
- [Set A Pixel](#set-a-pixel)
- [RGB](#rgb)
- [HSV](#hsv)
## Notes On PIO Limitations
The Interstate 75 driver uses the PIO hardware on the RP2040. There are only two PIOs with four state machines each, and i75 uses one of these (`PIO0`) and two state machines- one for clocking out pixels, and another for latching/lighting a row.
## Getting Started
Contruct a new `Hub75` instance, specifying the width/height of the display and any additional options.
```python
import hub75
WIDTH = 64
HEIGHT = 64
matrix = hub75.Hub75(WIDTH, HEIGHT, stb_invert=True)
```
Use `stb_invert` if you see a missing middle row corruption on the top row.
Start the matrix strip by calling `start`. This sets up DMA and PIO to drive your panel, pulling rows from the back buffer and refreshing as fast as it can.
```python
matrix.start()
```
### FM6216A Panels
Some panels - based on the FM6126A chips - require a couple of register settings in order for them to display anything at all. Interstate 75 will set these for you if you specify `panel_type=hub75.PANEL_FM6126A`. Eg:
```python
import hub75
WIDTH = 64
HEIGHT = 64
matrix = hub75.Hub75(WIDTH, HEIGHT, panel_type=hub75.PANEL_FM6126A)
```
## Set A Pixel
You can set the colour of an pixel in either the RGB colourspace, or HSV (Hue, Saturation, Value). HSV is useful for creating rainbow patterns.
### RGB
Set the top left-most LED - `0, 0` - to Purple `255, 0, 255`:
```python
matrixx.set_rgb(0, 0, 255, 0, 255)
```
### HSV
Set the top left-most LED - `0, o` - to Red `0.0`:
```python
matrix.set_hsv(0, 0, 0.0, 1.0, 1.0)
```

View File

@ -3,20 +3,29 @@
/***** Methods *****/
MP_DEFINE_CONST_FUN_OBJ_1(Hub75___del___obj, Hub75___del__);
MP_DEFINE_CONST_FUN_OBJ_KW(Hub75_set_color_obj, 3, Hub75_set_color);
MP_DEFINE_CONST_FUN_OBJ_KW(Hub75_set_rgb_obj, 5, Hub75_set_rgb);
MP_DEFINE_CONST_FUN_OBJ_KW(Hub75_set_hsv_obj, 5, Hub75_set_hsv);
MP_DEFINE_CONST_FUN_OBJ_KW(Hub75_set_color_masked_obj, 5, Hub75_set_color_masked);
MP_DEFINE_CONST_FUN_OBJ_2(Hub75_set_all_color_obj, Hub75_set_all_color);
MP_DEFINE_CONST_FUN_OBJ_KW(Hub75_set_all_hsv_obj, 3, Hub75_set_all_hsv);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_clear_obj, Hub75_clear);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_start_obj, Hub75_start);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_stop_obj, Hub75_stop);
MP_DEFINE_CONST_FUN_OBJ_1(Hub75_flip_obj, Hub75_flip);
MP_DEFINE_CONST_FUN_OBJ_3(Hub75_color_obj, Hub75_color);
MP_DEFINE_CONST_FUN_OBJ_3(Hub75_color_hsv_obj, Hub75_color_hsv);
/***** Binding of Methods *****/
STATIC const mp_rom_map_elem_t Hub75_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&Hub75___del___obj) },
{ MP_ROM_QSTR(MP_QSTR_set_color), MP_ROM_PTR(&Hub75_set_color_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_rgb), MP_ROM_PTR(&Hub75_set_rgb_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_hsv), MP_ROM_PTR(&Hub75_set_hsv_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_color_masked), MP_ROM_PTR(&Hub75_set_color_masked_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_all_hsv), MP_ROM_PTR(&Hub75_set_all_hsv_obj) },
{ MP_ROM_QSTR(MP_QSTR_set_all_color), MP_ROM_PTR(&Hub75_set_all_color_obj) },
{ MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&Hub75_clear_obj) },
{ MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&Hub75_start_obj) },
{ MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&Hub75_stop_obj) },
@ -41,6 +50,8 @@ STATIC const mp_map_elem_t hub75_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_Hub75), (mp_obj_t)&Hub75_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PANEL_GENERIC), MP_ROM_INT(0) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_PANEL_FM6126A), MP_ROM_INT(1) },
{ MP_ROM_QSTR(MP_QSTR_color), MP_ROM_PTR(&Hub75_color_obj) },
{ MP_ROM_QSTR(MP_QSTR_color_hsv), MP_ROM_PTR(&Hub75_color_hsv_obj) }
};
STATIC MP_DEFINE_CONST_DICT(mp_module_hub75_globals, hub75_globals_table);

View File

@ -139,10 +139,6 @@ void Hub75_display_update() {
mp_obj_t Hub75_start(mp_obj_t self_in) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
//size_t stack_size = 0;
//mp_thread_create(&Hub75_display_update, nullptr, &stack_size);
//multicore_reset_core1();
//multicore_launch_core1(Hub75_display_update);
self->hub75->start(dma_complete);
return mp_const_none;
}
@ -153,6 +149,67 @@ mp_obj_t Hub75_stop(mp_obj_t self_in) {
return mp_const_none;
}
mp_obj_t Hub75_set_color_masked(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_x, ARG_y, ARG_mask, ARG_color };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_mask, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_color, MP_ARG_REQUIRED | MP_ARG_INT },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int x = args[ARG_x].u_int;
int y = args[ARG_y].u_int;
int c = args[ARG_color].u_int;
int m = args[ARG_mask].u_int;
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Hub75_obj_t);
for(auto py = 0; py < 32; py++) {
if(m & (1 << py)) {
self->hub75->set_color(x, py + y, c);
}
}
return mp_const_none;
}
mp_obj_t Hub75_color(mp_obj_t r, mp_obj_t g, mp_obj_t b) {
return mp_obj_new_int(Pixel(mp_obj_get_int(r), mp_obj_get_int(g), mp_obj_get_int(b)).color);
}
mp_obj_t Hub75_color_hsv(mp_obj_t h, mp_obj_t s, mp_obj_t v) {
return mp_obj_new_int(hsv_to_rgb(mp_obj_get_float(h), mp_obj_get_float(s), mp_obj_get_float(v)).color);
}
mp_obj_t Hub75_set_color(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_x, ARG_y, ARG_color };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT },
{ MP_QSTR_color, MP_ARG_REQUIRED | MP_ARG_INT },
};
// Parse args.
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
int x = args[ARG_x].u_int;
int y = args[ARG_y].u_int;
int c = args[ARG_color].u_int;
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(args[ARG_self].u_obj, _Hub75_obj_t);
self->hub75->set_color(x, y, c);
return mp_const_none;
}
mp_obj_t Hub75_set_rgb(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_x, ARG_y, ARG_r, ARG_g, ARG_b };
static const mp_arg_t allowed_args[] = {
@ -207,6 +264,20 @@ mp_obj_t Hub75_set_hsv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_arg
return mp_const_none;
}
mp_obj_t Hub75_set_all_color(mp_obj_t self_in, mp_obj_t color) {
_Hub75_obj_t *self = MP_OBJ_TO_PTR2(self_in, _Hub75_obj_t);
int c = mp_obj_get_int(color);
for (auto x = 0u; x < self->hub75->width; x++) {
for (auto y = 0u; y < self->hub75->height; y++) {
self->hub75->set_color(x, y, c);
}
}
return mp_const_none;
}
mp_obj_t Hub75_set_all_hsv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_self, ARG_h, ARG_s, ARG_v };
static const mp_arg_t allowed_args[] = {

View File

@ -1,5 +1,6 @@
// Include MicroPython API.
#include "py/runtime.h"
#include "py/objstr.h"
/***** Extern of Class Definition *****/
extern const mp_obj_type_t Hub75_type;
@ -10,8 +11,13 @@ extern mp_obj_t Hub75_make_new(const mp_obj_type_t *type, size_t n_args, size_t
extern mp_obj_t Hub75___del__(mp_obj_t self_in);
extern mp_obj_t Hub75_start(mp_obj_t self_in);
extern mp_obj_t Hub75_stop(mp_obj_t self_in);
extern mp_obj_t Hub75_set_color(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_set_rgb(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_set_hsv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_set_color_masked(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_color(mp_obj_t r, mp_obj_t g, mp_obj_t b);
extern mp_obj_t Hub75_color_hsv(mp_obj_t h, mp_obj_t s, mp_obj_t v);
extern mp_obj_t Hub75_set_all_hsv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
extern mp_obj_t Hub75_set_all_color(mp_obj_t self_in, mp_obj_t color);
extern mp_obj_t Hub75_clear(mp_obj_t self_in);
extern mp_obj_t Hub75_flip(mp_obj_t self_in);