Displays text on a WS2812 (NeoPixel) matrix display

Dependencies:   mbed miniFont wsDrive

Displays text on an array of WS2812 LEDs (NeoPixels)

Text is 5 rows tall so any grid larger than that can be used. The font supports A-Z (capitals only, any lowercase input will be capitalised) numbers and some basic punctuation. Letters are 5 LEDs wide, some numbers and punctuation are smaller but generally you need 6 pixels wide per character you wish to fit. If displaying a string a 1 row space is left between characters, for other spacings either edit the code or print one letter at a time and adjust the offset for the next letter.

LEDs must be connected in horizontal rows, top row first. Rows can be either direction or alternating directions.

NOTE: The testing on this has been fairly minimal. It works with my one physical configuration, I think the logic for other configurations is correct but haven't tested it. If you find a problem please let me know.

Committer:
AndyA
Date:
Thu Nov 06 13:55:51 2014 +0000
Revision:
0:bada179a0b70
First commit;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AndyA 0:bada179a0b70 1 #include "miniFont.h"
AndyA 0:bada179a0b70 2
AndyA 0:bada179a0b70 3 const char miniFont::dot[5] = { 0x00,0x00,0x00,0x03,0x03};
AndyA 0:bada179a0b70 4 const char miniFont::space[5] = { 0x00,0x00,0x00,0x00,0x00};
AndyA 0:bada179a0b70 5 const char miniFont::exclam[5] = { 0x01,0x01,0x01,0x00,0x01};
AndyA 0:bada179a0b70 6 const char miniFont::quest[5] = { 0x0f,0x09,0x02,0x00,0x02};
AndyA 0:bada179a0b70 7
AndyA 0:bada179a0b70 8 const char miniFont::numbers[10][5] = {
AndyA 0:bada179a0b70 9 { 0x0e, 0x11, 0x11, 0x11, 0x08 }, // 0
AndyA 0:bada179a0b70 10 { 0x06, 0x02, 0x02, 0x02, 0x07 }, // 1
AndyA 0:bada179a0b70 11 { 0x1f, 0x01, 0x06, 0x18, 0x1f }, // 2
AndyA 0:bada179a0b70 12 { 0x1f, 0x01, 0x0f, 0x01, 0x1f }, // 3
AndyA 0:bada179a0b70 13 { 0x10, 0x10, 0x14, 0x1f, 0x04 }, // 4
AndyA 0:bada179a0b70 14 { 0x1f, 0x10, 0x1e, 0x01, 0x1e }, // 5
AndyA 0:bada179a0b70 15 { 0x1f, 0x10, 0x1f, 0x11, 0x1f }, // 6
AndyA 0:bada179a0b70 16 { 0x1f, 0x01, 0x01, 0x02, 0x02 }, // 7
AndyA 0:bada179a0b70 17 { 0x1f, 0x11, 0x08, 0x11, 0x1f }, // 8
AndyA 0:bada179a0b70 18 { 0x1f, 0x11, 0x1f, 0x01, 0x1f } // 9
AndyA 0:bada179a0b70 19 };
AndyA 0:bada179a0b70 20
AndyA 0:bada179a0b70 21 const char miniFont::letters[26][5] = {
AndyA 0:bada179a0b70 22 { 0x1f, 0x11, 0x1f, 0x11, 0x11 }, // A
AndyA 0:bada179a0b70 23 { 0x1e, 0x11, 0x1e, 0x11, 0x1e }, // B
AndyA 0:bada179a0b70 24 { 0x1f, 0x10, 0x10, 0x10, 0x1f }, // C
AndyA 0:bada179a0b70 25 { 0x1e, 0x11, 0x11, 0x11, 0x1e }, // D
AndyA 0:bada179a0b70 26 { 0x1f, 0x10, 0x1e, 0x10, 0x1f }, // E
AndyA 0:bada179a0b70 27 { 0x1f, 0x10, 0x1e, 0x10, 0x10 }, // F
AndyA 0:bada179a0b70 28 { 0x1f, 0x10, 0x13, 0x11, 0x1f }, // G
AndyA 0:bada179a0b70 29 { 0x11, 0x11, 0x1f, 0x11, 0x11 }, // H
AndyA 0:bada179a0b70 30 { 0x07, 0x02, 0x02, 0x02, 0x07 }, // I
AndyA 0:bada179a0b70 31 { 0x01, 0x01, 0x01, 0x11, 0x1f }, // J
AndyA 0:bada179a0b70 32 { 0x11, 0x12, 0x1c, 0x12, 0x11 }, // K
AndyA 0:bada179a0b70 33 { 0x10, 0x10, 0x10, 0x10, 0x1f }, // L
AndyA 0:bada179a0b70 34 { 0x11, 0x1b, 0x15, 0x11, 0x11 }, // M
AndyA 0:bada179a0b70 35 { 0x11, 0x19, 0x15, 0x13, 0x11 }, // N
AndyA 0:bada179a0b70 36 { 0x1f, 0x11, 0x11, 0x11, 0x1f }, // O
AndyA 0:bada179a0b70 37 { 0x1f, 0x11, 0x1f, 0x10, 0x10 }, // P
AndyA 0:bada179a0b70 38 { 0x1f, 0x11, 0x15, 0x1f, 0x04 }, // Q
AndyA 0:bada179a0b70 39 { 0x1f, 0x11, 0x1f, 0x12, 0x11 }, // R
AndyA 0:bada179a0b70 40 { 0x1f, 0x10, 0x1f, 0x01, 0x1F }, // S
AndyA 0:bada179a0b70 41 { 0x1f, 0x04, 0x04, 0x04, 0x04 }, // T
AndyA 0:bada179a0b70 42 { 0x11, 0x11, 0x11, 0x11, 0x1F }, // U
AndyA 0:bada179a0b70 43 { 0x11, 0x11, 0x11, 0x0a, 0x04 }, // V
AndyA 0:bada179a0b70 44 { 0x11, 0x11, 0x15, 0x1b, 0x11 }, // W
AndyA 0:bada179a0b70 45 { 0x11, 0x0a, 0x04, 0x0a, 0x11 }, // X
AndyA 0:bada179a0b70 46 { 0x11, 0x11, 0x1f, 0x04, 0x04 }, // Y
AndyA 0:bada179a0b70 47 { 0x1f, 0x02, 0x04, 0x08, 0x1f } // Z
AndyA 0:bada179a0b70 48 };
AndyA 0:bada179a0b70 49
AndyA 0:bada179a0b70 50
AndyA 0:bada179a0b70 51 miniFont::miniFont() {
AndyA 0:bada179a0b70 52
AndyA 0:bada179a0b70 53 rotate90 = false;
AndyA 0:bada179a0b70 54 fixedWidth = false;
AndyA 0:bada179a0b70 55 }
AndyA 0:bada179a0b70 56
AndyA 0:bada179a0b70 57
AndyA 0:bada179a0b70 58 uint8_t miniFont::getMinPixWidth(char letter)
AndyA 0:bada179a0b70 59 {
AndyA 0:bada179a0b70 60 switch(letter) {
AndyA 0:bada179a0b70 61 case '.':
AndyA 0:bada179a0b70 62 return 2;
AndyA 0:bada179a0b70 63 case ' ':
AndyA 0:bada179a0b70 64 case '1':
AndyA 0:bada179a0b70 65 case 'I':
AndyA 0:bada179a0b70 66 case 'i':
AndyA 0:bada179a0b70 67 return 3;
AndyA 0:bada179a0b70 68 case '!':
AndyA 0:bada179a0b70 69 return 1;
AndyA 0:bada179a0b70 70 case '?':
AndyA 0:bada179a0b70 71 return 4;
AndyA 0:bada179a0b70 72 default:
AndyA 0:bada179a0b70 73 return maxWidth;
AndyA 0:bada179a0b70 74 }
AndyA 0:bada179a0b70 75 }
AndyA 0:bada179a0b70 76
AndyA 0:bada179a0b70 77
AndyA 0:bada179a0b70 78 uint8_t miniFont::getPixWidth(char letter)
AndyA 0:bada179a0b70 79 {
AndyA 0:bada179a0b70 80 if (fixedWidth)
AndyA 0:bada179a0b70 81 return maxWidth;
AndyA 0:bada179a0b70 82 else
AndyA 0:bada179a0b70 83 return getMinPixWidth(letter);
AndyA 0:bada179a0b70 84 }
AndyA 0:bada179a0b70 85
AndyA 0:bada179a0b70 86 uint8_t miniFont::getPixHeight(char letter)
AndyA 0:bada179a0b70 87 {
AndyA 0:bada179a0b70 88 return 5;
AndyA 0:bada179a0b70 89 }
AndyA 0:bada179a0b70 90
AndyA 0:bada179a0b70 91 // gets the proportional letter
AndyA 0:bada179a0b70 92 bool miniFont::getRawChar(char letter, const char **rowArray)
AndyA 0:bada179a0b70 93 {
AndyA 0:bada179a0b70 94
AndyA 0:bada179a0b70 95 if ((letter>='A') && (letter<='Z')) { // upper
AndyA 0:bada179a0b70 96 *rowArray = letters[letter-'A'];
AndyA 0:bada179a0b70 97 return true;
AndyA 0:bada179a0b70 98 }
AndyA 0:bada179a0b70 99 if ((letter>='a') && (letter<='z')) { // lower
AndyA 0:bada179a0b70 100 *rowArray = letters[letter-'a'];
AndyA 0:bada179a0b70 101 return true;
AndyA 0:bada179a0b70 102 }
AndyA 0:bada179a0b70 103 if ((letter>='0') && (letter <='9')) {
AndyA 0:bada179a0b70 104 *rowArray = numbers[letter-'0'];
AndyA 0:bada179a0b70 105 return true;
AndyA 0:bada179a0b70 106 }
AndyA 0:bada179a0b70 107 if (letter == '.') {
AndyA 0:bada179a0b70 108 *rowArray = dot;
AndyA 0:bada179a0b70 109 return true;
AndyA 0:bada179a0b70 110 }
AndyA 0:bada179a0b70 111 if (letter == '!') {
AndyA 0:bada179a0b70 112 *rowArray = exclam;
AndyA 0:bada179a0b70 113 return true;
AndyA 0:bada179a0b70 114 }
AndyA 0:bada179a0b70 115 if (letter == '?') {
AndyA 0:bada179a0b70 116 *rowArray = quest;
AndyA 0:bada179a0b70 117 return true;
AndyA 0:bada179a0b70 118 }
AndyA 0:bada179a0b70 119 if (letter == ' ') {
AndyA 0:bada179a0b70 120 *rowArray = space;
AndyA 0:bada179a0b70 121 return true;
AndyA 0:bada179a0b70 122 }
AndyA 0:bada179a0b70 123 return false;
AndyA 0:bada179a0b70 124 }
AndyA 0:bada179a0b70 125
AndyA 0:bada179a0b70 126 // converts to fixed width if needed.
AndyA 0:bada179a0b70 127 bool miniFont::getVerticalChar(char letter, const char **rowArray)
AndyA 0:bada179a0b70 128 {
AndyA 0:bada179a0b70 129 if (!fixedWidth)
AndyA 0:bada179a0b70 130 return getRawChar(letter,rowArray);
AndyA 0:bada179a0b70 131
AndyA 0:bada179a0b70 132 uint8_t shift = (maxWidth - getMinPixWidth(letter)) / 2;
AndyA 0:bada179a0b70 133 if (shift == 0)
AndyA 0:bada179a0b70 134 return getRawChar(letter,rowArray);
AndyA 0:bada179a0b70 135
AndyA 0:bada179a0b70 136 const char *rawletter;
AndyA 0:bada179a0b70 137 if (getRawChar(letter,&rawletter)) {
AndyA 0:bada179a0b70 138 for (int i = 0; i < maxHeight; i++) {
AndyA 0:bada179a0b70 139 letterBuffer[i] = rawletter[i]<<shift;
AndyA 0:bada179a0b70 140 }
AndyA 0:bada179a0b70 141 *rowArray = (const char *)letterBuffer;
AndyA 0:bada179a0b70 142 return true;
AndyA 0:bada179a0b70 143 }
AndyA 0:bada179a0b70 144 return false;
AndyA 0:bada179a0b70 145 }
AndyA 0:bada179a0b70 146
AndyA 0:bada179a0b70 147 // rotates if needed.
AndyA 0:bada179a0b70 148 bool miniFont::getChar(char letter, const char **rowArray)
AndyA 0:bada179a0b70 149 {
AndyA 0:bada179a0b70 150 if (!rotate90) return getVerticalChar(letter,rowArray);
AndyA 0:bada179a0b70 151
AndyA 0:bada179a0b70 152 const char *vertical;
AndyA 0:bada179a0b70 153 if (!getVerticalChar(letter,&vertical))
AndyA 0:bada179a0b70 154 return false;
AndyA 0:bada179a0b70 155
AndyA 0:bada179a0b70 156 for (int i = 0; i < maxWidth; i++) {
AndyA 0:bada179a0b70 157 rotateBuffer[i] = 0;
AndyA 0:bada179a0b70 158 }
AndyA 0:bada179a0b70 159
AndyA 0:bada179a0b70 160 for (int i = 0; i < maxHeight; i++) {
AndyA 0:bada179a0b70 161 for (int j = 0; j < maxWidth; j++) {
AndyA 0:bada179a0b70 162 rotateBuffer[i] = vertical[j] << j;
AndyA 0:bada179a0b70 163 }
AndyA 0:bada179a0b70 164 }
AndyA 0:bada179a0b70 165 *rowArray = vertical;
AndyA 0:bada179a0b70 166 return true;
AndyA 0:bada179a0b70 167 }