Skip to content

Instantly share code, notes, and snippets.

@jaygreco
Last active April 11, 2022 04:07
Show Gist options
  • Save jaygreco/e3d4447d34fd07d16c777b25328c8f0e to your computer and use it in GitHub Desktop.
Save jaygreco/e3d4447d34fd07d16c777b25328c8f0e to your computer and use it in GitHub Desktop.
TIDBIT LED matrix example
#pragma once
#define USE_FONT_3x5
#ifdef USE_FONT_5x7
// standard ascii 5x7 font
// defines ascii characters 0x20-0x7F (32-127)
#define FONT_OFFSET 32
#define FONT_WIDTH 5
#define FONT_HEIGHT 7
static const uint8_t PROGMEM font[] = {
0x00, 0x00, 0x00, 0x00, 0x00,// (space)
0x00, 0x00, 0x5F, 0x00, 0x00,// !
0x00, 0x07, 0x00, 0x07, 0x00,// "
0x14, 0x7F, 0x14, 0x7F, 0x14,// #
0x24, 0x2A, 0x7F, 0x2A, 0x12,// $
0x23, 0x13, 0x08, 0x64, 0x62,// %
0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x1C, 0x22, 0x41, 0x00,// (
0x00, 0x41, 0x22, 0x1C, 0x00,// )
0x08, 0x2A, 0x1C, 0x2A, 0x08,// *
0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x50, 0x30, 0x00, 0x00,// ,
0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x60, 0x60, 0x00, 0x00,// .
0x20, 0x10, 0x08, 0x04, 0x02,// /
0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41,// <
0x14, 0x14, 0x14, 0x14, 0x14,// =
0x41, 0x22, 0x14, 0x08, 0x00,// >
0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x32, 0x49, 0x79, 0x41, 0x3E,// @
0x7E, 0x11, 0x11, 0x11, 0x7E,// A
0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x7F, 0x09, 0x09, 0x01, 0x01,// F
0x3E, 0x41, 0x41, 0x51, 0x32,// G
0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x7F, 0x02, 0x04, 0x02, 0x7F,// M
0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x46, 0x49, 0x49, 0x49, 0x31,// S
0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x7F, 0x20, 0x18, 0x20, 0x7F,// W
0x63, 0x14, 0x08, 0x14, 0x63,// X
0x03, 0x04, 0x78, 0x04, 0x03,// Y
0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41,// [
0x02, 0x04, 0x08, 0x10, 0x20,// "\"
0x41, 0x41, 0x7F, 0x00, 0x00,// ]
0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x01, 0x02, 0x04, 0x00,// `
0x20, 0x54, 0x54, 0x54, 0x78,// a
0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x38, 0x44, 0x44, 0x44, 0x20,// c
0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x38, 0x54, 0x54, 0x54, 0x18,// e
0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x08, 0x14, 0x54, 0x54, 0x3C,// g
0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x20, 0x40, 0x44, 0x3D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44,// k
0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x38, 0x44, 0x44, 0x44, 0x38,// o
0x7C, 0x14, 0x14, 0x14, 0x08,// p
0x08, 0x14, 0x14, 0x18, 0x7C,// q
0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x48, 0x54, 0x54, 0x54, 0x20,// s
0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x44, 0x28, 0x10, 0x28, 0x44,// x
0x0C, 0x50, 0x50, 0x50, 0x3C,// y
0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x00, 0x08, 0x36, 0x41, 0x00,// {
0x00, 0x00, 0x7F, 0x00, 0x00,// |
0x00, 0x41, 0x36, 0x08, 0x00,// }
0x08, 0x08, 0x2A, 0x1C, 0x08,// ->
0x08, 0x1C, 0x2A, 0x08, 0x08 // <-
};
#endif
#ifdef USE_FONT_3x5
// micro ascii 3x5 font
// defines ascii characters 0x20-0x7F (32-127)
#define FONT_OFFSET 32
#define FONT_WIDTH 3
#define FONT_HEIGHT 5
static const uint8_t PROGMEM font[] = {
0x00, 0x00, 0x00, // 32
0xB8, 0x00, 0x00, // 33
0x18, 0x00, 0x18, // 34
0xF8, 0x70, 0xF8, // 35
0x10, 0xF8, 0x40, // 36
0x00, 0x00, 0x00, // 37
0x00, 0x00, 0x00, // 38
0x18, 0x00, 0x00, // 39
0x70, 0x88, 0x00, // 40
0x88, 0x70, 0x00, // 41
0x70, 0x70, 0x70, // 42
0x20, 0x70, 0x20, // 43
0xC0, 0x00, 0x00, // 44
0x20, 0x20, 0x20, // 45
0x80, 0x00, 0x00, // 46
0xC0, 0x20, 0x18, // 47
0xF8, 0x88, 0xF8, // 48
0x90, 0xF8, 0x80, // 49
0xE8, 0xA8, 0xB8, // 50
0xA8, 0xA8, 0xF8, // 51
0x38, 0x20, 0xF8, // 52
0xB8, 0xA8, 0xE8, // 53
0xF8, 0xA8, 0xE8, // 54
0x08, 0xE8, 0x18, // 55
0xF8, 0xA8, 0xF8, // 56
0xB8, 0xA8, 0xF8, // 57
0x50, 0x00, 0x00, // 58
0xD0, 0x00, 0x00, // 59
0x20, 0x50, 0x88, // 60
0x50, 0x50, 0x50, // 61
0x88, 0x50, 0x20, // 62
0x08, 0xA8, 0x18, // 63
0x70, 0xE8, 0x70, // 64
0xF0, 0x28, 0xF0, // 65
0xF8, 0xA8, 0x50, // 66
0xF8, 0x88, 0x88, // 67
0xF8, 0x88, 0x70, // 68
0xF8, 0xA8, 0xA8, // 69
0xF8, 0x28, 0x28, // 70
0xF8, 0x88, 0xC8, // 71
0xF8, 0x20, 0xF8, // 72
0x88, 0xF8, 0x88, // 73
0x40, 0x80, 0x78, // 74
0xF8, 0x20, 0xD8, // 75
0xF8, 0x80, 0x80, // 76
0xF8, 0x30, 0xF8, // 77
0xF8, 0x08, 0xF8, // 78
0xF8, 0x88, 0xF8, // 79
0xF8, 0x28, 0x38, // 80
0x78, 0x48, 0xF8, // 81
0xF8, 0x28, 0xD0, // 82
0xB8, 0xA8, 0xE8, // 83
0x08, 0xF8, 0x08, // 84
0xF8, 0x80, 0xF8, // 85
0x78, 0x80, 0x78, // 86
0xF8, 0x60, 0xF8, // 87
0xD8, 0x20, 0xD8, // 88
0x18, 0xE0, 0x18, // 89
0xC8, 0xA8, 0x98, // 90
0xF8, 0x88, 0x00, // 91
0x18, 0x20, 0xC0, // 92
0x88, 0xF8, 0x00, // 93
0x10, 0x08, 0x10, // 94
0x80, 0x80, 0x80, // 95
0x08, 0x10, 0x00, // 96
0xE8, 0xA8, 0xF8, // 97
0xF8, 0xA0, 0xE0, // 98
0xE0, 0xA0, 0xA0, // 99
0xE0, 0xA0, 0xF8, // 100
0xF8, 0xA8, 0xB8, // 101
0xF8, 0x28, 0x08, // 102
0xB8, 0xA8, 0xF8, // 103
0xF8, 0x20, 0xE0, // 104
0x00, 0xE8, 0x00, // 105
0x40, 0x80, 0x68, // 106
0xF8, 0x40, 0xA0, // 107
0x00, 0xF8, 0x00, // 108
0xF0, 0x20, 0xF0, // 109
0xE0, 0x20, 0xC0, // 110
0xE0, 0xA0, 0xE0, // 111
0xF8, 0x28, 0x30, // 112
0x38, 0x28, 0xF0, // 113
0xE0, 0x20, 0x20, // 114
0x90, 0xA8, 0x48, // 115
0x10, 0xF8, 0x10, // 116
0xE0, 0x80, 0xE0, // 117
0x60, 0x80, 0x60, // 118
0xF0, 0x40, 0xF0, // 119
0xA0, 0x40, 0xA0, // 120
0x30, 0xA0, 0xF0, // 121
0xC8, 0xA8, 0x98, // 122
0x20, 0xF8, 0x88, // 123
0xF8, 0x00, 0x00, // 124
0x88, 0xF8, 0x20, // 125
0x60, 0x20, 0x30, // 126
0x00, 0x00, 0x00 // 127
};
#endif
/* Copyright 2021 Jay Greco
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include QMK_KEYBOARD_H
#include "HT16K33_GFX.h"
#include "font.h"
#include <stdlib.h>
// My LED matrix has address 0x71, but the default is 0x70. FYI.
#define DISP_ADDR 0x71
HT16K33 *disp;
uint16_t delay_timer;
uint8_t c = 32;
// Clear one single pixel.
// Note: only writes to the display buffer.
// Call HT16K33_refresh() to write to the display.
void clearPixel(HT16K33 *disp, uint8_t x, uint8_t y) {
if ((y < 0) || (y >= 8)) return;
if ((x < 0) || (x >= 16)) return;
disp->buf[y] &= ~(1 << x);
}
// Draw one single pixel.
// Note: only writes to the display buffer.
// Call HT16K33_refresh() to write to the display.
void drawPixel(HT16K33 *disp, uint8_t x, uint8_t y) {
if ((y < 0) || (y >= 8)) return;
if ((x < 0) || (x >= 16)) return;
disp->buf[y] |= 1 << x;
}
// Draws a vertically in the y direction using one font byte.
void line2px(HT16K33 *disp, uint8_t x, uint8_t bmp) {
for (uint8_t b=0; b<8; b++) {
uint8_t line = (bmp & (1 << b)) >> b;
uprintf("0x%02X %d:%d\n", bmp, b, line);
if (line) {
drawPixel(disp, x, b);
} else {
clearPixel(disp, x, b);
}
}
}
// Draw a single ASCII char at the specified x offset.
//todo: need vertical offset for centering
//todo: add flip, rotate
//todo: needs sanity checks for newlines, etc
void drawChar(HT16K33 *disp, uint8_t offset, uint8_t c) {
for (int i=0; i<FONT_WIDTH; i++) {
uint16_t idx = ((c - FONT_OFFSET) * FONT_WIDTH) + i;
uint8_t line = pgm_read_byte_near(font + idx);
uprintf("%c(%d)/%d: font[%d]=0x%02X\n", c, c, i, idx, line);
line2px(disp, i+offset, line);
}
}
enum layers {
_BASE = 0,
_VIA1,
_VIA2,
_VIA3
};
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BASE] = LAYOUT(
KC_PSLS, KC_PAST, KC_PMNS,
KC_VOLD, KC_VOLU, KC_P7, KC_P8, KC_P9, KC_PPLS,
KC_TRNS, KC_TRNS, KC_P4, KC_P5, KC_P6, KC_PPLS,
KC_TRNS, KC_TRNS, KC_P1, KC_P2, KC_P3, KC_PENT,
KC_TRNS, KC_TRNS, KC_P0, KC_P0, KC_PDOT, KC_PENT
),
[_VIA1] = LAYOUT(
___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___
),
[_VIA2] = LAYOUT(
___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___
),
[_VIA3] = LAYOUT(
___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___,
___, ___, ___, ___, ___, ___
),
};
void matrix_init_user(void) {
disp = newHT16K33(8, DISP_ADDR);
delay_timer = timer_read();
}
void matrix_scan_user() {
if (timer_elapsed(delay_timer) > 1000) {
delay_timer = timer_read();
HT16K33_clear(disp);
// Testing with a single char
// drawChar(disp, 0, c);
// c += 1;
#ifdef USE_FONT_5x7
// If using 5x7 font, two chars fit on the display.
drawChar(disp, 0, c);
drawChar(disp, FONT_WIDTH+1, c+1);
c += 2;
#endif
#ifdef USE_FONT_3x5
// If using 3x5 font, four chars fit on the display!
drawChar(disp, 0, c);
drawChar(disp, FONT_WIDTH+1, c+1);
drawChar(disp, 2*(FONT_WIDTH+1), c+2);
drawChar(disp, 3*(FONT_WIDTH+1), c+3);
c += 4;
#endif
HT16K33_refresh(disp);
if (c > 127) {
c = 32;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment