Skip to content

Instantly share code, notes, and snippets.

@markfink
Last active June 28, 2022 06:27
Show Gist options
  • Save markfink/2c70f76b4b8122f0bc15 to your computer and use it in GitHub Desktop.
Save markfink/2c70f76b4b8122f0bc15 to your computer and use it in GitHub Desktop.
Arduino LED Matrix 16 x 128 three colors
#include <avr/pgmspace.h>
#include "pins_arduino.h"
// based on myMatrix Arduino Library
// by Silviu - www.openhardware.ro
// MIT License (MIT)
// Connections to board
const byte pinSTB=8;
const byte pinClock=12;
const byte pinRed=10;
const byte pinGreen=11;
const byte pinOE=2;
const byte pinRowA=3;
const byte pinRowB=4;
const byte pinRowC=5;
const byte pinRowD=6;
byte scanRow = 0;
unsigned long counter;
//Insert message here ("message ")
char message[] = " Challenge ACCEPTED!!! ";
// ---------------------------------------------------------------------------------------------------
const byte RED = 0b10;
const byte GREEN = 0b01;
const byte YELLOW = 0b11;
const byte BLACK = 0b00;
struct Color {
byte R;
byte G;
};
#define BUFFER_INIT_256 BUFFER_INIT_128 BUFFER_INIT_128
#define BUFFER_INIT_128 BUFFER_INIT_100 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_8
#define BUFFER_INIT_100 BUFFER_INIT_50 BUFFER_INIT_50
#define BUFFER_INIT_50 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10 BUFFER_INIT_10
#define BUFFER_INIT_10 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2
#define BUFFER_INIT_8 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2 BUFFER_INIT_2
#define BUFFER_INIT_2 BUFFER_INIT_1 BUFFER_INIT_1
#define BUFFER_INIT_1 {0x00, 0x00},
Color buffer[256] = {BUFFER_INIT_256};
// ---------------------------------------------------------------------------------------------------
// FONTS sourced from various locations on the internet
// full ASCII character set (8x16) (1520 bytes)
static const uint8_t font8x16_basic[96][16] PROGMEM = {
/* (32) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* ! (33) */ {0x00, 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x3C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00},
/* " (34) */ {0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* # (35) */ {0x00, 0x00, 0x00, 0x00, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x6C, 0xFE, 0x6C, 0x6C, 0x00, 0x00, 0x00},
/* $ (36) */ {0x00, 0x18, 0x18, 0x7C, 0xC6, 0xC2, 0xC0, 0x7C, 0x06, 0x06, 0x86, 0xC6, 0x7C, 0x18, 0x18, 0x00},
/* % (37) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xC6, 0x0C, 0x18, 0x30, 0x60, 0xC6, 0x86, 0x00, 0x00, 0x00},
/* & (38) */ {0x00, 0x00, 0x00, 0x38, 0x6C, 0x6C, 0x38, 0x76, 0xDC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00},
/* ' (39) */ {0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* ( (40) */ {0x00, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, 0x00, 0x00},
/* ) (41) */ {0x00, 0x00, 0x00, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00},
/* * (42) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
/* + (43) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
/* , (44) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00},
/* - (45) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* . (46) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00},
/* / (47) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0x80, 0x00, 0x00, 0x00},
/* 0 (48) */ {0x00, 0x00, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xDB, 0xDB, 0xC3, 0xC3, 0x66, 0x3C, 0x00, 0x00, 0x00},
/* 1 (49) */ {0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, 0x00, 0x00},
/* 2 (50) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC0, 0xC6, 0xFE, 0x00, 0x00, 0x00},
/* 3 (51) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0x06, 0x06, 0x3C, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* 4 (52) */ {0x00, 0x00, 0x00, 0x0C, 0x1C, 0x3C, 0x6C, 0xCC, 0xFE, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, 0x00, 0x00},
/* 5 (53) */ {0x00, 0x00, 0x00, 0xFE, 0xC0, 0xC0, 0xC0, 0xFC, 0x06, 0x06, 0x06, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* 6 (54) */ {0x00, 0x00, 0x00, 0x38, 0x60, 0xC0, 0xC0, 0xFC, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* 7 (55) */ {0x00, 0x00, 0x00, 0xFE, 0xC6, 0x06, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00},
/* 8 (56) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* 9 (57) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x06, 0x06, 0x0C, 0x78, 0x00, 0x00, 0x00},
/* : (58) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
/* ; (59) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00},
/* < (60) */ {0x00, 0x00, 0x00, 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00},
/* = (61) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* > (62) */ {0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00},
/* ? (63) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x0C, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00},
/* @ (64) */ {0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xDE, 0xDE, 0xDE, 0xDC, 0xC0, 0x7C, 0x00, 0x00, 0x00},
/* A (65) */ {0x00, 0x00, 0x00, 0x10, 0x38, 0x6C, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00},
/* B (66) */ {0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x66, 0x66, 0xFC, 0x00, 0x00, 0x00},
/* C (67) */ {0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xC0, 0xC0, 0xC2, 0x66, 0x3C, 0x00, 0x00, 0x00},
/* D (68) */ {0x00, 0x00, 0x00, 0xF8, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6C, 0xF8, 0x00, 0x00, 0x00},
/* E (69) */ {0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00},
/* F (70) */ {0x00, 0x00, 0x00, 0xFE, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00},
/* G (71) */ {0x00, 0x00, 0x00, 0x3C, 0x66, 0xC2, 0xC0, 0xC0, 0xDE, 0xC6, 0xC6, 0x66, 0x3A, 0x00, 0x00, 0x00},
/* H (72) */ {0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xFE, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00},
/* I (73) */ {0x00, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00},
/* J (74) */ {0x00, 0x00, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0xCC, 0xCC, 0xCC, 0x78, 0x00, 0x00, 0x00},
/* K (75) */ {0x00, 0x00, 0x00, 0xE6, 0x66, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00},
/* L (76) */ {0x00, 0x00, 0x00, 0xF0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xFE, 0x00, 0x00, 0x00},
/* M (77) */ {0x00, 0x00, 0x00, 0xC3, 0xE7, 0xFF, 0xFF, 0xDB, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x00, 0x00, 0x00},
/* N (78) */ {0x00, 0x00, 0x00, 0xC6, 0xE6, 0xF6, 0xFE, 0xDE, 0xCE, 0xC6, 0xC6, 0xC6, 0xC6, 0x00, 0x00, 0x00},
/* O (79) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* P (80) */ {0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00},
/* Q (81) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xD6, 0xDE, 0x7C, 0x0C, 0x0E, 0x00},
/* R (82) */ {0x00, 0x00, 0x00, 0xFC, 0x66, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00},
/* S (83) */ {0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0x60, 0x38, 0x0C, 0x06, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* T (84) */ {0x00, 0x00, 0x00, 0xFF, 0xDB, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00},
/* U (85) */ {0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* V (86) */ {0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00},
/* W (87) */ {0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xDB, 0xDB, 0xFF, 0x66, 0x66, 0x00, 0x00, 0x00},
/* X (88) */ {0x00, 0x00, 0x00, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0x00, 0x00, 0x00},
/* Y (89) */ {0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00},
/* Z (90) */ {0x00, 0x00, 0x00, 0xFF, 0xC3, 0x86, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC3, 0xFF, 0x00, 0x00, 0x00},
/* [ (91) */ {0x00, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C, 0x00, 0x00, 0x00},
/* \ (92) */ {0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x70, 0x38, 0x1C, 0x0E, 0x06, 0x02, 0x00, 0x00, 0x00},
/* ] (93) */ {0x00, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C, 0x00, 0x00, 0x00},
/* ^ (94) */ {0x00, 0x10, 0x38, 0x6C, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* _ (95) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00},
/* ` (96) */ {0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* a (97) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0C, 0x7C, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00},
/* b (98) */ {0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x78, 0x6C, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00},
/* c (99) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC0, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* d (100) */ {0x00, 0x00, 0x00, 0x1C, 0x0C, 0x0C, 0x3C, 0x6C, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00},
/* e (101) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xFE, 0xC0, 0xC0, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* f (102) */ {0x00, 0x00, 0x00, 0x38, 0x6C, 0x64, 0x60, 0xF0, 0x60, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00},
/* g (103) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0xCC, 0x78},
/* h (104) */ {0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x6C, 0x76, 0x66, 0x66, 0x66, 0x66, 0xE6, 0x00, 0x00, 0x00},
/* i (105) */ {0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00},
/* j (106) */ {0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3C},
/* k (107) */ {0x00, 0x00, 0x00, 0xE0, 0x60, 0x60, 0x66, 0x6C, 0x78, 0x78, 0x6C, 0x66, 0xE6, 0x00, 0x00, 0x00},
/* l (108) */ {0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00},
/* m (109) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xFF, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, 0x00, 0x00},
/* n (110) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00},
/* o (111) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* p (112) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, 0xF0},
/* q (113) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x7C, 0x0C, 0x0C, 0x1E},
/* r (114) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDC, 0x76, 0x66, 0x60, 0x60, 0x60, 0xF0, 0x00, 0x00, 0x00},
/* s (115) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0xC6, 0x60, 0x38, 0x0C, 0xC6, 0x7C, 0x00, 0x00, 0x00},
/* t (116) */ {0x00, 0x00, 0x00, 0x10, 0x30, 0x30, 0xFC, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x00},
/* u (117) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x76, 0x00, 0x00, 0x00},
/* v (118) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00},
/* w (119) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC3, 0xC3, 0xDB, 0xDB, 0xFF, 0x66, 0x00, 0x00, 0x00},
/* x (120) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0xC3, 0x00, 0x00, 0x00},
/* y (121) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0xC6, 0x7E, 0x06, 0x0C, 0xF8},
/* z (122) */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0xCC, 0x18, 0x30, 0x60, 0xC6, 0xFE, 0x00, 0x00, 0x00},
/* { (123) */ {0x00, 0x00, 0x00, 0x0E, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, 0x00, 0x00},
/* | (124) */ {0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00},
/* } (125) */ {0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00},
/* ~ (126) */ {0x00, 0x00, 0x00, 0x76, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* BLK(127)*/ {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
};
// function to colorize a pixel
// color 2 Bit, (R)ed (G)reen 0b000000RG
void setPixel(uint8_t x ,uint8_t y, uint8_t color)
{
uint8_t myindex = (y*16)+x/8; // 16 segments per row
uint8_t mybitmask = 7 -(x % 8);
bitWrite(buffer[myindex].R, mybitmask, (color & 0b00000010)); // red
bitWrite(buffer[myindex].G, mybitmask, (color & 0b00000001)); // green
}
// function to print a character at column
void printChar(uint8_t x_offset, uint8_t fg_color, uint8_t bg_color, byte ch) {
if (0 != (x_offset % 8)) return; // x_offset not a multiple of 8
if ((ch>9) && (ch<32)) return; // invalid character
const uint8_t y_offset = 0;
for (uint8_t y=0; y<16; y++){
for (uint8_t i=0; i<8; i++){
if(bitRead(pgm_read_byte(&font8x16_basic[ch-32][y]),7-i)) setPixel(x_offset+i, y_offset+y, fg_color);
else setPixel(x_offset+i, y_offset+y, bg_color);
}
}
}
// function to scrol the text message to the left
void hScroll(uint8_t fg_color, uint8_t bg_color, char *mystring){
// offset starts with 0
// this means text starts in upper left corner
for (int offset=0; offset < ((lenString(mystring)-8)*8-1); offset++){
for (byte x=0; x<128; x++){ // 128
for (byte y=0; y<16; y++){
byte color=bg_color;
if (getPixelMessage(x+offset,y,mystring)) color=fg_color;
setPixel(x,y,color);
}
}
delay(40);
}
}
byte getPixelMessage(uint16_t x, uint16_t y, char *p){
p=p+x/8;
return getPixelChar(x%8, y, *p);
}
byte getPixelChar(uint8_t x, uint8_t y, char ch){
return bitRead(pgm_read_byte(&font8x16_basic[ch-32][y]),7-x);
}
// length of the message string
uint8_t lenString(char *p){
unsigned int retVal=0;
while(*p!='\0'){
retVal++;
p++;
}
return retVal;
}
void drawRectangle(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color){
drawHLine(x1,x2,y1,color);
drawHLine(x1,x2,y2,color);
drawVLine(x1,y1,y2,color);
drawVLine(x2,y1,y2,color);
}
void drawVLine(uint16_t x, uint16_t y1, uint16_t y2, uint8_t color){
for (uint16_t y = y1; y <= y2; y++) {
setPixel(x,y,color);
}
}
void drawHLine(uint16_t x1, uint16_t x2, uint16_t y, uint8_t color){
for (uint16_t x = x1; x <= x2; x++) {
setPixel(x,y,color);
}
}
void clearScreen(){
for (uint8_t i=0; i<256; i++) // buffer size
{
buffer[i].R=0;
buffer[i].G=0;
}
}
// helper function to paint one row
void shiftOut(uint8_t row) {
const uint8_t bitRed = digitalPinToBitMask(pinRed);
volatile uint8_t *outRed = portOutputRegister(digitalPinToPort(pinRed));
const uint8_t bitGreen = digitalPinToBitMask(pinGreen);
volatile uint8_t *outGreen = portOutputRegister(digitalPinToPort(pinGreen));
const uint8_t bitClock = digitalPinToBitMask(pinClock);
volatile uint8_t *outClock = portOutputRegister(digitalPinToPort(pinClock));
const uint8_t bitRowA = digitalPinToBitMask(pinRowA);
volatile uint8_t *outRowA = portOutputRegister(digitalPinToPort(pinRowA));
const uint8_t bitRowB = digitalPinToBitMask(pinRowB);
volatile uint8_t *outRowB = portOutputRegister(digitalPinToPort(pinRowB));
const uint8_t bitRowC = digitalPinToBitMask(pinRowC);
volatile uint8_t *outRowC = portOutputRegister(digitalPinToPort(pinRowC));
const uint8_t bitRowD = digitalPinToBitMask(pinRowD);
volatile uint8_t *outRowD = portOutputRegister(digitalPinToPort(pinRowD));
const uint8_t bitOE = digitalPinToBitMask(pinOE);
volatile uint8_t *outOE = portOutputRegister(digitalPinToPort(pinOE));
const uint8_t bitSTB = digitalPinToBitMask(pinSTB);
volatile uint8_t *outSTB = portOutputRegister(digitalPinToPort(pinSTB));
*outOE |= bitOE; // Turn off display // digitalWrite(pinOE,HIGH);
// select row
if (bitRead(row, 0)) *outRowA |= bitRowA; else *outRowA &= ~bitRowA;
if (bitRead(row, 1)) *outRowB |= bitRowB; else *outRowB &= ~bitRowB;
if (bitRead(row, 2)) *outRowC |= bitRowC; else *outRowC &= ~bitRowC;
if (bitRead(row, 3)) *outRowD |= bitRowD; else *outRowD &= ~bitRowD;
for(uint8_t column=0; column<16; column++){ // 16 segments
uint8_t index = column + (row*16); // 16 segments
for(uint8_t i=0; i<8; i++) {
if (buffer[index].R & (1<<(7-i))) *outRed &= ~bitRed;
else *outRed |= bitRed;
if (buffer[index].G & (1<<(7-i))) *outGreen &= ~bitGreen;
else *outGreen |= bitGreen;
//Clock Pulse
*outClock |= bitClock; //CLK, HIGH
*outClock &= ~bitClock; //CLK, LOW
}
}
*outSTB &= ~bitSTB; // digitalWrite(pinSTB,LOW);
*outSTB |= bitSTB; // digitalWrite(pinSTB,HIGH);
*outOE &= ~bitOE; // Turn on display // digitalWrite(pinOE,LOW);
}
// interrupt routine is responsible for painting the screen
ISR(TIMER2_COMPA_vect){
cli();
shiftOut(scanRow);
if (scanRow < 15) scanRow++; else scanRow = 0;
sei();
}
void setup() {
// use timer2 as the scanning interrupt timer
cli(); // clear interrupts
TCCR2A = 0; TCCR2B = 0; TCNT2 = 0;
TCCR2B |= (1 << CS12) | (1 << CS10); // Set 1024 prescaler
// 160Hz scan rate = 10 frames/second (16 rows)
OCR2A = 97; // 97 = (16,000,000 / (1024*160)) - 1
TCCR2A |= (1 << WGM21); TIMSK2 |= (1 << OCIE2A);
pinMode(pinRed, OUTPUT);
pinMode(pinGreen, OUTPUT);
pinMode(pinClock, OUTPUT);
pinMode(pinRowA, OUTPUT);
pinMode(pinRowB, OUTPUT);
pinMode(pinRowC, OUTPUT);
pinMode(pinRowD, OUTPUT);
pinMode(pinOE, OUTPUT);
pinMode(pinSTB, OUTPUT);
digitalWrite(pinOE, LOW);
digitalWrite(pinRed, HIGH); digitalWrite(pinGreen, HIGH);
sei(); //allow interrupts
}
// main loop is responsible for updating the screen
void loop() {
// printChar(0,GREEN,BLACK,'A');
hScroll(YELLOW, BLACK, message);
}
@simon419
Copy link

Hi, I have managed to get your 16 x 64 to work but I cannot get the 16 x 128 to work (I just get 1 row of LEDs). Could you help? Thanks.

@umeshw23
Copy link

hi, mark
16x64 program is working... but 16x128 isn't.
i tried changing the code with reference from arduino forum
http://forum.arduino.cc/index.php?topic=222334.15

but it is not working...
pls guide me what changes i supposed to make

@alexvazquez
Copy link

Hi its working but teh background is turned on and the letters are leds turned off. How can I invert that? Thanks

@ux-fran
Copy link

ux-fran commented Dec 1, 2017

Thanks, it works with my 16X64. Learned a lot from your code!

@frankcannon
Copy link

Hi also for me is working but I have the same problem as alexvazquez, backgrounf On and message off, There is any way how to solve? Thanks
Donciccio

@frankcannon
Copy link

Thanks to a friend here is the solution:

in the penultimate line
hScroll (YELLOW, BLACK, message);
make it become
hScroll (BLACK, YELLOW, message);

@ReefLiveMusic
Copy link

Thanks for the code for this 16x128 3 color led matrix.

  1. Would it be possible to change it to a 32x128 (i.e 2 panels of 32x64) 3 color led matrix?
    it looks like the one in the market such as https://www.aliexpress.com/item/33005142831.html?spm=a2g0o.cart.0.0.777d3c00odcu2v&mp=1 (1/16 scan rate - HUB08)
    have R1 R2 G1 G2 pins on the hub8 connector whereas you use R and G.
    for the single color 32x64 panel it's got R1 and R2. A small pcb connector connects the Arduino pins to the HUB8 but it doesn't have G1/G2 on the arduino side.

  2. Do you know where to get this type of connector for Arduino? I am aware of the DMDCON from Freetronics but it uses SPI pins and is HUB12.

I note that in your ShiftOut function you use functions like: digitalPinTo BitMask and Port. Also potOutRegister. I assume your project works on UNO. but

  1. do you know if these functions would works for MEG2560 and even the ESPDuino-32 ( Wemos D1 R32 ESP)?

Thanks in advance .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment