├── Arduino_HUB08_Matrix_Led-main.ino ├── Buffer.cpp ├── Buffer.h ├── HUB08SPI.cpp ├── HUB08SPI.h ├── LICENSE ├── README.md ├── TimerOne.cpp ├── TimerOne.h ├── Tool ├── Font Builder.xlsm └── wiring.png ├── config └── known_16bit_timers.h ├── ronnAnimation.h └── ronnFont.h /Arduino_HUB08_Matrix_Led-main.ino: -------------------------------------------------------------------------------- 1 | /* ******************************************************************** 2 | * THIS DEMO TESTED ON ARDUINO UNO, NANO, PRO MINI (ATMEGA328P) 3 | * ******************************************************************** 4 | * HUB08 (matrix led) to ARDUINO pin connection 5 | * LA / A -> Digital Pin 4 6 | * LB / B -> Digital Pin 5 7 | * LC / C -> Digital Pin 6 8 | * LD / D -> Digital Pin 7 9 | * S / CLK -> Digital Pin 13 10 | * R1 / R -> Digital Pin 11 11 | * OE / EN -> Digital Pin 3 12 | * L / LAT / STB -> Digital Pin 2 13 | * 14 | * ******************************************************************** 15 | * If display in matrix led invert, change in HUB08SPI.cpp 16 | * Find : 17 | * SPI.transfer(*ptr); 18 | * Change to : 19 | * SPI.transfer(~*ptr); 20 | * Detail, check in : 21 | * https://github.com/emgoz/HUB08SPI/issues/5 22 | * ********************************************************************/ 23 | 24 | 25 | 26 | #include 27 | #include 28 | #include "HUB08SPI.h" 29 | #include "TimerOne.h" 30 | #include "Buffer.h" 31 | 32 | #define WIDTH 64 // width of led matrix (pixel) 33 | #define HEIGHT 16 // height of led matrix 34 | 35 | HUB08SPI display; 36 | uint8_t displaybuf[WIDTH * HEIGHT / 8]; 37 | Buffer buff(displaybuf,64,16); 38 | 39 | //make sure to put after create buffer 40 | #include "ronnAnimation.h" 41 | 42 | void refresh() { 43 | display.scan(); //refresh a single line of the display 44 | } 45 | void showTitle(String icon, String text, bool topPosition=true){ 46 | char* topMoving[] ={"P:300", "L:27", "E:0"}; 47 | char* midMoving[] ={"D:4","P:300", "L:27", "E:0"}; 48 | ronn.setFont(C_ICON); 49 | ronn.scrollText_D(icon,27,0,9,10); 50 | ronn.moveTo((topPosition?topMoving:midMoving), 10, 27, 0, 9, 8); 51 | ronn.setFont(); 52 | ronn.scanText_L(text, 11, (topPosition?0:4), 10); 53 | delay(500); 54 | } 55 | void changeTitle(String text){ 56 | ronn.setFont(); 57 | ronn.clear_L(10,0,54,8); 58 | ronn.printText_RC(text,11,0); 59 | delay(500); 60 | } 61 | void setup(){ 62 | Serial.begin(9600); 63 | display.begin(displaybuf, WIDTH, HEIGHT); 64 | Timer1.initialize(100); //800 us -> refresh rate 1250 Hz per line / 16 = 78 fps 65 | Timer1.attachInterrupt(refresh); 66 | display.setBrightness(200); //low brightness to save energy 67 | buff.clear(); //clear display led matrix 68 | buff.bitmap(0,0,64,16,logo,1); //bitmap logo 69 | delay(2000); 70 | ronn.clear_A1(); 71 | } 72 | void loop(){ 73 | showFont(); 74 | animationDemo(); 75 | moveDemo(); 76 | clearDemo(); 77 | showTitle("4","END DEMO",false); 78 | delay(5000); 79 | ronn.clearSlice_R(); 80 | } 81 | 82 | 83 | 84 | 85 | /* 86 | * RONN ANIMATION DEMO FUNCTION 87 | * ************************************************************************************************ 88 | */ 89 | 90 | //CEAR DEMO 91 | void clearDemo(){ 92 | showTitle("2","CLEAR",false);delay(500); 93 | ronn.move_U(4);delay(300); 94 | changeTitle("Clear Left"); 95 | ronn.printText("Animation Demo",0,9);delay(500); 96 | ronn.clear_L(0,8,64,8,CLEAR); 97 | changeTitle("Scroll Left"); 98 | ronn.printText("Animation Demo",0,9);delay(500); 99 | ronn.clear_L(0,8,64,8,SCROLL); 100 | changeTitle("Clear Right"); 101 | ronn.printText("Animation Demo",0,9);delay(500); 102 | ronn.clear_R(0,8,64,8,CLEAR); 103 | changeTitle("Scroll Right"); 104 | ronn.printText("Animation Demo",0,9);delay(500); 105 | ronn.clear_R(0,8,64,8,SCROLL); 106 | changeTitle("Clear Up"); 107 | ronn.printText("Animation Demo",0,9);delay(500); 108 | ronn.clear_U(0,8,64,8,CLEAR); 109 | changeTitle("Scroll Up"); 110 | ronn.printText("Animation Demo",0,9);delay(500); 111 | ronn.clear_U(0,8,64,8,SCROLL); 112 | changeTitle("Clear Down"); 113 | ronn.printText("Animation Demo",0,9);delay(500); 114 | ronn.clear_D(0,8,64,8,CLEAR); 115 | changeTitle("Scroll Down"); 116 | ronn.printText("Animation Demo",0,9);delay(500); 117 | ronn.clear_D(0,8,64,8,SCROLL); 118 | 119 | changeTitle("Slice Left"); 120 | ronn.printText("Animation Demo",0,9);delay(500); 121 | ronn.clearSlice_L(0,8,64,8); 122 | changeTitle("Slice Right"); 123 | ronn.printText("Animation Demo",0,9);delay(500); 124 | ronn.clearSlice_R(0,8,64,8); 125 | ronn.clear_U(); 126 | 127 | showTitle("2","CLEAR ALL",false);delay(500); 128 | ronn.move_U(4);delay(300); 129 | changeTitle("Clear Left"); 130 | ronn.printText("Animation Demo",0,9);delay(500); 131 | ronn.clear_L(CLEAR); 132 | showTitle("2","Scroll Left");delay(500); 133 | ronn.printText("Animation Demo",0,9);delay(500); 134 | ronn.clear_L(); 135 | showTitle("2","Clear Right");delay(500); 136 | ronn.printText("Animation Demo",0,9);delay(500); 137 | ronn.clear_R(CLEAR); 138 | showTitle("2","Scroll Right");delay(500); 139 | ronn.printText("Animation Demo",0,9);delay(500); 140 | ronn.clear_R(); 141 | showTitle("2","Clear Down");delay(500); 142 | ronn.printText("Animation Demo",0,9);delay(500); 143 | ronn.clear_D(CLEAR); 144 | showTitle("2","Scroll Down");delay(500); 145 | ronn.printText("Animation Demo",0,9);delay(500); 146 | ronn.clear_D(); 147 | showTitle("2","Clear Up");delay(500); 148 | ronn.printText("Animation Demo",0,9);delay(500); 149 | ronn.clear_U(CLEAR); 150 | showTitle("2","Scroll Up");delay(500); 151 | ronn.printText("Animation Demo",0,9);delay(500); 152 | ronn.clear_U(); 153 | showTitle("2","Slice Left");delay(500); 154 | ronn.printText("Animation Demo",0,9);delay(500); 155 | ronn.clearSlice_L(); 156 | showTitle("2","Slice Right");delay(500); 157 | ronn.printText("Animation Demo",0,9);delay(500); 158 | ronn.clearSlice_R(); 159 | 160 | showTitle("2","Animation 1");delay(500); 161 | ronn.printText("Animation Demo",0,9);delay(500); 162 | ronn.clear_A1(); 163 | showTitle("2","Animation 2");delay(500); 164 | ronn.printText("Animation Demo",0,9);delay(500); 165 | ronn.clear_A2(); 166 | } 167 | 168 | //MOVE DEMO 169 | void moveDemo(){ 170 | showTitle("3","MOVE DEMO",false);delay(500); 171 | ronn.move_U(4);delay(300); 172 | changeTitle("Move All"); 173 | ronn.printText_RC("Demo",0,9);delay(500); 174 | ronn.move_R(32);delay(500); 175 | ronn.move_U(8);delay(500); 176 | ronn.move_L(16);delay(500); 177 | ronn.move_D(16);delay(500); 178 | showTitle("3","Custom"); 179 | changeTitle("Move"); 180 | ronn.move_R(14);delay(500); 181 | ronn.move_D(4);delay(500); 182 | buff.rect(0,12,4,4,1);delay(500); 183 | char* moving[] ={"R:60", "P:300", "U:8", "P:300", "L:14", "E:0"}; 184 | ronn.moveTo(moving, 20, 0, 12, 4, 4);delay(1000); 185 | ronn.clear_A2(); 186 | //ronn.clearSlice_R(); 187 | } 188 | 189 | //FONT DEMO 190 | void showFont(){ 191 | showTitle("0","FONT DEMO",false);delay(500); 192 | ronn.move_U(4);delay(300); 193 | changeTitle("Big Font"); 194 | ronn.clear_R(); 195 | ronn.setFont(B_STD); 196 | ronn.scrollText_LR("This is a big font demo from RONN ANIMATION - 1234567890",0,0,64,20); 197 | showTitle("0","Normal Font"); 198 | ronn.scrollText_LR("Normal font example - CAPITAL - 1234567890",0,9,64,30); 199 | changeTitle("Small Font"); 200 | ronn.setFont(S_STD); 201 | ronn.scrollText_LR("Small font example - CAPITAL - 1234567890",0,9,64,40); 202 | changeTitle("Custom"); 203 | changeTitle("7 Segment"); 204 | ronn.setFont(N_7SEGMENT); 205 | ronn.scrollText_LR("1234567890",0,9,64,30); 206 | changeTitle("Big Font"); 207 | changeTitle("7 Segment"); 208 | ronn.clear_L(); 209 | ronn.setFont(B_7SEGMENT); 210 | ronn.scrollText_LR("1234567890",0,0,64,20); 211 | } 212 | 213 | //TEXT ANIMATION DEMO 214 | void animationDemo(){ 215 | showTitle("1","ANIMATION",false); 216 | ronn.move_U(4);delay(300); 217 | 218 | //Print text 219 | changeTitle("Print Text"); 220 | ronn.printText("Animation Demo",0,9);delay(500); 221 | 222 | //Print Right 223 | changeTitle("Print Right"); 224 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 225 | ronn.printText_R("Animation Demo",0,9);delay(500); 226 | changeTitle("Custom"); 227 | changeTitle("Speed"); 228 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 229 | ronn.printText_R("Animation Demo",0,9,50);delay(500); 230 | changeTitle("With Cursor"); 231 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 232 | ronn.printText_RC("Animation Demo",0,9);delay(500); 233 | changeTitle("Custom"); 234 | changeTitle("Speed"); 235 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 236 | ronn.printText_RC("Animation Demo",0,9,50);delay(500); 237 | changeTitle("Big Font"); 238 | ronn.clear_L(CLEAR);delay(300); 239 | ronn.setFont(B_STD); 240 | ronn.printText_RC("Example",0,0);delay(1000); 241 | ronn.clear_L(); 242 | 243 | //Print Left 244 | showTitle("1","Print Left"); 245 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 246 | ronn.printText_L("Animation Demo",0,9);delay(500); 247 | changeTitle("With Cursor"); 248 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 249 | ronn.printText_LC("Animation Demo",0,9);delay(500); 250 | changeTitle("Big Font"); 251 | ronn.clear_R(CLEAR);delay(300); 252 | ronn.setFont(B_STD); 253 | ronn.printText_LC("Example",0,0);delay(1000); 254 | ronn.clear_R(); 255 | 256 | //Scan Left 257 | showTitle("1","Scan Left"); 258 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 259 | ronn.scanText_L("Animation Demo",0,9);delay(500); 260 | changeTitle("Custom"); 261 | changeTitle("Speed"); 262 | ronn.clear_L(0,8,64,8,CLEAR);delay(300); 263 | ronn.scanText_L("Animation Demo",0,9,50);delay(500); 264 | changeTitle("Big Font"); 265 | ronn.clear_R(CLEAR);delay(300); 266 | ronn.setFont(B_STD); 267 | ronn.scanText_L("Example",0,0);delay(1000); 268 | ronn.clear_L(CLEAR); 269 | 270 | //Scan Right 271 | showTitle("1","Scan Right"); 272 | ronn.clear_R(0,8,64,8,CLEAR);delay(300); 273 | ronn.scanText_R("Animation Demo",0,9);delay(500); 274 | changeTitle("Big Font"); 275 | ronn.clear_R(CLEAR);delay(300); 276 | ronn.setFont(B_STD); 277 | ronn.scanText_R("Example",0,0);delay(1000); 278 | ronn.clear_R(CLEAR); 279 | 280 | //Scroll text 281 | showTitle("1","Scroll Left"); 282 | ronn.scrollText_LL("Animation",0,9,64);delay(500); 283 | changeTitle("Run Text"); 284 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 285 | ronn.scrollText_LR("Ronn Animation Demo",0,9,64);delay(500); 286 | changeTitle("Custom"); 287 | changeTitle("Speed"); 288 | ronn.scrollText_LR("Ronn Animation Demo",0,9,64,50);delay(500); 289 | changeTitle("Custom"); 290 | changeTitle("Position"); 291 | buff.rect(0,9,15,7,1); 292 | buff.rect(49,9,15,7,1); 293 | for(int i=0;i<2;i++)//run 3x 294 | ronn.scrollText_LR("Ronn Animation Demo - RONN ANIMATION DEMO",16,9,32,40);delay(500); 295 | 296 | //Scroll Down 297 | changeTitle("Scroll Down"); 298 | ronn.scrollText_D("Animation Demo",0,9,64);delay(500); 299 | ronn.scrollText_D("Animation",0,9,43);delay(500); 300 | ronn.scrollText_D("Demo",43,9,64-43);delay(500); 301 | 302 | changeTitle("Clock Demo"); 303 | ronn.clear_D(0,8,64,8,CLEAR);delay(300); 304 | ronn.scrollText_D("06:30:55",11,8,64-11); 305 | delay(1000-160); 306 | for(int i=6;i<=9;i++){ 307 | ronn.scrollText_D(String(i),36+11,8,5); 308 | delay(1000-160);//animatioan delay = 20ms * 8 step =160ms 309 | } 310 | ronn.scrollText_D("00",30+11,8,11); 311 | ronn.scrollText_D("1",21+11,8,5); 312 | changeTitle("Big Clock"); 313 | ronn.clear_D(); 314 | ronn.setFont(B_7SEGMENT); 315 | ronn.scrollText_D("06:30",9,0,64-11); 316 | for(int i=1;i<=5;i++){ 317 | delay(400); 318 | buff.fillRect(31,0,2,16,0); 319 | delay(600); 320 | ronn.printText(":",31,0); 321 | } 322 | ronn.scrollText_D("1",45,0,10);delay(500); 323 | ronn.clear_D(); 324 | 325 | //Scroll Up 326 | showTitle("1","Scroll Up"); 327 | ronn.scrollText_U("Animation",12,8,43);delay(500); 328 | ronn.scrollText_U(" Demo",12,8,64-23);delay(500); 329 | changeTitle("Clock Demo"); 330 | ronn.clear_U(0,8,64,8,CLEAR);delay(300); 331 | ronn.scrollText_U("06:30:55",11,8,64-11); 332 | delay(1000-160); 333 | for(int i=6;i<=9;i++){ 334 | ronn.scrollText_U(String(i),36+11,8,5); 335 | delay(1000-160); 336 | } 337 | ronn.scrollText_U("00",30+11,8,11); 338 | ronn.scrollText_U("1",21+11,8,5); 339 | ronn.clear_U(); 340 | 341 | 342 | //ronn.clearSlice_L(0,8,64,8); 343 | } 344 | 345 | 346 | -------------------------------------------------------------------------------- /Buffer.cpp: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------------------- 2 | // *** Change Log / Version history *** 3 | // 4 | // 0.1 - A basic Graphics library for buffers, 5 | // made to use it with any low res (up to 256 x 256 pix) monochrome LCD 6 | // The LCD must have a width which is divisible by 8 and 7 | // the data has to be stored byte-wise (1 bit = 1 pixel) starting at the top left. 8 | // For further information on how to use the functions, read the Documentation.pdf 9 | // Made by Marvin G. aka MGOS / Apr 27 2013 10 | // request, bug reports and qustions to: marv.mgos@gmail.com 11 | //-----------------------------------------------------------------------------------------------*/ 12 | 13 | /*------------------------------------------------------------------------------------------------- 14 | // You are allowed to copy, distribute or modify the source code of this library. 15 | // Any modification you make should be added to the change log / version history 16 | // in this document and at the top of each source file, including the author, 17 | // the date and all changes made. 18 | // 19 | // Release into public domain. 20 | //-----------------------------------------------------------------------------------------------*/ 21 | #include "Arduino.h" 22 | #include "Buffer.h" 23 | 24 | 25 | //------------------------------------------------------------------------------------------------- 26 | // Constructor 27 | //------------------------------------------------------------------------------------------------- 28 | Buffer::Buffer(uint8_t * RAM_area, int16_t pixHor, int16_t pixVer) 29 | { 30 | pixHor = (pixHor >> 3) * 8; 31 | if (pixHor > 256) pixHor = 256; 32 | if (pixVer > 256) pixVer = 256; 33 | width = pixHor; 34 | height = pixVer; 35 | columns = width/8; 36 | size = columns*height; 37 | array = RAM_area; 38 | } 39 | 40 | //------------------------------------------------------------------------------------------------- 41 | // Pointer getter 42 | //------------------------------------------------------------------------------------------------- 43 | uint8_t* Buffer::ptr() 44 | { 45 | return array; 46 | } 47 | //------------------------------------------------------------------------------------------------- 48 | // Pointer setter 49 | //------------------------------------------------------------------------------------------------- 50 | uint8_t* Buffer::ptr(uint8_t* new_pointer) 51 | { 52 | array = new_pointer; 53 | return array; 54 | } 55 | //------------------------------------------------------------------------------------------------- 56 | // Get size 57 | //------------------------------------------------------------------------------------------------- 58 | int16_t Buffer::getWidth() 59 | { 60 | return width; 61 | } 62 | int16_t Buffer::getHeight() 63 | { 64 | return height; 65 | } 66 | //------------------------------------------------------------------------------------------------- 67 | // clear 68 | //------------------------------------------------------------------------------------------------- 69 | uint8_t * Buffer::clear() 70 | { 71 | for(uint16_t i=0; i < size; i++) array[i] = 0; 72 | return array; 73 | } 74 | //------------------------------------------------------------------------------------------------- 75 | // fill 76 | //------------------------------------------------------------------------------------------------- 77 | uint8_t * Buffer::fill(uint8_t n) 78 | { 79 | for(uint16_t i=0; i < size; i++) array[i] = n; 80 | return array; 81 | } 82 | //------------------------------------------------------------------------------------------------- 83 | // Invert 84 | //------------------------------------------------------------------------------------------------- 85 | uint8_t * Buffer::invert() 86 | { 87 | for(uint16_t i=0; i < size; i++) array[i] ^= 0xFF; 88 | return array; 89 | } 90 | //------------------------------------------------------------------------------------------------- 91 | // Set Pixel 92 | //------------------------------------------------------------------------------------------------- 93 | void Buffer::setPixel(int x, int y, uint8_t mode) 94 | { 95 | if (y >= height || x >= width || x < 0 || y < 0) 96 | return; 97 | if (mode == OFF) 98 | array[x/8+y*columns] &= ~(128 >> (x & 7)); 99 | else if (mode == ON) 100 | array[x/8+y*columns] |= (128 >> (x & 7)); 101 | else 102 | array[x/8+y*columns] ^= (128 >> (x & 7)); 103 | } 104 | //------------------------------------------------------------------------------------------------- 105 | // Get Pixel 106 | //------------------------------------------------------------------------------------------------- 107 | bool Buffer::getPixel(int x, int y) 108 | { 109 | if (y >= height || x >= width || x < 0 || y < 0) 110 | return true; 111 | return (array[x/8+y*columns] & (128 >> (x & 7))); 112 | } 113 | //------------------------------------------------------------------------------------------------- 114 | // Scrolling 115 | //------------------------------------------------------------------------------------------------- 116 | void Buffer::scrollUp(int x, int y, int a, int b) 117 | { 118 | if (x + a > width) 119 | a = width-x; 120 | if (y + b > height) 121 | b = height-y; 122 | if (x < 0) 123 | { 124 | a = a+x; 125 | x = 0; 126 | } 127 | if (y < 0) 128 | { 129 | b = b+y; 130 | y = 0; 131 | } 132 | if (y >= height || x >= width || a <= 0 || b <= 1) return; 133 | uint16_t bottom; 134 | uint8_t left = x& 7; 135 | if (left+a <= 8) //only one byte? 136 | { 137 | uint8_t m = 0xFF << (8-a); 138 | m >>= left; 139 | bottom = (y+b-1)*columns; 140 | for (uint16_t l = y*columns+x/8; l < bottom; l+=columns){ 141 | array[l] = (array[l] & (~m)) | (array[l+columns] & m); 142 | } 143 | } 144 | else 145 | { 146 | uint8_t right = (x+a)& 7; 147 | uint16_t start = y*columns+(x+7)/8; //included 148 | uint16_t end = y*columns+(x+a)/8; //not included 149 | uint8_t l_m = 0xFF >> left; 150 | uint8_t r_m = 0xFF << 8-right; 151 | bottom = (b-1)*columns; 152 | for (uint16_t l = 0; l < bottom; l+=columns) 153 | { 154 | if (left) array[l+start-1] = (array[l+start-1] & (~l_m)) | (array[l+start+columns-1] & l_m); 155 | for (uint16_t p = start; p < end ; p++) array[l+p] = array[l+p+columns]; 156 | if (right) array[l+end] = (array[l+end] & (~r_m)) | (array[l+end+columns] & r_m); 157 | } 158 | } 159 | } 160 | void Buffer::scrollDown(int x, int y, int a, int b) 161 | { 162 | if (x + a > width) 163 | a = width-x; 164 | if (y + b > height) 165 | b = height-y; 166 | if (x < 0) 167 | { 168 | a = a+x; 169 | x = 0; 170 | } 171 | if (y < 0) 172 | { 173 | b = b+y; 174 | y = 0; 175 | } 176 | if (y >= height || x >= width || a <= 0 || b <= 1) return; 177 | uint8_t left = x& 7; 178 | //Serial.println(left); 179 | //Serial.println(a); 180 | if (left+a <= 8) //only one byte? 181 | { 182 | uint8_t m = 0xFF << (8-a); 183 | 184 | m >>= left; 185 | uint16_t top = y*columns+x/8; 186 | 187 | 188 | //SOMETHING WRONG WITH FORMULA 189 | //i have modified this , But some location still error.... ^___^ 190 | //maybe someone can help..... 191 | uint16_t bottom = (y+b-1)*columns + x/8 - 8; 192 | for (uint16_t l = bottom; l > top; l-=columns) 193 | array[l] = (array[l] & (~m)) | (array[l-columns] & m); 194 | 195 | 196 | /* RONN MOD. INFO 197 | * ****************************************************** 198 | * ORIGINAL LIBRARY CODE 199 | Serial.println(); 200 | for (uint16_t l = (y+b-1)*columns; l > top; l-=columns){ 201 | array[l] = (array[l] & (~m)) | (array[l-columns] & m); 202 | } 203 | */ 204 | 205 | /* 206 | * TRY THIS CODE WITH ORIGINAL LIBRARY 207 | * ******************************************************* 208 | buff.fillRect(0,5,64,6,ON); 209 | for (byte i = 0; i < 64; i++) { 210 | buff.fillRect(0,5,64,6,ON); 211 | for (byte aa = 0; aa < 8; aa++) { 212 | buff.scrollDown(i,4,3,8); 213 | delay(10); 214 | } 215 | delay(500); 216 | } 217 | */ 218 | 219 | } 220 | else 221 | { 222 | uint8_t right = (x+a)& 7; 223 | uint16_t start = y*columns+(x+7)/8; //included 224 | uint16_t end = y*columns+(x+a)/8; //not included 225 | uint8_t l_m = 0xFF >> left; 226 | uint8_t r_m = 0xFF << 8-right; 227 | for (uint16_t l = (b-1)*columns; l > 0; l-=columns) 228 | { 229 | if (left) array[l+start-1] = (array[l+start-1] & (~l_m)) | (array[l+start-columns-1] & l_m); 230 | for (uint16_t p = start; p < end ; p++) array[l+p] = array[l+p-columns]; 231 | if (right) array[l+end] = (array[l+end] & (~r_m)) | (array[l+end-columns] & r_m); 232 | } 233 | } 234 | } 235 | void Buffer::scrollRight(int x, int y, int a, int b) 236 | { 237 | if (x + a > width) 238 | a = width-x; 239 | if (y + b > height) 240 | b = height-y; 241 | if (x < 0) 242 | { 243 | a = a+x; 244 | x = 0; 245 | } 246 | if (y < 0) 247 | { 248 | b = b+y; 249 | y = 0; 250 | } 251 | if (y >= height || x >= width || a <= 1 || b <= 0) return; 252 | uint8_t left = x& 7; 253 | uint16_t bottom = (y+b)*columns; 254 | if (left+a <= 8) //only one byte? 255 | { 256 | uint8_t m = 0xFF << (8-a); 257 | m >>= left; 258 | for (uint16_t l = x/8+y*columns; l < bottom; l+=columns) 259 | array[l] = (array[l] & ~m) | (((array[l] & m) >> 1) & m); 260 | 261 | } 262 | else 263 | { 264 | uint16_t start = x/8; //included 265 | uint16_t end = (x+a)/8; //included 266 | uint8_t l_m = 0xFF >> left; 267 | uint8_t r_m = 0xFF << 8-((x+a)& 7); 268 | if (!r_m) 269 | { 270 | r_m = 0xFF; 271 | end--; 272 | } 273 | uint8_t c,d; 274 | for (uint16_t l = y*columns; l < bottom; l+=columns) 275 | { 276 | c = array[l+start] << 7; 277 | array[l+start] = (array[l+start] & ~l_m) | (((array[l+start] & l_m) >> 1) & l_m); 278 | if (end-start>1) 279 | { 280 | for (uint8_t p = start+1; p < end; p++) 281 | { 282 | d = array[p + l] << 7; 283 | array[p + l] = c | (array[p+l] >> 1); 284 | c = d; 285 | } 286 | } 287 | array[l+end] = (array[l+end] & ~r_m) | (((array[l+end] & r_m) >> 1) & r_m) | c; 288 | } 289 | } 290 | 291 | 292 | } 293 | void Buffer::scrollLeft(int x, int y, int a, int b) 294 | { 295 | if (x + a > width) 296 | a = width-x; 297 | if (y + b > height) 298 | b = height-y; 299 | if (x < 0) 300 | { 301 | a = a+x; 302 | x = 0; 303 | } 304 | if (y < 0) 305 | { 306 | b = b+y; 307 | y = 0; 308 | } 309 | if (y >= height || x >= width || a <= 1 || b <= 0) return; 310 | uint8_t left = x& 7; 311 | uint16_t bottom = (y+b)*columns; 312 | 313 | if (left+a <= 8) //only one uint8_t? 314 | { 315 | uint8_t m = 0xFF << (8-a); 316 | m >>= left; 317 | for (uint16_t l = x/8+y*columns; l < bottom; l+=columns) 318 | array[l] = (array[l] & ~m) | (((array[l] & m) << 1) & m); 319 | } 320 | else 321 | { 322 | uint16_t start = x/8; //included 323 | uint16_t end = (x+a)/8; //included 324 | uint8_t l_m = 0xFF >> left; 325 | uint8_t r_m = 0xFF << 8-((x+a)& 7); 326 | if (!r_m) 327 | { 328 | r_m = 0xFF; 329 | end--; 330 | } 331 | uint8_t c,d; 332 | for (uint16_t l = y*columns; l < bottom; l+=columns) 333 | { 334 | c = array[l+end] >> 7; 335 | array[l+end] = (array[l+end] & ~r_m) | (((array[l+end] & r_m) << 1) & r_m); 336 | if (end-start>1) 337 | { 338 | for (uint8_t p = end-1; p > start ; p--) 339 | { 340 | d = array[p + l] >> 7; 341 | array[p + l] = c | (array[p+l] << 1); 342 | c = d; 343 | } 344 | } 345 | array[l+start] = (array[l+start] & ~l_m) | (((array[l+start] & l_m) << 1) & l_m) | c; 346 | } 347 | 348 | 349 | } 350 | 351 | } 352 | uint8_t * Buffer::scrollUp(int n) 353 | { 354 | if (n < 0) 355 | return scrollDown(-n); 356 | 357 | if (n >= height || !n) return array; 358 | memmove(array,array+n*columns,(height-n)*columns); 359 | return array; 360 | 361 | } 362 | uint8_t * Buffer::scrollDown(int n) 363 | { 364 | if (n < 0) 365 | return scrollUp(-n); 366 | 367 | if (n >= height || !n) return array; 368 | memmove(array+n*columns,array,(height-n)*columns); 369 | return array; 370 | } 371 | uint8_t * Buffer::scrollRight(int n) 372 | { 373 | if (n < 0) 374 | return scrollLeft(-n); 375 | 376 | if (n > 8 || !n) return array; 377 | if (n == 8) 378 | { 379 | memmove(array+1,array,size-1); 380 | for (uint16_t l = 0; l < size; l+= columns) array[l] = 0; 381 | } 382 | else 383 | { 384 | uint8_t c,d; 385 | for (uint16_t l = 0; l < size; l+= columns) 386 | { 387 | c = 0; 388 | for (uint8_t p = 0; p < columns; p++) 389 | { 390 | d = array[p + l] << (8-n); 391 | array[p + l] = c | (array[p+l] >> n); 392 | c = d; 393 | } 394 | } 395 | } 396 | return array; 397 | } 398 | uint8_t * Buffer::scrollLeft(int n) 399 | { 400 | if (n < 0) 401 | return scrollRight(-n); 402 | 403 | if (n > 8 || !n) return array; 404 | if (n == 8) 405 | { 406 | memmove(array,array+1,size-1); 407 | for (uint16_t l = columns-1; l < size; l+= columns) array[l] = 0; 408 | } 409 | else 410 | { 411 | uint8_t c,d; 412 | for (uint16_t l = 0; l < size; l+= columns) 413 | { 414 | c = 0; 415 | for (uint8_t p = columns; p;) 416 | { 417 | d = array[--p + l] >> (8-n); 418 | array[p + l] = c | (array[p+l] << n); 419 | c = d; 420 | } 421 | } 422 | } 423 | return array; 424 | 425 | } 426 | //------------------------------------------------------------------------------------------------- 427 | // Overlay And / Or / Xor 428 | //------------------------------------------------------------------------------------------------- 429 | uint8_t * Buffer::overlay(uint8_t* other_buffer, uint8_t mode) 430 | { 431 | if (mode == AND) 432 | { 433 | for(uint16_t i=0; i < size; i++) array[i] &= other_buffer[i]; 434 | } 435 | else if (mode == XOR) 436 | { 437 | for(uint16_t i=0; i < size; i++) array[i] ^= other_buffer[i]; 438 | } 439 | else //Default OR 440 | { 441 | for(uint16_t i=0; i < size; i++) array[i] |= other_buffer[i]; 442 | } 443 | return array; 444 | } 445 | uint8_t * Buffer::overlay(Buffer other_buffer, uint8_t mode) 446 | { 447 | return overlay(other_buffer.ptr(),mode); 448 | } 449 | uint8_t * Buffer::overlay(const uint8_t* picture, uint8_t mode) 450 | { 451 | if (mode == AND) 452 | { 453 | for(uint16_t i=0; i < size; i++) array[i] &= picture[i]; 454 | } 455 | else if (mode == XOR) 456 | { 457 | for(uint16_t i=0; i < size; i++) array[i] ^= picture[i]; 458 | } 459 | else //Default OR 460 | { 461 | for(uint16_t i=0; i < size; i++) array[i] |= picture[i]; 462 | } 463 | return array; 464 | } 465 | //------------------------------------------------------------------------------------------------- 466 | // Overwrite / Copy 467 | //------------------------------------------------------------------------------------------------- 468 | uint8_t * Buffer::overwrite(Buffer other_buffer) 469 | { 470 | memcpy(array,other_buffer.ptr(),size); 471 | return array; 472 | } 473 | uint8_t * Buffer::overwrite(uint8_t* other_buffer) 474 | { 475 | memcpy(array,other_buffer,size); 476 | return array; 477 | } 478 | uint8_t * Buffer::overwrite(const uint8_t* picture) 479 | { 480 | memcpy(array,picture,size); 481 | return array; 482 | } 483 | //------------------------------------------------------------------------------------------------- 484 | // Area mirroring ; Unoptimized ; Does NOT Clip! 485 | //------------------------------------------------------------------------------------------------- 486 | void Buffer::flipV(int x, int y, int a, int b) 487 | { 488 | if (y+b > height || x+a > width || x < 0 || y < 0 || a<=0 || b<=0) return; 489 | uint16_t _lines = b/2; 490 | uint16_t d = y+b-1; 491 | bool c; 492 | for (uint16_t l = 0; l < _lines; l++) 493 | { 494 | for (uint16_t p = x; p < x+a; p++) 495 | { 496 | c = getPixel(p,y); 497 | setPixel(p,y,getPixel(p,d)); 498 | setPixel(p,d,c); 499 | } 500 | y++; 501 | d--; 502 | } 503 | } 504 | uint8_t * Buffer::flipV() 505 | { 506 | flipV(0,0,getWidth(),getHeight()); 507 | return array; 508 | } 509 | void Buffer::flipH(int x, int y, int a, int b) 510 | { 511 | if (y+b > height || x+a > width || x < 0 || y < 0 || a<=0 || b<=0) return; 512 | uint16_t _lines = a/2; 513 | uint16_t d = x+a-1; 514 | bool c; 515 | for (uint16_t l = 0; l < _lines; l++) 516 | { 517 | for (uint16_t p = y; p < y+b; p++) 518 | { 519 | c = getPixel(x,p); 520 | setPixel(x,p,getPixel(d,p)); 521 | setPixel(d,p,c); 522 | } 523 | x++; 524 | d--; 525 | } 526 | 527 | } 528 | uint8_t * Buffer::flipH() 529 | { 530 | flipH(0,0,getWidth(),getHeight()); 531 | return array; 532 | } 533 | //------------------------------------------------------------------------------------------------- 534 | // Area rotating ; Unoptimized ; Does NOT Clip! 535 | //------------------------------------------------------------------------------------------------- 536 | void Buffer::rotateR(int x, int y, int a) 537 | { 538 | if (y+a > height || x+a > width || x < 0 || y < 0 || a<=0) return; 539 | uint16_t r = x+a-1; 540 | uint16_t b = y+a-1; 541 | bool c; 542 | for (uint16_t q = 0; q < a/2; q++) 543 | { 544 | for (uint16_t p = 0; p < (a+1)/2; p++) 545 | { 546 | c = getPixel(x+p,y+q); 547 | setPixel(x+p,y+q,getPixel(x+q,b-p)); 548 | setPixel(x+q,b-p,getPixel(r-p,b-q)); 549 | setPixel(r-p,b-q,getPixel(r-q,y+p)); 550 | setPixel(r-q,y+p,c); 551 | } 552 | } 553 | } 554 | uint8_t * Buffer::rotateR() 555 | { 556 | rotateR(0,0,min(getHeight(),getWidth())); 557 | return array; 558 | } 559 | void Buffer::rotateL(int x, int y, int a) 560 | { 561 | if (y+a > height || x+a > width || x < 0 || y < 0 || a<=0) return; 562 | uint16_t r = x+a-1; 563 | uint16_t b = y+a-1; 564 | bool c; 565 | for (uint16_t q = 0; q < a/2; q++) 566 | { 567 | for (uint16_t p = 0; p < (a+1)/2; p++) 568 | { 569 | c = getPixel(x+p,y+q); 570 | setPixel(x+p,y+q,getPixel(r-q,y+p)); 571 | setPixel(r-q,y+p,getPixel(r-p,b-q)); 572 | setPixel(r-p,b-q,getPixel(x+q,b-p)); 573 | setPixel(x+q,b-p,c); 574 | } 575 | } 576 | 577 | } 578 | uint8_t * Buffer::rotateL() 579 | { 580 | rotateL(0,0,min(getHeight(),getWidth())); 581 | return array; 582 | } 583 | //------------------------------------------------------------------------------------------------- 584 | // Bitmap getting ; Does NOT clip! ; May crash when given memory (*buff) is not large enough! 585 | //------------------------------------------------------------------------------------------------- 586 | uint8_t * Buffer::getBitmap(int x, int y, uint16_t a, uint16_t b, uint8_t* buff) 587 | { 588 | if (y+b > height || x+a > width || x < 0 || y < 0 || !a || !b) return 0; //not entirely on screen 589 | uint16_t start_line = y; //included 590 | uint16_t start_col = x/8; // included 591 | uint16_t end_line = y+b; //excluded 592 | uint16_t end_col = (x+a+7)/8; //excluded 593 | uint8_t offset_left = x& 7; //bit offset 594 | uint8_t offset_right = (a+x)& 7; 595 | uint8_t mask = 0xFF << 8-(a& 7); 596 | if (!mask) mask = 0xFF; 597 | uint16_t i = 0; 598 | if (offset_left) //Not aligned 599 | { 600 | for (uint16_t l = start_line; l < end_line; l++) 601 | { 602 | for (uint16_t p = start_col+1; p < end_col; p++) 603 | buff[i++] = (array[l*columns+p-1] << offset_left) | (array[l*columns+p] >> 8-offset_left); 604 | if (offset_left < offset_right) 605 | buff[i++] = (array[l*columns+end_col-1] << offset_left); 606 | buff[i-1] &= mask; 607 | } 608 | } 609 | else //Aligned 610 | { 611 | for (uint16_t l = start_line; l < end_line; l++) 612 | { 613 | for (uint16_t p = start_col; p < end_col; p++) 614 | buff[i++] = array[l*columns+p]; 615 | buff[i-1] &= mask; 616 | } 617 | } 618 | return buff; 619 | } 620 | uint8_t * Buffer::getBitmap(int x, int y, Buffer buff2) 621 | { 622 | uint8_t * buff = buff2.ptr(); 623 | uint16_t a = buff2.getWidth(); 624 | uint16_t b = buff2.getHeight(); 625 | if (y+b > height || x+a > width || x < 0 || y < 0 || !a || !b) return 0; //not entirely on screen 626 | uint16_t start_line = y; //included 627 | uint16_t start_col = x/8; // included 628 | uint16_t end_line = y+b; //excluded 629 | uint16_t end_col = (x+a)/8; //excluded 630 | uint8_t offset = x& 7; //bit offset 631 | uint16_t i = 0; 632 | if (offset) //Not aligned 633 | { 634 | for (uint16_t l = start_line; l < end_line; l++) 635 | { 636 | for (uint16_t p = start_col; p < end_col; p++) 637 | buff[i++] = (array[l*columns+p] << offset) | (array[l*columns+p+1] >> 8-offset); 638 | } 639 | } 640 | else //Aligned 641 | { 642 | for (uint16_t l = start_line; l < end_line; l++) 643 | { 644 | for (uint16_t p = start_col; p < end_col; p++) 645 | buff[i++] = array[l*columns+p]; 646 | } 647 | } 648 | return buff; 649 | } 650 | //------------------------------------------------------------------------------------------------- 651 | // Bitmap drawing 652 | //------------------------------------------------------------------------------------------------- 653 | void Buffer::bitmap(int x, int y, Buffer pic_buffer, uint8_t mode) 654 | { 655 | bitmap(x,y,(uint16_t)pic_buffer.getWidth(),(uint16_t)pic_buffer.getHeight(),pic_buffer.ptr(),mode); 656 | } 657 | void Buffer::bitmap(int x, int y, uint16_t a, uint16_t b, const uint8_t* pic, uint8_t mode) 658 | { 659 | bitmap(x,y,a,b,(uint8_t*)(pic),mode); 660 | } 661 | void Buffer::bitmap(int x, int y, uint16_t a, uint16_t b, uint8_t* pic, uint8_t mode) 662 | { 663 | if (x >= width || y >= height || x+a <= 0 || y+b <= 0 || !a || !b) return; //outside screen 664 | uint16_t w_bmp = (a+7)/8; //width in bytes 665 | uint16_t start_line_bmp = 0; //included 666 | uint16_t start_col_bmp = 0; // included 667 | uint16_t end_line_bmp = b; //excluded 668 | uint16_t end_col_bmp = w_bmp; //excluded 669 | uint8_t offset = x& 7; //bit offset 670 | int dy = y; //vertical offset to get line on buffer; bmp_line+dy -> buff_y 671 | int dx = x/8; //... 672 | if (x + a > width) 673 | end_col_bmp = columns-(x/8); //right clipping 674 | if (y + b > height) 675 | end_line_bmp = height-y; //bottom clipping 676 | if (y < 0) 677 | start_line_bmp = -dy; //top clipping 678 | 679 | if (offset) //not aligned 680 | { 681 | if (x < 0) 682 | { 683 | offset = 8-(abs(x)& 7); //calculate new offset 684 | start_col_bmp = -dx; //left clipping 685 | dx--; //correct rounding issue when x < 0 686 | 687 | } 688 | uint8_t c,d; //shifted pixels 689 | if (mode == OFF) 690 | { 691 | for (uint16_t l = start_line_bmp; l < end_line_bmp; l++) 692 | { 693 | c = 0; 694 | int p = start_col_bmp; 695 | d = pic[l*w_bmp+p] << (8-offset); 696 | if (p+dx >= 0) 697 | { 698 | array[(l+dy)*columns+p+dx] &= ~(0xFF >> offset); 699 | array[(l+dy)*columns+p+dx] |= (pic[l*w_bmp+p] >> offset); 700 | } 701 | c = d; 702 | p++; 703 | for (; p < end_col_bmp; p++) 704 | { 705 | d = pic[l*w_bmp+p] << (8-offset); 706 | if (p+dx >= 0 && p+dx < columns) //don't mess up 707 | { 708 | array[(l+dy)*columns+p+dx] = (c | (pic[l*w_bmp+p] >> offset)); 709 | } 710 | c = d; 711 | } 712 | if (p+dx < columns) 713 | { 714 | array[(l+dy)*columns+p+dx] &= ~(0xFF << (8-offset)); 715 | array[(l+dy)*columns+p+dx] |= c; 716 | } 717 | } 718 | } 719 | else 720 | { 721 | for (uint16_t l = start_line_bmp; l < end_line_bmp; l++) 722 | { 723 | c = 0; 724 | int p; 725 | for (p = start_col_bmp; p < end_col_bmp; p++) 726 | { 727 | d = pic[l*w_bmp+p] << (8-offset); 728 | if (p+dx >= 0) //don't mess up 729 | { 730 | if (mode == XOR) 731 | array[(l+dy)*columns+p+dx] ^= (c | (pic[l*w_bmp+p] >> offset)); 732 | else 733 | array[(l+dy)*columns+p+dx] |= (c | (pic[l*w_bmp+p] >> offset)); 734 | } 735 | c = d; 736 | } 737 | if (p+dx < columns) 738 | { 739 | if (mode == XOR) 740 | array[(l+dy)*columns+p+dx] ^= c; 741 | else 742 | array[(l+dy)*columns+p+dx] |= c; 743 | } 744 | } 745 | } 746 | } 747 | else //Aligned bitmap 748 | { 749 | if (x < 0) 750 | start_col_bmp = -dx; //left clipping 751 | for (uint16_t l = start_line_bmp; l < end_line_bmp; l++) 752 | { 753 | for (uint16_t p = start_col_bmp; p < end_col_bmp; p++) 754 | { 755 | if (mode == OFF) 756 | array[(l+dy)*columns+p+dx] = pic[l*w_bmp+p]; 757 | else if (mode == XOR) 758 | array[(l+dy)*columns+p+dx] ^= pic[l*w_bmp+p]; 759 | else 760 | array[(l+dy)*columns+p+dx] |= pic[l*w_bmp+p]; 761 | } 762 | } 763 | } 764 | } 765 | void Buffer::writeByte(int x, int y, uint8_t data, uint8_t mode) 766 | { 767 | if (x >= width ||y >= height || x+8<=0 || y < 0) return; //outside screen 768 | 769 | uint8_t offset = x & 7; //bit offset 770 | if (offset) //not aligned 771 | { 772 | writeByte(x-offset,y,data>>offset,mode); 773 | writeByte(x+8-offset,y,data<<(8-offset),mode); 774 | } 775 | else //Aligned byte 776 | { 777 | uint8_t col = x / 8; 778 | if (mode == XOR) 779 | array[y*columns+col] ^= data; 780 | else 781 | array[y*columns+col] |= data; 782 | } 783 | } 784 | //------------------------------------------------------------------------------------------------- 785 | // Quadrilateral 786 | //------------------------------------------------------------------------------------------------- 787 | void Buffer::quad(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, uint8_t mode) 788 | { 789 | line(x0,y0,x1,y1,mode); 790 | line(x0,y0,x3,y3,mode); 791 | line(x1,y1,x2,y2,mode); 792 | line(x3,y3,x2,y2,mode); 793 | if (mode == XOR) 794 | { 795 | setPixel(x0,y0,XOR); 796 | setPixel(x1,y1,XOR); 797 | setPixel(x2,y2,XOR); 798 | setPixel(x3,y3,XOR); 799 | } 800 | } 801 | //------------------------------------------------------------------------------------------------- 802 | // Triangle 803 | //------------------------------------------------------------------------------------------------- 804 | void Buffer::tri(int x0, int y0, int x1, int y1, int x2, int y2, uint8_t mode) 805 | { 806 | line(x0,y0,x1,y1,mode); 807 | line(x0,y0,x2,y2,mode); 808 | line(x1,y1,x2,y2,mode); 809 | if (mode == XOR) 810 | { 811 | setPixel(x0,y0,XOR); 812 | setPixel(x1,y1,XOR); 813 | setPixel(x2,y2,XOR); 814 | } 815 | } 816 | //------------------------------------------------------------------------------------------------- 817 | // Circle 818 | //------------------------------------------------------------------------------------------------- 819 | void Buffer::circle(int cx, int cy, int radius, uint8_t mode) 820 | { 821 | if (radius <= 0) return; 822 | int x = radius, y = 0, xchange, ychange, radiusError; 823 | xchange = 1 - radius*2; 824 | ychange = 1; 825 | radiusError = 0; 826 | while (x >= y) 827 | { 828 | setPixel(cx+y, cy+x, mode); 829 | setPixel(cx-y, cy-x, mode); 830 | setPixel(cx+x, cy-y, mode); 831 | setPixel(cx-x, cy+y, mode); 832 | if (y && x && x!=y) //Fixes double pixel inverts on XOR mode 833 | { 834 | setPixel(cx-y, cy+x, mode); 835 | setPixel(cx+x, cy+y, mode); 836 | setPixel(cx-x, cy-y, mode); 837 | setPixel(cx+y, cy-x, mode); 838 | } 839 | y++; 840 | radiusError += ychange; 841 | ychange += 2; 842 | if (radiusError + radiusError + xchange > 0 ) 843 | { 844 | x--; 845 | radiusError += xchange; 846 | xchange += 2; 847 | } 848 | } 849 | } 850 | void Buffer::fillCircle(int cx, int cy, int radius, uint8_t mode) 851 | { 852 | if (radius <= 0) return; 853 | int x = radius, y = 0, xchange, ychange, radiusError; 854 | xchange = 1 - radius*2; 855 | ychange = 1; 856 | radiusError = 0; 857 | while (x >= y) 858 | { 859 | if (y && x != y) //Fixes double pixel inverts on XOR mode 860 | lineAcross(cx-x,cy+y,x+x+1,mode); 861 | if (x != y) 862 | lineAcross(cx-x,cy-y,x+x+1,mode); 863 | radiusError += ychange; 864 | ychange += 2; 865 | if (radiusError + radiusError + xchange > 0 ) 866 | { 867 | radiusError += xchange; 868 | xchange += 2; 869 | lineAcross(cx-y,cy-x,y+y+1,mode); 870 | lineAcross(cx-y,cy+x,y+y+1,mode); 871 | x--; 872 | } 873 | y++; 874 | } 875 | } 876 | //------------------------------------------------------------------------------------------------- 877 | // Vertical line 878 | //------------------------------------------------------------------------------------------------- 879 | void Buffer::lineDown(int x,int y, int h, uint8_t mode) 880 | { 881 | if (x < 0 || x >= width || y >= height) return; 882 | if (y < 0) 883 | { 884 | h = h+y; 885 | y = 0; 886 | } 887 | if (y + h >= height) 888 | h = height-y; 889 | if (h <= 0) return; 890 | uint8_t k = 128 >> (x& 7); 891 | h = x/8 + (y+h)*columns; 892 | if (mode == OFF) 893 | { 894 | for (uint16_t p = x/8 + y*columns; p < h ; p+= columns) array[p] &= ~k; 895 | } 896 | else if (mode == XOR) 897 | { 898 | for (uint16_t p = x/8 + y*columns; p < h ; p+= columns) array[p] ^= k; 899 | } 900 | else 901 | { 902 | for (uint16_t p = x/8 + y*columns; p < h ; p+= columns) array[p] |= k; 903 | } 904 | } 905 | //------------------------------------------------------------------------------------------------- 906 | // Horizontal line 907 | //------------------------------------------------------------------------------------------------- 908 | void Buffer::lineAcross(int x,int y, int w, uint8_t mode) 909 | { 910 | if (y < 0 || y >= height || x >= width) return; 911 | if (x < 0) 912 | { 913 | w = w+x; 914 | x = 0; 915 | } 916 | if (x + w > width) 917 | w = width-x; 918 | if (w <= 0) return; 919 | if ((x& 7)+w <= 8) 920 | { 921 | uint8_t m = 0xFF << (8-w); 922 | m >>= (x& 7); 923 | if (mode == OFF) array[y*columns+x/8] &= ~m; 924 | else if (mode == XOR) array[y*columns+x/8] ^= m; 925 | else array[y*columns+x/8] |= m; 926 | 927 | } 928 | else 929 | { 930 | uint16_t start = y*columns+(x+7)/8; //included 931 | uint16_t end = y*columns+(x+w)/8; //not included 932 | if (mode == OFF) 933 | { 934 | if (x& 7) array[start-1] &= ~(0xFF >> (x& 7)); 935 | for (uint16_t p = start; p < end ; p++) array[p] = 0; 936 | if ((x+w)& 7) array[end] &= ~(0xFF << (8-(x+w)& 7)); 937 | } 938 | else if (mode == XOR) 939 | { 940 | if (x& 7) array[start-1] ^= 0xFF >> (x& 7); 941 | for (uint16_t p = start; p < end ; p++) array[p] ^= 0xFF; 942 | if ((x+w)& 7) array[end] ^= 0xFF << (8-(x+w)& 7); 943 | } 944 | else 945 | { 946 | if (x& 7) array[start-1] |= 0xFF >> (x& 7); 947 | for (uint16_t p = start; p < end ; p++) array[p] = 0xFF; 948 | if ((x+w)& 7) array[end] |= 0xFF << (8-(x+w)& 7); 949 | } 950 | } 951 | } 952 | 953 | //------------------------------------------------------------------------------------------------- 954 | // Any line 955 | //------------------------------------------------------------------------------------------------- 956 | void Buffer::line(int x1,int y1, int x2, int y2, uint8_t mode) 957 | { 958 | int CurrentX, CurrentY, Xinc, Yinc, Dx, Dy, TwoDx, TwoDy, AccumulatedError; 959 | Dx = x2-x1; 960 | Dy = y2-y1; 961 | CurrentX = x1; 962 | CurrentY = y1; 963 | Xinc = 1; 964 | Yinc = 1; 965 | if(Dx < 0) 966 | { 967 | Xinc = -1; 968 | Dx = -Dx; 969 | } 970 | if (Dy < 0) 971 | { 972 | Yinc = -1; 973 | Dy = -Dy; 974 | } 975 | TwoDx = Dx + Dx; 976 | TwoDy = Dy + Dy; 977 | setPixel(x1,y1, mode); 978 | if (Dx || Dy) 979 | { 980 | if (Dy <= Dx) 981 | { 982 | AccumulatedError = 0; 983 | do 984 | { 985 | CurrentX += Xinc; 986 | AccumulatedError += TwoDy; 987 | if(AccumulatedError > Dx) 988 | { 989 | CurrentY += Yinc; 990 | AccumulatedError -= TwoDx; 991 | } 992 | setPixel(CurrentX,CurrentY, mode); 993 | } 994 | while (CurrentX != x2); 995 | } 996 | else 997 | { 998 | AccumulatedError = 0; 999 | do 1000 | { 1001 | CurrentY += Yinc; 1002 | AccumulatedError += TwoDx; 1003 | if(AccumulatedError > Dy) 1004 | { 1005 | CurrentX += Xinc; 1006 | AccumulatedError -= TwoDy; 1007 | } 1008 | setPixel(CurrentX,CurrentY, mode); 1009 | } 1010 | while (CurrentY != y2); 1011 | } 1012 | } 1013 | } 1014 | //------------------------------------------------------------------------------------------------- 1015 | // filled Rectangle 1016 | //------------------------------------------------------------------------------------------------- 1017 | void Buffer::fillRect(int x, int y, int a, int b, uint8_t mode) 1018 | { 1019 | if (x + a > width) 1020 | a = width-x; 1021 | if (y + b > height) 1022 | b = height-y; 1023 | if (x < 0) 1024 | { 1025 | a = a+x; 1026 | x = 0; 1027 | } 1028 | if (y < 0) 1029 | { 1030 | b = b+y; 1031 | y = 0; 1032 | } 1033 | if (y >= height || x >= width || a <= 0 || b <= 0) return; 1034 | uint16_t bottom; 1035 | uint8_t left = (x& 7); 1036 | if (left+a <= 8) //only one byte? 1037 | { 1038 | uint8_t m = 0xFF << (8-a); 1039 | m >>= left; 1040 | bottom = (y+b)*columns; 1041 | if (mode == OFF) 1042 | { 1043 | for (uint16_t l = y*columns+x/8; l < bottom; l+=columns) 1044 | array[l] &= ~m; 1045 | } 1046 | else if (mode == XOR) 1047 | { 1048 | for (uint16_t l = y*columns+x/8; l < bottom; l+=columns) 1049 | array[l] ^= m; 1050 | } 1051 | else 1052 | { 1053 | for (uint16_t l = y*columns+x/8; l < bottom; l+=columns) 1054 | array[l] |= m; 1055 | } 1056 | } 1057 | else 1058 | { 1059 | uint8_t right = (x+a)& 7; 1060 | uint16_t start = y*columns+(x+7)/8; //included 1061 | uint16_t end = y*columns+(x+a)/8; //not included 1062 | uint8_t l_m = 0xFF >> left; 1063 | uint8_t r_m = 0xFF << 8-right; 1064 | bottom = b*columns; 1065 | if (mode == OFF) 1066 | { 1067 | for (uint16_t l = 0; l < bottom; l+=columns) 1068 | { 1069 | if (left) array[l+start-1] &= ~l_m; 1070 | for (uint16_t p = start; p < end ; p++) array[l+p] = 0; 1071 | if (right) array[l+end] &= ~r_m; 1072 | } 1073 | } 1074 | else if (mode == XOR) 1075 | { 1076 | for (uint16_t l = 0; l < bottom; l+=columns) 1077 | { 1078 | if (left) array[l+start-1] ^= l_m; 1079 | for (uint16_t p = start; p < end ; p++) array[l+p] ^= 0xFF; 1080 | if (right) array[l+end] ^= r_m; 1081 | } 1082 | } 1083 | else 1084 | { 1085 | for (uint16_t l = 0; l < bottom; l+=columns) 1086 | { 1087 | if (left) array[l+start-1] |= l_m; 1088 | for (uint16_t p = start; p < end ; p++) array[l+p] = 0xFF; 1089 | if (right) array[l+end] |= r_m; 1090 | } 1091 | } 1092 | } 1093 | } 1094 | //------------------------------------------------------------------------------------------------- 1095 | // Rectangular Frame 1096 | //------------------------------------------------------------------------------------------------- 1097 | void Buffer::rect(int x, int y, int a, int b, uint8_t mode) 1098 | { 1099 | lineAcross(x,y,a,mode); 1100 | if (b > 1) lineAcross(x,y+b-1,a,mode); 1101 | if (b > 2) 1102 | { 1103 | lineDown(x,y+1,b-2,mode); 1104 | lineDown(x+a-1,y+1,b-2,mode); 1105 | } 1106 | } 1107 | -------------------------------------------------------------------------------- /Buffer.h: -------------------------------------------------------------------------------- 1 | /*------------------------------------------------------------------------------------------------- 2 | // *** Change Log / Version history *** 3 | // 4 | // 0.1 - A basic Graphics library for buffers, 5 | // made to use it with any low res (up to 256 x 256 pix) monochrome LCD 6 | // The LCD must have a width which is divisible by 8 and 7 | // the data has to be stored byte-wise (1 bit = 1 pixel) starting at the top left. 8 | // For further information on how to use the functions, read the Documentation.pdf 9 | // Made by Marvin G. aka MGOS / Apr 28 2013 10 | // request, bug reports and qustions to: marv.mgos@gmail.com 11 | //-----------------------------------------------------------------------------------------------*/ 12 | 13 | /*------------------------------------------------------------------------------------------------- 14 | // You are allowed to copy, distribute or modify the source code of this library. 15 | // Any modification you make should be added to the change log / version history 16 | // in this document and at the top of each source file, including the author, 17 | // the date and all changes made. 18 | // 19 | // Release into public domain. 20 | //-----------------------------------------------------------------------------------------------*/ 21 | #ifndef BUFFER_h 22 | #define BUFFER_h 23 | 24 | #include "Arduino.h" 25 | #include "inttypes.h" 26 | 27 | 28 | //Drawing Modes 29 | #define OFF 0 30 | #define CLEAR 0 31 | #define ON 1 32 | #define FILLED 1 33 | #define XOR 2 34 | #define INVERT 2 35 | #define OR 3 36 | #define AND 4 37 | 38 | 39 | class Buffer{ 40 | public: 41 | Buffer(uint8_t * RAM_area, int16_t pixHor, int16_t pixVer); //Constructor 42 | //Control 43 | int16_t getWidth(void); //Returns size of buffer 44 | int16_t getHeight(void); //Returns size of buffer 45 | uint8_t* ptr(void); //Returns pointer to graphics area 46 | uint8_t* ptr(uint8_t* new_pointer); //Changes pointer to another Ram area 47 | 48 | //Buffer manipulation 49 | uint8_t* overwrite(Buffer other_buffer); 50 | uint8_t* overwrite(uint8_t* other_buffer); //Copies another buffer (must be same size!) to this buffer and overwrites it. 51 | uint8_t* overwrite(const uint8_t* picture); 52 | uint8_t* overlay(Buffer other_buffer, uint8_t mode); 53 | uint8_t* overlay(uint8_t* other_buffer, uint8_t mode); //Puts another on top of this buffer. modes availlable are: OR / AND / XOR 54 | uint8_t* overlay(const uint8_t* picture, uint8_t mode); 55 | uint8_t* invert(void); //Inverts the colors 56 | uint8_t* clear(void); //Clears the screen 57 | uint8_t* fill(uint8_t n); //fills every location with specified byte. 58 | 59 | 60 | void scrollUp(int x, int y, int a, int b); //Scrolls the content of the given area up one pixel 61 | void scrollDown(int x, int y, int a, int b); //Scrolls the content of the given area down one pixel 62 | void scrollLeft(int x, int y, int a, int b); //Scrolls the content of the given area left one pixel 63 | void scrollRight(int x, int y, int a, int b); //Scrolls the content of the given area right one pixel 64 | uint8_t* scrollUp(int n); //Same as the above, but applies on whole buffer and number of pixels to scroll can be specified 65 | uint8_t* scrollDown(int n); 66 | uint8_t* scrollLeft(int n); // |n| <= 8 67 | uint8_t* scrollRight(int n); 68 | 69 | 70 | void flipV(int x, int y, int a, int b); //Flips the given area vertically 71 | void flipH(int x, int y, int a, int b); //Flips the given area horizontally 72 | void rotateR(int x, int y, int a); //Rotates the given square clockwise 73 | void rotateL(int x, int y, int a); //Rotates the given square counter clockwise 74 | uint8_t * flipV(void); //Same as the above, but applies on whole buffer 75 | uint8_t * flipH(void); 76 | uint8_t * rotateR(void); 77 | uint8_t * rotateL(void); 78 | 79 | //Drawing 80 | void fillRect(int x, int y, int a, int b, uint8_t mode); //Draws a filled rectangle at top left x|y a pixels wide and b pixels high 81 | //Modes available: ON=FILLED / OFF=CLEAR / XOR=INVERT 82 | void rect(int x, int y, int a, int b, uint8_t mode); //Draws a rectangular frame at top left x|y a pixels wide and b pixels high 83 | //line styles available: ON=FILLED / OFF=CLEAR / XOR=INVERT 84 | void line(int x1,int y1, int x2, int y2, uint8_t mode); //Draws a line from x1|y1 to x2|y2 85 | //line styles available: ON=FILLED / OFF=CLEAR / XOR=INVERT 86 | void lineAcross(int x,int y, int w, uint8_t mode); //Draws a horizontal, w pixels long line from x|y to the right. 87 | //line styles available: ON=FILLED / OFF=CLEAR / XOR=INVERT 88 | void lineDown(int x,int y, int h, uint8_t mode); //Draws a vertical, h pixels long line from x|y to the bottom. 89 | //line styles available: ON=FILLED / OFF=CLEAR / XOR=INVERT 90 | void circle(int cx, int cy, int radius, uint8_t mode); //Draws a circle with center cx|cy and given radius 91 | //line styles available: ON=FILLED / OFF=CLEAR / XOR=INVERT 92 | void fillCircle(int cx, int cy, int radius, uint8_t mode); //Draws a filled circle with center cx|cy and given radius 93 | 94 | void quad(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3, uint8_t mode); 95 | void tri(int x0, int y0, int x1, int y1, int x2, int y2, uint8_t mode); 96 | 97 | //Pixel access 98 | void setPixel(int x, int y, uint8_t mode); //Sets the state of the pixel x|y. Modes/Colors available: ON=FILLED / OFF=CLEAR / XOR=INVERT 99 | bool getPixel(int x, int y); //Returns whether a pixel is set (1) or not (0). 100 | 101 | //Bitmaps 102 | void bitmap(int x, int y, uint16_t a, uint16_t b, uint8_t* pic, uint8_t mode); //Draws a*b bitmap at top left x,y; Modes available OR=FILLED=ON / XOR=INVERT / OFF=CLEAR (deletes background) 103 | void bitmap(int x, int y, uint16_t a, uint16_t b, const uint8_t* pic, uint8_t mode); 104 | void bitmap(int x, int y, Buffer pic_buffer, uint8_t mode); //Same as first, but takes a buffer as a bitmap 105 | void writeByte(int x, int y, uint8_t data, uint8_t mode); //writes a single line of 8 bits; Modes available OR=FILLED=ON / XOR=INVERT 106 | 107 | uint8_t* getBitmap(int x, int y, uint16_t a, uint16_t b, uint8_t* buff); //Takes a screenshoot of the given area and stores it in another buffer. "Bitmap backwards" 108 | uint8_t* getBitmap(int x, int y, Buffer buff2); //Same as above, but screenshot is as large as the buffer given. 109 | 110 | private: 111 | uint8_t * array; //pointer to buffer array 112 | uint16_t size; //#Bytes the buffer holds (Width/8 * Height) 113 | int16_t width; 114 | int16_t height; 115 | uint8_t columns; //#Columns the buffer has (Width/8) 116 | }; 117 | 118 | 119 | 120 | 121 | 122 | #endif // BUFFER_h 123 | -------------------------------------------------------------------------------- /HUB08SPI.cpp: -------------------------------------------------------------------------------- 1 | #include "HUB08SPI.h" 2 | #include "Arduino.h" 3 | 4 | HUB08SPI::HUB08SPI() 5 | { 6 | } 7 | 8 | void HUB08SPI::begin(uint8_t *displaybuf, uint16_t width, uint16_t height) 9 | { 10 | this->displaybuf = displaybuf; 11 | this->width = width; 12 | this->height = height; 13 | DDRD |= 0xFC; // BIN = 0b11111100 ==> SET PIN 7,6,5,4,3,2 = OUTPUT ==> pin 1,0 = not change 14 | TCCR2B = TCCR2B & 0b11111000 | 0x01; //32khz pwm on pin 3 & 11 15 | SPI.begin(); 16 | analogWrite(3,128); // default brightness 17 | } 18 | 19 | void HUB08SPI::drawPoint(uint16_t x, uint16_t y, uint8_t color) 20 | { 21 | uint8_t *byte = displaybuf + x / 8 + y * width / 8; 22 | uint8_t bit = x % 8; 23 | 24 | if (color) 25 | *byte |= 0x80 >> bit; 26 | else 27 | *byte &= ~(0x80 >> bit); 28 | } 29 | 30 | void HUB08SPI::drawRect(uint16_t x1, uint16_t y1, uint16_t w, uint16_t h, uint8_t color) 31 | { 32 | for (uint16_t x = x1; x < x1+w; x++){ 33 | for (uint16_t y = y1; y < y1+h; y++){ 34 | drawPoint(x, y, color); 35 | } 36 | } 37 | } 38 | void HUB08SPI::clear() 39 | { 40 | uint8_t *ptr = displaybuf; 41 | for (uint16_t i = 0; i < (width * height / 8); i++) 42 | { 43 | *ptr = 0x00; 44 | ptr++; 45 | } 46 | } 47 | 48 | void HUB08SPI::scan() 49 | { 50 | static uint8_t row = 0; // from 0 to 15 51 | uint8_t *head = displaybuf + row * (width/ 8); 52 | for (uint8_t line = 0; line < (height / 16); line++) //when more than 16 line display 53 | { 54 | uint8_t *ptr = head; 55 | head += width * 2; // width * 16 / 8 56 | for (uint8_t byte = 0; byte < (width / 8); byte++) 57 | { 58 | //CHANGE THIS IF DISPLAY INVERT 59 | //SPI.transfer(~*ptr); 60 | SPI.transfer(*ptr); 61 | ptr++; 62 | } 63 | } 64 | 65 | uint16_t r = -2000; //timeout. If something is wrong with the connection, we do not want to wait forever. This value is incremented each cycle of the blocking wait - while loop to bail out evantually, when OE never goes HIGH. 66 | while (!(PIND & (1<<3)) && ++r); // Wait for OE to go HIGH or Timeout (r == 0) 67 | uint8_t t = (PIND & 0x0F) | (row <<4); //?? Select row by binary? e.g. 1 -> A or 3 -> A,B or 5 -> A,C? yes, exactly. I shift row by 4 and or it to the output to make row appear on the upper half of Port D. the lower half must remain the same. 68 | PORTD = t; 69 | PIND = 1<<2; //toggle latch. It's a lesser known feature of the atmega controllers. Writing to PINx toggles the output in only one processor cycle 70 | PIND = 1<<2; 71 | row = (row + 1) & 0x0F; // Everytime this function is called, it scans the next line. Lines only range from 0 to 15. "& 0xF" equals "% 16", so it wraps back to 0 after reaching 15. 72 | 73 | 74 | } 75 | void HUB08SPI::setBrightness(uint8_t brightness){ 76 | analogWrite(3,255-dim_curve[brightness]); 77 | } 78 | -------------------------------------------------------------------------------- /HUB08SPI.h: -------------------------------------------------------------------------------- 1 | #ifndef __HUB08SPI_H__ 2 | #define __HUB08SPI_H__ 3 | 4 | #include 5 | #include 6 | 7 | const byte dim_curve[] = 8 | { 9 | 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 10 | 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 11 | 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 12 | 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 13 | 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 14 | 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15 | 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 16 | 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, 17 | 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, 18 | 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, 19 | 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 20 | 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, 21 | 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, 22 | 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, 23 | 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, 24 | 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 247, 252, 25 | }; 26 | 27 | class HUB08SPI { 28 | public: 29 | HUB08SPI(); 30 | void begin(uint8_t *displaybuf, uint16_t width, uint16_t height); 31 | void drawPoint(uint16_t x, uint16_t y, uint8_t color); 32 | void drawRect(uint16_t x1, uint16_t y1, uint16_t h, uint16_t w, uint8_t color); 33 | void clear(); 34 | void scan(); 35 | void setBrightness(uint8_t brightness); 36 | 37 | private: 38 | uint8_t *displaybuf; 39 | uint16_t width; 40 | uint16_t height; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 fahroniganteng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RONN ANIMATION - V1.0 2 | This is arduino library for creating animation on matrix led. 3 | > NOTE : only supports single color matrix led and HUB08 connector. 4 | 5 | ## Components 6 | - **MATRIX LED** single color with connector **HUB08** (P7.62, P4.75, etc). 7 | - **ARDUINO**, tested on ATMEGA328 (Arduino NANO, UNO and PRO MINI 5V version). 8 | 9 | ## Demo 10 | [![DEMO](http://img.youtube.com/vi/jYppBStfILE/0.jpg)](https://youtu.be/jYppBStfILE) 11 | 12 | ## How to install 13 | Just download, open with arduino IDE and upload into arduino board (all libraries included). 14 | [![TUTORIAL](http://img.youtube.com/vi/RXkWcjTcCjA/0.jpg)](https://youtu.be/RXkWcjTcCjA) 15 | >Video tutorial in indonesia language. 16 | >Content : 17 | >1. Install 18 | >2. Make custom font 19 | >3. Make custom bitmap 20 | 21 | ## Wiring 22 | HUB08 (matrix led) to ARDUINO pin connection 23 | - LA / A -> Digital Pin 4 24 | - LB / B -> Digital Pin 5 25 | - LC / C -> Digital Pin 6 26 | - LD / D -> Digital Pin 7 27 | - S / CLK -> Digital Pin 13 28 | - R1 / R -> Digital Pin 11 29 | - OE / EN -> Digital Pin 3 30 | - L / LAT / STB -> Digital Pin 2 31 | 32 | Example wiring on Arduino Mini board. 33 | ![Wiring](Tool/wiring.png) 34 | 35 | > SPI connection based from HUB08SPI.h, check into original library for details (https://github.com/emgoz/HUB08SPI). 36 | 37 | ## Usage 38 | ### Required libraries 39 | ~~~C 40 | #include 41 | #include 42 | #include "HUB08SPI.h" 43 | #include "TimerOne.h" 44 | #include "Buffer.h" 45 | 46 | #define WIDTH 64 // width of led matrix (pixel) 47 | #define HEIGHT 16 // height of led matrix 48 | 49 | HUB08SPI display; 50 | uint8_t displaybuf[WIDTH * HEIGHT / 8]; 51 | Buffer buff(displaybuf,64,16); 52 | 53 | //make sure to put after create buffer 54 | #include "ronnAnimation.h" 55 | ~~~ 56 | > All libraries included, you don't need to install manually. 57 | 58 | 59 | 60 | ### Animation function 61 | First, you need create a font. 62 | Several fonts have been created, but you can also create your own. Check **Font Builder.xlsm** in the ***Tool*** folder. 63 | > Fonts created based on the MD_MAX72xx library (only fonts, not include MD_MAX72xx libraries). 64 | > Original tool can be found at https://github.com/MajicDesigns/MD_MAX72XX/tree/main/Font%20Builder/Excel 65 | 66 | Default variable name for call the class is ***ronn***. So you can call a function like : 67 | ```C 68 | ronn.setFont(font_DEFAULT); 69 | ronn.printText("Demo Ronn Animation"); 70 | etc... 71 | ``` 72 | #### 1. Set Font 73 | For call the font 74 | ```C 75 | setFont(fontType_t *f=font_DEFAULT); //*f = variable font name 76 | ``` 77 | #### 2. Write text animation 78 | ```C 79 | printText(String string, int x, int y); // text,X,Y 80 | printText_R(String string, int x, int y, int s); // text,X,Y,speed --> print right with delay animation 81 | printText_RC(String string, int x, int y, int s); // text,X,Y,speed --> print right with delay and cursor animation 82 | printText_L(String string, int x, int y, int s); // text,X,Y,speed --> print left with delay animation 83 | printText_LC(String string, int x, int y, int s); // text,X,Y,speed --> print left with delay and cursor animation 84 | scanText_L(String string, int x, int y, int s); // text,X,Y,speed --> scan left animation 85 | scanText_R(String string, int x, int y, int s); // text,X,Y,speed --> scan right animation 86 | ``` 87 | 88 | #### 3. Scrolling text animation 89 | Vertical Scroll 90 | ```C 91 | scrollText_U(String string, int x, int y, int w, int s=20); //text,X,Y,width,speed --> scroll text up 92 | scrollText_D(String string, int x, int y, int w, int s=20); //text,X,Y,width,speed --> scroll text down 93 | 94 | ``` 95 | Scroll to left until first character in X position (until left character) 96 | ```C 97 | scrollText_LL(String string, int x, int y, int w, int s); //text,X,Y,width,speed (height auto from font height) 98 | ``` 99 | Scroll to left until last character (until right character) 100 | > You can use this function for continues scroll text (put on loop) 101 | ```C 102 | scrollText_LR(String string, int x, int y, int w, int s); //text,X,Y,width,speed (height auto from font height) 103 | ``` 104 | 105 | #### 4. Move animation 106 | ```C 107 | move_U(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT); //step,speed,X,Y,width,height --> move up 108 | move_L(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT); //step,speed,X,Y,width,height --> move left 109 | move_R(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT); //step,speed,X,Y,width,height --> move right 110 | move_D(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT); //step,speed,X,Y,width,height --> move down 111 | ``` 112 | Custom move 113 | ```C 114 | moveTo(char* moving[], int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT); //array direction & step,speed,X,Y,width,height 115 | ``` 116 | example using moveTo: 117 | ```C 118 | char* moving[] = {"D:6", "P:500", "L:20", "U:2","R:41","E:0"}; 119 | 120 | // move all area 121 | ronn.moveTo(moving); 122 | 123 | // move spesific area 124 | ronn.moveTo(moving,20,16,0,5,5); 125 | 126 | ``` 127 | Result: 128 | Move down 6 pixel --> parking 500ms --> move left 20 pixel --> move up 2 pixel --> move right 41 pixel --> end 129 | 130 | 131 | #### 5. Clear animation 132 | Clear spesific area 133 | ```C 134 | clear_L(int x, int y, int w, int h, int m); //X,Y,width,height,mode(SCROLL,CLEAR) --> clear left 135 | clear_R(int x, int y, int w, int h, int m); //X,Y,width,height,mode(SCROLL,CLEAR) --> clear right 136 | clear_D(int x, int y, int w, int h, int m); //X,Y,width,height,mode(SCROLL,CLEAR) --> clear down 137 | clear_U(int x, int y, int w, int h, int m); //X,Y,width,height,mode(SCROLL,CLEAR) --> clear up 138 | ``` 139 | 140 | Clear all pixel on display 141 | ```C 142 | clear_L(int m); //mode(SCROLL,CLEAR); --> clear left 143 | clear_R(int m); //mode(SCROLL,CLEAR); --> clear right 144 | clear_D(int m); //mode(SCROLL,CLEAR); --> clear down 145 | clear_U(int m); //mode(SCROLL,CLEAR); --> clear up 146 | ``` 147 | 148 | Clear slice 149 | ```C 150 | clearSlice_L(int x, int y, int w, int h); //X,Y,width,height --> clear slice left 151 | clearSlice_R(int x, int y, int w, int h); //X,Y,width,height --> clear slice right 152 | clearSlice_L(); // all pixel --> clear slice left 153 | clearSlice_R(); // all pixel --> clear slice right 154 | ``` 155 | 156 | Other clear animation 157 | ```C 158 | clear_A1(); // all pixel --> random pixel and scroll to center 159 | clear_A2(); // all pixel --> blink out 160 | ``` 161 | 162 | #### 6. Bitmap 163 | Yup, apart from fonts, you can also create images from bitmaps. 164 | Bitmap function actually from BufferGraphics libraries, check into original library for details, or you can check from the sample sketch. 165 | You can also download tool for creating bitmaps ***Monochrome Bitmap to Code Coverter.exe*** from original repository https://github.com/emgoz/BufferGraphics/tree/master/Tools. 166 | 167 | ## License and credits 168 | Ronn Animation under MIT license. 169 | Other libraries follow their own license. 170 | - HUB08SPI.h under MIT License (https://github.com/emgoz/HUB08SPI) 171 | - BufferGraphics under MIT License (https://github.com/emgoz/BufferGraphics) 172 | - TimerOne (https://github.com/PaulStoffregen/TimerOne) 173 | - Part of font under LGPL-2.1 License (https://github.com/MajicDesigns/MD_MAX72XX) 174 | 175 | ## Donation 176 | Support me 177 | - [Send me coffee](https://sociabuzz.com/fahroniganteng/tribe) 178 | - [or maybe ice cream](https://trakteer.id/fahroniganteng/tip) 179 | 180 | -------------------------------------------------------------------------------- /TimerOne.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 3 | * Original code by Jesse Tane for http://labs.ideo.com August 2008 4 | * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support 5 | * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop 6 | * Modified Oct 2009 by Dan Clemens to work with timer1 of the ATMega1280 or Arduino Mega 7 | * Modified April 2012 by Paul Stoffregen 8 | * Modified again, June 2014 by Paul Stoffregen 9 | * Modified July 2017 by Stoyko Dimitrov - added support for ATTiny85 except for the PWM functionality 10 | * 11 | * This is free software. You can redistribute it and/or modify it under 12 | * the terms of Creative Commons Attribution 3.0 United States License. 13 | * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ 14 | * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. 15 | * 16 | */ 17 | 18 | #include "TimerOne.h" 19 | 20 | TimerOne Timer1; // preinstatiate 21 | 22 | unsigned short TimerOne::pwmPeriod = 0; 23 | unsigned char TimerOne::clockSelectBits = 0; 24 | void (*TimerOne::isrCallback)() = TimerOne::isrDefaultUnused; 25 | 26 | // interrupt service routine that wraps a user defined function supplied by attachInterrupt 27 | #if defined (__AVR_ATtiny85__) 28 | ISR(TIMER1_COMPA_vect) 29 | { 30 | Timer1.isrCallback(); 31 | } 32 | #elif defined(__AVR__) 33 | ISR(TIMER1_OVF_vect) 34 | { 35 | Timer1.isrCallback(); 36 | } 37 | #elif defined(__arm__) && defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL)) 38 | void ftm1_isr(void) 39 | { 40 | uint32_t sc = FTM1_SC; 41 | #ifdef KINETISL 42 | if (sc & 0x80) FTM1_SC = sc; 43 | #else 44 | if (sc & 0x80) FTM1_SC = sc & 0x7F; 45 | #endif 46 | Timer1.isrCallback(); 47 | } 48 | #elif defined(__arm__) && defined(TEENSYDUINO) && defined(__IMXRT1062__) 49 | void TimerOne::isr(void) 50 | { 51 | FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF; 52 | Timer1.isrCallback(); 53 | } 54 | 55 | #endif 56 | 57 | void TimerOne::isrDefaultUnused() 58 | { 59 | } 60 | -------------------------------------------------------------------------------- /TimerOne.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Interrupt and PWM utilities for 16 bit Timer1 on ATmega168/328 3 | * Original code by Jesse Tane for http://labs.ideo.com August 2008 4 | * Modified March 2009 by Jérôme Despatis and Jesse Tane for ATmega328 support 5 | * Modified June 2009 by Michael Polli and Jesse Tane to fix a bug in setPeriod() which caused the timer to stop 6 | * Modified April 2012 by Paul Stoffregen - portable to other AVR chips, use inline functions 7 | * Modified again, June 2014 by Paul Stoffregen - support Teensy 3.x & even more AVR chips 8 | * Modified July 2017 by Stoyko Dimitrov - added support for ATTiny85 except for the PWM functionality 9 | * 10 | * 11 | * This is free software. You can redistribute it and/or modify it under 12 | * the terms of Creative Commons Attribution 3.0 United States License. 13 | * To view a copy of this license, visit http://creativecommons.org/licenses/by/3.0/us/ 14 | * or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. 15 | * 16 | */ 17 | 18 | #ifndef TimerOne_h_ 19 | #define TimerOne_h_ 20 | 21 | #if defined(ARDUINO) && ARDUINO >= 100 22 | #include "Arduino.h" 23 | #else 24 | #include "WProgram.h" 25 | #endif 26 | 27 | #include "config/known_16bit_timers.h" 28 | #if defined (__AVR_ATtiny85__) 29 | #define TIMER1_RESOLUTION 256UL // Timer1 is 8 bit 30 | #elif defined(__AVR__) 31 | #define TIMER1_RESOLUTION 65536UL // Timer1 is 16 bit 32 | #else 33 | #define TIMER1_RESOLUTION 65536UL // assume 16 bits for non-AVR chips 34 | #endif 35 | 36 | // Placing nearly all the code in this .h file allows the functions to be 37 | // inlined by the compiler. In the very common case with constant values 38 | // the compiler will perform all calculations and simply write constants 39 | // to the hardware registers (for example, setPeriod). 40 | 41 | 42 | class TimerOne 43 | { 44 | 45 | #if defined (__AVR_ATtiny85__) 46 | public: 47 | //**************************** 48 | // Configuration 49 | //**************************** 50 | void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { 51 | TCCR1 = _BV(CTC1); //clear timer1 when it matches the value in OCR1C 52 | TIMSK |= _BV(OCIE1A); //enable interrupt when OCR1A matches the timer value 53 | setPeriod(microseconds); 54 | } 55 | void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { 56 | const unsigned long cycles = microseconds * ratio; 57 | if (cycles < TIMER1_RESOLUTION) { 58 | clockSelectBits = _BV(CS10); 59 | pwmPeriod = cycles; 60 | } else 61 | if (cycles < TIMER1_RESOLUTION * 2UL) { 62 | clockSelectBits = _BV(CS11); 63 | pwmPeriod = cycles / 2; 64 | } else 65 | if (cycles < TIMER1_RESOLUTION * 4UL) { 66 | clockSelectBits = _BV(CS11) | _BV(CS10); 67 | pwmPeriod = cycles / 4; 68 | } else 69 | if (cycles < TIMER1_RESOLUTION * 8UL) { 70 | clockSelectBits = _BV(CS12); 71 | pwmPeriod = cycles / 8; 72 | } else 73 | if (cycles < TIMER1_RESOLUTION * 16UL) { 74 | clockSelectBits = _BV(CS12) | _BV(CS10); 75 | pwmPeriod = cycles / 16; 76 | } else 77 | if (cycles < TIMER1_RESOLUTION * 32UL) { 78 | clockSelectBits = _BV(CS12) | _BV(CS11); 79 | pwmPeriod = cycles / 32; 80 | } else 81 | if (cycles < TIMER1_RESOLUTION * 64UL) { 82 | clockSelectBits = _BV(CS12) | _BV(CS11) | _BV(CS10); 83 | pwmPeriod = cycles / 64UL; 84 | } else 85 | if (cycles < TIMER1_RESOLUTION * 128UL) { 86 | clockSelectBits = _BV(CS13); 87 | pwmPeriod = cycles / 128; 88 | } else 89 | if (cycles < TIMER1_RESOLUTION * 256UL) { 90 | clockSelectBits = _BV(CS13) | _BV(CS10); 91 | pwmPeriod = cycles / 256; 92 | } else 93 | if (cycles < TIMER1_RESOLUTION * 512UL) { 94 | clockSelectBits = _BV(CS13) | _BV(CS11); 95 | pwmPeriod = cycles / 512; 96 | } else 97 | if (cycles < TIMER1_RESOLUTION * 1024UL) { 98 | clockSelectBits = _BV(CS13) | _BV(CS11) | _BV(CS10); 99 | pwmPeriod = cycles / 1024; 100 | } else 101 | if (cycles < TIMER1_RESOLUTION * 2048UL) { 102 | clockSelectBits = _BV(CS13) | _BV(CS12); 103 | pwmPeriod = cycles / 2048; 104 | } else 105 | if (cycles < TIMER1_RESOLUTION * 4096UL) { 106 | clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS10); 107 | pwmPeriod = cycles / 4096; 108 | } else 109 | if (cycles < TIMER1_RESOLUTION * 8192UL) { 110 | clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11); 111 | pwmPeriod = cycles / 8192; 112 | } else 113 | if (cycles < TIMER1_RESOLUTION * 16384UL) { 114 | clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10); 115 | pwmPeriod = cycles / 16384; 116 | } else { 117 | clockSelectBits = _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10); 118 | pwmPeriod = TIMER1_RESOLUTION - 1; 119 | } 120 | OCR1A = pwmPeriod; 121 | OCR1C = pwmPeriod; 122 | TCCR1 = _BV(CTC1) | clockSelectBits; 123 | } 124 | 125 | //**************************** 126 | // Run Control 127 | //**************************** 128 | void start() __attribute__((always_inline)) { 129 | TCCR1 = 0; 130 | TCNT1 = 0; 131 | resume(); 132 | } 133 | void stop() __attribute__((always_inline)) { 134 | TCCR1 = _BV(CTC1); 135 | } 136 | void restart() __attribute__((always_inline)) { 137 | start(); 138 | } 139 | void resume() __attribute__((always_inline)) { 140 | TCCR1 = _BV(CTC1) | clockSelectBits; 141 | } 142 | 143 | //**************************** 144 | // PWM outputs 145 | //**************************** 146 | //Not implemented yet for ATTiny85 147 | //TO DO 148 | 149 | //**************************** 150 | // Interrupt Function 151 | //**************************** 152 | void attachInterrupt(void (*isr)()) __attribute__((always_inline)) { 153 | isrCallback = isr; 154 | TIMSK |= _BV(OCIE1A); 155 | } 156 | void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { 157 | if(microseconds > 0) setPeriod(microseconds); 158 | attachInterrupt(isr); 159 | } 160 | void detachInterrupt() __attribute__((always_inline)) { 161 | //TIMSK = 0; // Timer 0 and Timer 1 both use TIMSK register so setting it to 0 will override settings for Timer1 as well 162 | TIMSK &= ~_BV(OCIE1A); 163 | } 164 | static void (*isrCallback)(); 165 | static void isrDefaultUnused(); 166 | 167 | private: 168 | static unsigned short pwmPeriod; 169 | static unsigned char clockSelectBits; 170 | static const byte ratio = (F_CPU)/ ( 1000000 ); 171 | 172 | #elif defined(__AVR__) 173 | 174 | #if defined (__AVR_ATmega8__) 175 | //in some io definitions for older microcontrollers TIMSK is used instead of TIMSK1 176 | #define TIMSK1 TIMSK 177 | #endif 178 | 179 | public: 180 | //**************************** 181 | // Configuration 182 | //**************************** 183 | void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { 184 | TCCR1B = _BV(WGM13); // set mode as phase and frequency correct pwm, stop the timer 185 | TCCR1A = 0; // clear control register A 186 | setPeriod(microseconds); 187 | } 188 | void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { 189 | const unsigned long cycles = ((F_CPU/100000 * microseconds) / 20); 190 | if (cycles < TIMER1_RESOLUTION) { 191 | clockSelectBits = _BV(CS10); 192 | pwmPeriod = cycles; 193 | } else 194 | if (cycles < TIMER1_RESOLUTION * 8) { 195 | clockSelectBits = _BV(CS11); 196 | pwmPeriod = cycles / 8; 197 | } else 198 | if (cycles < TIMER1_RESOLUTION * 64) { 199 | clockSelectBits = _BV(CS11) | _BV(CS10); 200 | pwmPeriod = cycles / 64; 201 | } else 202 | if (cycles < TIMER1_RESOLUTION * 256) { 203 | clockSelectBits = _BV(CS12); 204 | pwmPeriod = cycles / 256; 205 | } else 206 | if (cycles < TIMER1_RESOLUTION * 1024) { 207 | clockSelectBits = _BV(CS12) | _BV(CS10); 208 | pwmPeriod = cycles / 1024; 209 | } else { 210 | clockSelectBits = _BV(CS12) | _BV(CS10); 211 | pwmPeriod = TIMER1_RESOLUTION - 1; 212 | } 213 | ICR1 = pwmPeriod; 214 | TCCR1B = _BV(WGM13) | clockSelectBits; 215 | } 216 | 217 | //**************************** 218 | // Run Control 219 | //**************************** 220 | void start() __attribute__((always_inline)) { 221 | TCCR1B = 0; 222 | TCNT1 = 0; // TODO: does this cause an undesired interrupt? 223 | resume(); 224 | } 225 | void stop() __attribute__((always_inline)) { 226 | TCCR1B = _BV(WGM13); 227 | } 228 | void restart() __attribute__((always_inline)) { 229 | start(); 230 | } 231 | void resume() __attribute__((always_inline)) { 232 | TCCR1B = _BV(WGM13) | clockSelectBits; 233 | } 234 | 235 | //**************************** 236 | // PWM outputs 237 | //**************************** 238 | void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) { 239 | unsigned long dutyCycle = pwmPeriod; 240 | dutyCycle *= duty; 241 | dutyCycle >>= 10; 242 | if (pin == TIMER1_A_PIN) OCR1A = dutyCycle; 243 | #ifdef TIMER1_B_PIN 244 | else if (pin == TIMER1_B_PIN) OCR1B = dutyCycle; 245 | #endif 246 | #ifdef TIMER1_C_PIN 247 | else if (pin == TIMER1_C_PIN) OCR1C = dutyCycle; 248 | #endif 249 | } 250 | void pwm(char pin, unsigned int duty) __attribute__((always_inline)) { 251 | if (pin == TIMER1_A_PIN) { pinMode(TIMER1_A_PIN, OUTPUT); TCCR1A |= _BV(COM1A1); } 252 | #ifdef TIMER1_B_PIN 253 | else if (pin == TIMER1_B_PIN) { pinMode(TIMER1_B_PIN, OUTPUT); TCCR1A |= _BV(COM1B1); } 254 | #endif 255 | #ifdef TIMER1_C_PIN 256 | else if (pin == TIMER1_C_PIN) { pinMode(TIMER1_C_PIN, OUTPUT); TCCR1A |= _BV(COM1C1); } 257 | #endif 258 | setPwmDuty(pin, duty); 259 | TCCR1B = _BV(WGM13) | clockSelectBits; 260 | } 261 | void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) { 262 | if (microseconds > 0) setPeriod(microseconds); 263 | pwm(pin, duty); 264 | } 265 | void disablePwm(char pin) __attribute__((always_inline)) { 266 | if (pin == TIMER1_A_PIN) TCCR1A &= ~_BV(COM1A1); 267 | #ifdef TIMER1_B_PIN 268 | else if (pin == TIMER1_B_PIN) TCCR1A &= ~_BV(COM1B1); 269 | #endif 270 | #ifdef TIMER1_C_PIN 271 | else if (pin == TIMER1_C_PIN) TCCR1A &= ~_BV(COM1C1); 272 | #endif 273 | } 274 | 275 | //**************************** 276 | // Interrupt Function 277 | //**************************** 278 | 279 | void attachInterrupt(void (*isr)()) __attribute__((always_inline)) { 280 | isrCallback = isr; 281 | TIMSK1 = _BV(TOIE1); 282 | } 283 | void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { 284 | if(microseconds > 0) setPeriod(microseconds); 285 | attachInterrupt(isr); 286 | } 287 | void detachInterrupt() __attribute__((always_inline)) { 288 | TIMSK1 = 0; 289 | } 290 | static void (*isrCallback)(); 291 | static void isrDefaultUnused(); 292 | 293 | private: 294 | // properties 295 | static unsigned short pwmPeriod; 296 | static unsigned char clockSelectBits; 297 | 298 | 299 | 300 | 301 | 302 | 303 | #elif defined(__arm__) && defined(TEENSYDUINO) && (defined(KINETISK) || defined(KINETISL)) 304 | 305 | #if defined(KINETISK) 306 | #define F_TIMER F_BUS 307 | #elif defined(KINETISL) 308 | #define F_TIMER (F_PLL/2) 309 | #endif 310 | 311 | // Use only 15 bit resolution. From K66 reference manual, 45.5.7 page 1200: 312 | // The CPWM pulse width (duty cycle) is determined by 2 x (CnV - CNTIN) and the 313 | // period is determined by 2 x (MOD - CNTIN). See the following figure. MOD must be 314 | // kept in the range of 0x0001 to 0x7FFF because values outside this range can produce 315 | // ambiguous results. 316 | #undef TIMER1_RESOLUTION 317 | #define TIMER1_RESOLUTION 32768 318 | 319 | public: 320 | //**************************** 321 | // Configuration 322 | //**************************** 323 | void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { 324 | setPeriod(microseconds); 325 | } 326 | void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { 327 | const unsigned long cycles = (F_TIMER / 2000000) * microseconds; 328 | // A much faster if-else 329 | // This is like a binary serch tree and no more than 3 conditions are evaluated. 330 | // I haven't checked if this becomes significantly longer ASM than the simple ladder. 331 | // It looks very similar to the ladder tho: same # of if's and else's 332 | 333 | /* 334 | // This code does not work properly in all cases :( 335 | // https://github.com/PaulStoffregen/TimerOne/issues/17 336 | if (cycles < TIMER1_RESOLUTION * 16) { 337 | if (cycles < TIMER1_RESOLUTION * 4) { 338 | if (cycles < TIMER1_RESOLUTION) { 339 | clockSelectBits = 0; 340 | pwmPeriod = cycles; 341 | }else{ 342 | clockSelectBits = 1; 343 | pwmPeriod = cycles >> 1; 344 | } 345 | }else{ 346 | if (cycles < TIMER1_RESOLUTION * 8) { 347 | clockSelectBits = 3; 348 | pwmPeriod = cycles >> 3; 349 | }else{ 350 | clockSelectBits = 4; 351 | pwmPeriod = cycles >> 4; 352 | } 353 | } 354 | }else{ 355 | if (cycles > TIMER1_RESOLUTION * 64) { 356 | if (cycles > TIMER1_RESOLUTION * 128) { 357 | clockSelectBits = 7; 358 | pwmPeriod = TIMER1_RESOLUTION - 1; 359 | }else{ 360 | clockSelectBits = 7; 361 | pwmPeriod = cycles >> 7; 362 | } 363 | } 364 | else{ 365 | if (cycles > TIMER1_RESOLUTION * 32) { 366 | clockSelectBits = 6; 367 | pwmPeriod = cycles >> 6; 368 | }else{ 369 | clockSelectBits = 5; 370 | pwmPeriod = cycles >> 5; 371 | } 372 | } 373 | } 374 | */ 375 | if (cycles < TIMER1_RESOLUTION) { 376 | clockSelectBits = 0; 377 | pwmPeriod = cycles; 378 | } else 379 | if (cycles < TIMER1_RESOLUTION * 2) { 380 | clockSelectBits = 1; 381 | pwmPeriod = cycles >> 1; 382 | } else 383 | if (cycles < TIMER1_RESOLUTION * 4) { 384 | clockSelectBits = 2; 385 | pwmPeriod = cycles >> 2; 386 | } else 387 | if (cycles < TIMER1_RESOLUTION * 8) { 388 | clockSelectBits = 3; 389 | pwmPeriod = cycles >> 3; 390 | } else 391 | if (cycles < TIMER1_RESOLUTION * 16) { 392 | clockSelectBits = 4; 393 | pwmPeriod = cycles >> 4; 394 | } else 395 | if (cycles < TIMER1_RESOLUTION * 32) { 396 | clockSelectBits = 5; 397 | pwmPeriod = cycles >> 5; 398 | } else 399 | if (cycles < TIMER1_RESOLUTION * 64) { 400 | clockSelectBits = 6; 401 | pwmPeriod = cycles >> 6; 402 | } else 403 | if (cycles < TIMER1_RESOLUTION * 128) { 404 | clockSelectBits = 7; 405 | pwmPeriod = cycles >> 7; 406 | } else { 407 | clockSelectBits = 7; 408 | pwmPeriod = TIMER1_RESOLUTION - 1; 409 | } 410 | 411 | uint32_t sc = FTM1_SC; 412 | FTM1_SC = 0; 413 | FTM1_MOD = pwmPeriod; 414 | FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | clockSelectBits | (sc & FTM_SC_TOIE); 415 | } 416 | 417 | //**************************** 418 | // Run Control 419 | //**************************** 420 | void start() __attribute__((always_inline)) { 421 | stop(); 422 | FTM1_CNT = 0; 423 | resume(); 424 | } 425 | void stop() __attribute__((always_inline)) { 426 | FTM1_SC = FTM1_SC & (FTM_SC_TOIE | FTM_SC_CPWMS | FTM_SC_PS(7)); 427 | } 428 | void restart() __attribute__((always_inline)) { 429 | start(); 430 | } 431 | void resume() __attribute__((always_inline)) { 432 | FTM1_SC = (FTM1_SC & (FTM_SC_TOIE | FTM_SC_PS(7))) | FTM_SC_CPWMS | FTM_SC_CLKS(1); 433 | } 434 | 435 | //**************************** 436 | // PWM outputs 437 | //**************************** 438 | void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) { 439 | unsigned long dutyCycle = pwmPeriod; 440 | dutyCycle *= duty; 441 | dutyCycle >>= 10; 442 | if (pin == TIMER1_A_PIN) { 443 | FTM1_C0V = dutyCycle; 444 | } else if (pin == TIMER1_B_PIN) { 445 | FTM1_C1V = dutyCycle; 446 | } 447 | } 448 | void pwm(char pin, unsigned int duty) __attribute__((always_inline)) { 449 | setPwmDuty(pin, duty); 450 | if (pin == TIMER1_A_PIN) { 451 | *portConfigRegister(TIMER1_A_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE; 452 | } else if (pin == TIMER1_B_PIN) { 453 | *portConfigRegister(TIMER1_B_PIN) = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE; 454 | } 455 | } 456 | void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) { 457 | if (microseconds > 0) setPeriod(microseconds); 458 | pwm(pin, duty); 459 | } 460 | void disablePwm(char pin) __attribute__((always_inline)) { 461 | if (pin == TIMER1_A_PIN) { 462 | *portConfigRegister(TIMER1_A_PIN) = 0; 463 | } else if (pin == TIMER1_B_PIN) { 464 | *portConfigRegister(TIMER1_B_PIN) = 0; 465 | } 466 | } 467 | 468 | //**************************** 469 | // Interrupt Function 470 | //**************************** 471 | void attachInterrupt(void (*isr)()) __attribute__((always_inline)) { 472 | isrCallback = isr; 473 | FTM1_SC |= FTM_SC_TOIE; 474 | NVIC_ENABLE_IRQ(IRQ_FTM1); 475 | } 476 | void attachInterrupt(void (*isr)(), unsigned long microseconds) __attribute__((always_inline)) { 477 | if(microseconds > 0) setPeriod(microseconds); 478 | attachInterrupt(isr); 479 | } 480 | void detachInterrupt() __attribute__((always_inline)) { 481 | FTM1_SC &= ~FTM_SC_TOIE; 482 | NVIC_DISABLE_IRQ(IRQ_FTM1); 483 | } 484 | static void (*isrCallback)(); 485 | static void isrDefaultUnused(); 486 | 487 | private: 488 | // properties 489 | static unsigned short pwmPeriod; 490 | static unsigned char clockSelectBits; 491 | 492 | #undef F_TIMER 493 | 494 | #elif defined(__arm__) && defined(TEENSYDUINO) && defined(__IMXRT1062__) 495 | 496 | public: 497 | //**************************** 498 | // Configuration 499 | //**************************** 500 | void initialize(unsigned long microseconds=1000000) __attribute__((always_inline)) { 501 | setPeriod(microseconds); 502 | } 503 | void setPeriod(unsigned long microseconds) __attribute__((always_inline)) { 504 | uint32_t period = (float)F_BUS_ACTUAL * (float)microseconds * 0.0000005f; 505 | uint32_t prescale = 0; 506 | while (period > 32767) { 507 | period = period >> 1; 508 | if (++prescale > 7) { 509 | prescale = 7; // when F_BUS is 150 MHz, longest 510 | period = 32767; // period is 55922 us (~17.9 Hz) 511 | break; 512 | } 513 | } 514 | //Serial.printf("setPeriod, period=%u, prescale=%u\n", period, prescale); 515 | FLEXPWM1_FCTRL0 |= FLEXPWM_FCTRL0_FLVL(8); // logic high = fault 516 | FLEXPWM1_FSTS0 = 0x0008; // clear fault status 517 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8); 518 | FLEXPWM1_SM3CTRL2 = FLEXPWM_SMCTRL2_INDEP; 519 | FLEXPWM1_SM3CTRL = FLEXPWM_SMCTRL_HALF | FLEXPWM_SMCTRL_PRSC(prescale); 520 | FLEXPWM1_SM3INIT = -period; 521 | FLEXPWM1_SM3VAL0 = 0; 522 | FLEXPWM1_SM3VAL1 = period; 523 | FLEXPWM1_SM3VAL2 = 0; 524 | FLEXPWM1_SM3VAL3 = 0; 525 | FLEXPWM1_SM3VAL4 = 0; 526 | FLEXPWM1_SM3VAL5 = 0; 527 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8) | FLEXPWM_MCTRL_RUN(8); 528 | pwmPeriod = period; 529 | } 530 | //**************************** 531 | // Run Control 532 | //**************************** 533 | void start() __attribute__((always_inline)) { 534 | stop(); 535 | // TODO: how to force counter back to zero? 536 | resume(); 537 | } 538 | void stop() __attribute__((always_inline)) { 539 | FLEXPWM1_MCTRL &= ~FLEXPWM_MCTRL_RUN(8); 540 | } 541 | void restart() __attribute__((always_inline)) { 542 | start(); 543 | } 544 | void resume() __attribute__((always_inline)) { 545 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_RUN(8); 546 | } 547 | 548 | //**************************** 549 | // PWM outputs 550 | //**************************** 551 | void setPwmDuty(char pin, unsigned int duty) __attribute__((always_inline)) { 552 | if (duty > 1023) duty = 1023; 553 | int dutyCycle = (pwmPeriod * duty) >> 10; 554 | //Serial.printf("setPwmDuty, period=%u\n", dutyCycle); 555 | if (pin == TIMER1_A_PIN) { 556 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8); 557 | FLEXPWM1_SM3VAL5 = dutyCycle; 558 | FLEXPWM1_SM3VAL4 = -dutyCycle; 559 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8); 560 | } else if (pin == TIMER1_B_PIN) { 561 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_CLDOK(8); 562 | FLEXPWM1_SM3VAL3 = dutyCycle; 563 | FLEXPWM1_SM3VAL2 = -dutyCycle; 564 | FLEXPWM1_MCTRL |= FLEXPWM_MCTRL_LDOK(8); 565 | } 566 | } 567 | void pwm(char pin, unsigned int duty) __attribute__((always_inline)) { 568 | setPwmDuty(pin, duty); 569 | if (pin == TIMER1_A_PIN) { 570 | FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMB_EN(8); 571 | IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 = 6; // pin 7 FLEXPWM1_PWM3_B 572 | } else if (pin == TIMER1_B_PIN) { 573 | FLEXPWM1_OUTEN |= FLEXPWM_OUTEN_PWMA_EN(8); 574 | IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 6; // pin 8 FLEXPWM1_PWM3_A 575 | } 576 | } 577 | void pwm(char pin, unsigned int duty, unsigned long microseconds) __attribute__((always_inline)) { 578 | if (microseconds > 0) setPeriod(microseconds); 579 | pwm(pin, duty); 580 | } 581 | void disablePwm(char pin) __attribute__((always_inline)) { 582 | if (pin == TIMER1_A_PIN) { 583 | IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01 = 5; // pin 7 FLEXPWM1_PWM3_B 584 | FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMB_EN(8); 585 | } else if (pin == TIMER1_B_PIN) { 586 | IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 = 5; // pin 8 FLEXPWM1_PWM3_A 587 | FLEXPWM1_OUTEN &= ~FLEXPWM_OUTEN_PWMA_EN(8); 588 | } 589 | } 590 | //**************************** 591 | // Interrupt Function 592 | //**************************** 593 | void attachInterrupt(void (*f)()) __attribute__((always_inline)) { 594 | isrCallback = f; 595 | attachInterruptVector(IRQ_FLEXPWM1_3, &isr); 596 | FLEXPWM1_SM3STS = FLEXPWM_SMSTS_RF; 597 | FLEXPWM1_SM3INTEN = FLEXPWM_SMINTEN_RIE; 598 | NVIC_ENABLE_IRQ(IRQ_FLEXPWM1_3); 599 | } 600 | void attachInterrupt(void (*f)(), unsigned long microseconds) __attribute__((always_inline)) { 601 | if(microseconds > 0) setPeriod(microseconds); 602 | attachInterrupt(f); 603 | } 604 | void detachInterrupt() __attribute__((always_inline)) { 605 | NVIC_DISABLE_IRQ(IRQ_FLEXPWM1_3); 606 | FLEXPWM1_SM3INTEN = 0; 607 | } 608 | static void isr(void); 609 | static void (*isrCallback)(); 610 | static void isrDefaultUnused(); 611 | 612 | private: 613 | // properties 614 | static unsigned short pwmPeriod; 615 | static unsigned char clockSelectBits; 616 | 617 | #endif 618 | }; 619 | 620 | extern TimerOne Timer1; 621 | 622 | #endif 623 | 624 | -------------------------------------------------------------------------------- /Tool/Font Builder.xlsm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fahroniganteng/Arduino_HUB08_Matrix_Led/96f30e959b95963d12888ad0a5e4b7016d4d48d7/Tool/Font Builder.xlsm -------------------------------------------------------------------------------- /Tool/wiring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fahroniganteng/Arduino_HUB08_Matrix_Led/96f30e959b95963d12888ad0a5e4b7016d4d48d7/Tool/wiring.png -------------------------------------------------------------------------------- /config/known_16bit_timers.h: -------------------------------------------------------------------------------- 1 | #ifndef known_16bit_timers_header_ 2 | #define known_16bit_timers_header_ 3 | 4 | // Wiring-S 5 | // 6 | #if defined(__AVR_ATmega644P__) && defined(WIRING) 7 | #define TIMER1_A_PIN 5 8 | #define TIMER1_B_PIN 4 9 | #define TIMER1_ICP_PIN 6 10 | 11 | // Teensy 2.0 12 | // 13 | #elif defined(__AVR_ATmega32U4__) && defined(CORE_TEENSY) 14 | #define TIMER1_A_PIN 14 15 | #define TIMER1_B_PIN 15 16 | #define TIMER1_C_PIN 4 17 | #define TIMER1_ICP_PIN 22 18 | #define TIMER1_CLK_PIN 11 19 | #define TIMER3_A_PIN 9 20 | #define TIMER3_ICP_PIN 10 21 | 22 | // Teensy++ 2.0 23 | #elif defined(__AVR_AT90USB1286__) && defined(CORE_TEENSY) 24 | #define TIMER1_A_PIN 25 25 | #define TIMER1_B_PIN 26 26 | #define TIMER1_C_PIN 27 27 | #define TIMER1_ICP_PIN 4 28 | #define TIMER1_CLK_PIN 6 29 | #define TIMER3_A_PIN 16 30 | #define TIMER3_B_PIN 15 31 | #define TIMER3_C_PIN 14 32 | #define TIMER3_ICP_PIN 17 33 | #define TIMER3_CLK_PIN 13 34 | 35 | // Teensy 3.0 36 | // 37 | #elif defined(__MK20DX128__) 38 | #define TIMER1_A_PIN 3 39 | #define TIMER1_B_PIN 4 40 | #define TIMER1_ICP_PIN 4 41 | 42 | // Teensy 3.1 / Teensy 3.2 43 | // 44 | #elif defined(__MK20DX256__) 45 | #define TIMER1_A_PIN 3 46 | #define TIMER1_B_PIN 4 47 | #define TIMER1_ICP_PIN 4 48 | #define TIMER3_A_PIN 32 49 | #define TIMER3_B_PIN 25 50 | #define TIMER3_ICP_PIN 32 51 | 52 | // Teensy 3.5 / Teensy 3.6 53 | // 54 | #elif defined(__MK64FX512__) || defined(__MK66FX1M0__) 55 | #define TIMER1_A_PIN 3 56 | #define TIMER1_B_PIN 4 57 | #define TIMER1_ICP_PIN 4 58 | #define TIMER3_A_PIN 29 59 | #define TIMER3_B_PIN 30 60 | #define TIMER3_ICP_PIN 29 61 | 62 | // Teensy-LC 63 | // 64 | #elif defined(__MKL26Z64__) 65 | #define TIMER1_A_PIN 16 66 | #define TIMER1_B_PIN 17 67 | #define TIMER1_ICP_PIN 17 68 | #define TIMER3_A_PIN 3 69 | #define TIMER3_B_PIN 4 70 | #define TIMER3_ICP_PIN 4 71 | 72 | // Teensy 4.0 73 | // 74 | #elif defined(__IMXRT1062__) 75 | #define TIMER1_A_PIN 7 76 | #define TIMER1_B_PIN 8 77 | #define TIMER3_A_PIN 9 78 | #define TIMER3_B_PIN 6 79 | 80 | // Arduino Mega 81 | // 82 | #elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) 83 | #define TIMER1_A_PIN 11 84 | #define TIMER1_B_PIN 12 85 | #define TIMER3_A_PIN 5 86 | #define TIMER3_B_PIN 2 87 | #define TIMER3_C_PIN 3 88 | #define TIMER4_A_PIN 6 89 | #define TIMER4_B_PIN 7 90 | #define TIMER4_C_PIN 8 91 | #define TIMER4_ICP_PIN 49 92 | #define TIMER5_A_PIN 46 93 | #define TIMER5_B_PIN 45 94 | #define TIMER5_C_PIN 44 95 | #define TIMER3_ICP_PIN 48 96 | #define TIMER3_CLK_PIN 47 97 | 98 | // Arduino Leonardo, Yun, etc 99 | // 100 | #elif defined(__AVR_ATmega32U4__) 101 | #define TIMER1_A_PIN 9 102 | #define TIMER1_B_PIN 10 103 | #define TIMER1_C_PIN 11 104 | #define TIMER1_ICP_PIN 4 105 | #define TIMER1_CLK_PIN 12 106 | #define TIMER3_A_PIN 5 107 | #define TIMER3_ICP_PIN 13 108 | 109 | // Uno, Duemilanove, LilyPad, etc 110 | // 111 | #elif defined (__AVR_ATmega168__) || defined (__AVR_ATmega328P__) || defined (__AVR_ATmega328__) || defined (__AVR_ATmega8__) 112 | #define TIMER1_A_PIN 9 113 | #define TIMER1_B_PIN 10 114 | #define TIMER1_ICP_PIN 8 115 | #define TIMER1_CLK_PIN 5 116 | 117 | // Minicore generic 118 | // 119 | #elif defined(__AVR_ATmega48PB__) || defined(__AVR_ATmega88PB__) || defined(__AVR_ATmega168PB__) 120 | #define TIMER1_A_PIN 9 121 | #define TIMER1_B_PIN 10 122 | #define TIMER1_ICP_PIN 8 123 | #define TIMER1_CLK_PIN 5 124 | #elif defined(__AVR_ATmega328PB__) 125 | #define TIMER1_A_PIN 9 126 | #define TIMER1_B_PIN 10 127 | #define TIMER1_ICP_PIN 8 128 | #define TIMER1_CLK_PIN 5 129 | #define TIMER3_A_PIN 0 130 | #define TIMER3_B_PIN 2 131 | #define TIMER3_ICP_PIN 25 132 | #define TIMER3_CLK_PIN 26 133 | #define TIMER4_A_PIN 1 134 | #define TIMER4_B_PIN 2 135 | #define TIMER4_ICP_PIN 23 136 | #define TIMER4_CLK_PIN 24 137 | 138 | // attiny167 139 | // 140 | #elif defined (__AVR_ATtiny167__) 141 | #define TIMER1_A_PIN 14 142 | #define TIMER1_B_PIN 11 143 | //#define TIMER1_ICP_PIN 8 144 | //#define TIMER1_CLK_PIN 5 145 | 146 | // Sanguino 147 | // 148 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644__) 149 | #define TIMER1_A_PIN 13 150 | #define TIMER1_B_PIN 12 151 | #define TIMER1_ICP_PIN 14 152 | #define TIMER1_CLK_PIN 1 153 | 154 | // Wildfire - Wicked Devices 155 | // 156 | #elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION >= 3 157 | #define TIMER1_A_PIN 5 // PD5 158 | #define TIMER1_B_PIN 8 // PD4 159 | #define TIMER1_ICP_PIN 6 // PD6 160 | #define TIMER1_CLK_PIN 23 // PB1 161 | #define TIMER3_A_PIN 12 // PB6 162 | #define TIMER3_B_PIN 13 // PB7 163 | #define TIMER3_ICP_PIN 9 // PB5 164 | #define TIMER3_CLK_PIN 0 // PD0 165 | #elif defined(__AVR_ATmega1284P__) && defined(WILDFIRE_VERSION) && WILDFIRE_VERSION < 3 166 | #define TIMER1_A_PIN 5 // PD5 167 | #define TIMER1_B_PIN 4 // PD4 168 | #define TIMER1_ICP_PIN 6 // PD6 169 | #define TIMER1_CLK_PIN 15 // PB1 170 | #define TIMER3_A_PIN 12 // PB6 171 | #define TIMER3_B_PIN 13 // PB7 172 | #define TIMER3_ICP_PIN 11 // PB5 173 | #define TIMER3_CLK_PIN 0 // PD0 174 | 175 | // Mighty-1284 - Maniacbug 176 | // 177 | #elif defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega1284__) 178 | #define TIMER1_A_PIN 12 // PD5 179 | #define TIMER1_B_PIN 13 // PD4 180 | #define TIMER1_ICP_PIN 14 // PD6 181 | #define TIMER1_CLK_PIN 1 // PB1 182 | #define TIMER3_A_PIN 6 // PB6 183 | #define TIMER3_B_PIN 7 // PB7 184 | #define TIMER3_ICP_PIN 5 // PB5 185 | #define TIMER3_CLK_PIN 8 // PD0 186 | 187 | #endif 188 | 189 | #endif 190 | -------------------------------------------------------------------------------- /ronnAnimation.h: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "ronnFont.h" 3 | 4 | class ronnAnimation{ 5 | //PRIVATE CLASS /////////////////////////////////////////////////////////////// 6 | private: 7 | typedef const uint8_t fontType_t; 8 | fontType_t *_fontData; 9 | bool big_font; 10 | int min_font; 11 | int max_font; 12 | int height_font; 13 | int x_pos = 0; 14 | int y_pos = 0; 15 | #define SCROLL 1 16 | #define CLEAR 0 17 | 18 | int getFontPosition(byte c){ 19 | int pos_font = 5; 20 | int charWidth; 21 | for (uint16_t i = min_font; i < c; i++){ 22 | charWidth = pgm_read_byte_near(_fontData + pos_font); 23 | pos_font += charWidth +1; 24 | } 25 | return pos_font; 26 | } 27 | 28 | 29 | 30 | /* 31 | * ******************************************************************************************************************* 32 | * PRINT TEXT 33 | * ******************************************************************************************************************* 34 | */ 35 | void writeByte(int x, int y, uint8_t data, int s){ 36 | //if (x >= WIDTH ||y >= HEIGHT || x+8<=0 || y < 0) return; //outside already check in buff.setPixel 37 | for (uint16_t row=0; row max_font || x_pos > WIDTH)return; //already check in buff.setPixel 47 | int pos_font = getFontPosition(chr); 48 | int pos_font_big = getFontPosition(chr + 128); 49 | int charWidth = pgm_read_byte_near(_fontData + pos_font); 50 | int charWidthBig = pgm_read_byte_near(_fontData + pos_font_big); 51 | pos_font++; 52 | pos_font_big++; 53 | //Serial.println(big_font); 54 | //write char dari kiri --> kolom 1 (atas ke bawah), kolom 2 (atas ke bawah) dst... 55 | for (uint16_t col = 0; col < charWidth; col++){ 56 | if(m==1)buff.fillRect(x_pos,y,2,height_font,1); 57 | if(m==2)buff.fillRect(x_pos-1,y,1,height_font,0); 58 | if(big_font){ 59 | writeByte(x_pos,y,pgm_read_byte_near(_fontData + pos_font_big + col),0); 60 | writeByte(x_pos++,y+8,pgm_read_byte_near(_fontData + pos_font + col),0); 61 | } 62 | else 63 | writeByte(x_pos++,y,pgm_read_byte_near(_fontData + pos_font + col),0); 64 | 65 | delay(s); 66 | } 67 | 68 | //print space betwen char 69 | if(m==2)buff.fillRect(x_pos-1,y,1,height_font,0); 70 | buff.lineDown(x_pos,y,height_font,0); 71 | x_pos++; 72 | } 73 | int getLastPositionText(char* string){// X position last text 74 | int x = 0; 75 | int pos_font; 76 | for(int i=0;i 0; col--){ 90 | if(m==1)buff.fillRect(x_pos-1,y,2,height_font,1); 91 | if(big_font){ 92 | writeByte(x_pos,y,pgm_read_byte_near(_fontData + pos_font_big + col-1),0); 93 | writeByte(x_pos--,y+8,pgm_read_byte_near(_fontData + pos_font + col-1),0); 94 | } 95 | else 96 | writeByte(x_pos--,y,pgm_read_byte_near(_fontData + pos_font + col-1),0); 97 | if(x_pos < WIDTH) delay(s); //outside already check in buff.setPixel, but delay still execute. 98 | if(m==2)buff.fillRect(x_pos+1,y,1,height_font,0); 99 | } 100 | buff.lineDown(x_pos,y,height_font,0); 101 | x_pos--; 102 | if(x_pos < WIDTH) delay(s); //outside already check in buff.setPixel, but delay still execute. 103 | } 104 | 105 | /* ******************************************************************************************************************* 106 | * VERTICAL SCROLL 107 | * ******************************************************************************************************************* 108 | */ 109 | void scrollCharVertical(byte c, int x, int y, int w, int row){ 110 | if( c < min_font || c > max_font || x_pos > WIDTH)return; 111 | int pos_font = getFontPosition(c); 112 | int pos_font_big = getFontPosition(c + 128); 113 | int charWidth = pgm_read_byte_near(_fontData + pos_font); 114 | int charWidthBig = pgm_read_byte_near(_fontData + pos_font_big); 115 | pos_font++; 116 | pos_font_big++; 117 | for (uint16_t col = 0; col < charWidth; col++){ 118 | if(x_pos+col-x=8?row-8:row))==1? 123 | buff.setPixel(x_pos+col,y,1): 124 | buff.setPixel(x_pos+col,y,0); 125 | } 126 | } 127 | x_pos += charWidth+1; 128 | } 129 | 130 | /* ******************************************************************************************************************* 131 | * HORISONTAL SCROLL 132 | * ******************************************************************************************************************* 133 | */ 134 | void scrollChar_LR(byte c, int x, int y, int w, int s){ //char,X,Y,width,speed 135 | if( c < min_font || c > max_font)return; 136 | int pos_font = getFontPosition(c); 137 | int pos_font_big = getFontPosition(c + 128); 138 | int charWidth = pgm_read_byte_near(_fontData + pos_font); 139 | int charWidthBig = pgm_read_byte_near(_fontData + pos_font_big); 140 | pos_font++; 141 | pos_font_big++; 142 | for (uint16_t col = 0; col < charWidth; col++){ 143 | if(big_font){ 144 | writeByte(x+w-1, y, pgm_read_byte_near(_fontData + pos_font_big + col), 0); 145 | writeByte(x+w-1, y + 8, pgm_read_byte_near(_fontData + pos_font + col), 0); 146 | } 147 | else 148 | writeByte(x+w-1, y, pgm_read_byte_near(_fontData + pos_font + col), 0); 149 | delay(s); 150 | buff.scrollLeft(x, y, w, height_font); 151 | } 152 | delay(s); 153 | buff.scrollLeft(x, y, w, height_font); 154 | } 155 | void scrollChar_LL(byte c, int x, int y, int w, int s){ //char,X,Y,width,speed 156 | if( c < min_font || c > max_font)return; 157 | int pos_font = getFontPosition(c); 158 | int pos_font_big = getFontPosition(c + 128); 159 | int charWidth = pgm_read_byte_near(_fontData + pos_font); 160 | int charWidthBig = pgm_read_byte_near(_fontData + pos_font_big); 161 | pos_font++; 162 | pos_font_big++; 163 | for (uint16_t col = 0; col < charWidth; col++){ 164 | if(x_pos < 1)return; 165 | if(big_font){ 166 | writeByte(x+w-1, y, pgm_read_byte_near(_fontData + pos_font_big + col), 0); 167 | writeByte(x+w-1, y + 8, pgm_read_byte_near(_fontData + pos_font + col), 0); 168 | } 169 | else 170 | writeByte(x+w-1, y, pgm_read_byte_near(_fontData + pos_font + col), 0); 171 | delay(s); 172 | buff.scrollLeft(x, y, w, height_font); 173 | x_pos--; 174 | } 175 | delay(s); 176 | buff.scrollLeft(x, y, w, height_font); 177 | x_pos--; 178 | } 179 | 180 | 181 | /* ******************************************************************************************************************* 182 | * MOVE 183 | * ******************************************************************************************************************* 184 | */ 185 | bool checkMove(char* str,int sp, int x, int y, int w, int h){ 186 | char k[5];//key (move to) 187 | char b[5];//buffer just for check format --> : 188 | int st = 0;//step 189 | sscanf(str, "%1s%1s%d", k, b, &st); 190 | //Serial.println(String(str) + " = " + String(k) + "-" + String(b) + " => " + String(st)); 191 | if(b[0]!=':' || st<1 || st==NULL || k[0]=='E') return false; 192 | else if(k[0]=='U') move_U(st,sp,x,y,w,h);//Move up 193 | else if(k[0]=='R') move_R(st,sp,x,y,w,h);//Move right 194 | else if(k[0]=='D') move_D(st,sp,x,y,w,h);//Move down 195 | else if(k[0]=='L') move_L(st,sp,x,y,w,h);//Move left 196 | else if(k[0]=='P') delay(st);//parking(delay) 197 | else if(k[0]=='E') return false; //End Move 198 | else return false; 199 | return true; 200 | } 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | //PUBLIC CLASS /////////////////////////////////////////////////////////////// 216 | public: 217 | ronnAnimation(){ 218 | setFont(); 219 | } 220 | 221 | bool setFont(fontType_t *f=font_DEFAULT){ //variable font name on ronnFont.h 222 | if (f != _fontData){ 223 | _fontData = (f == nullptr ? font_DEFAULT : f); 224 | } 225 | big_font = pgm_read_byte_near(_fontData + 0)=='T'?true:false; 226 | min_font = pgm_read_byte_near(_fontData + 2); 227 | max_font = pgm_read_byte_near(_fontData + 3); 228 | height_font = pgm_read_byte_near(_fontData + 4); 229 | return(true); 230 | } 231 | 232 | 233 | /* 234 | * ******************************************************************************************************************* 235 | * PRINT TEXT 236 | * ******************************************************************************************************************* 237 | * printText(String string, int x, int y) //string,X,Y 238 | * printText_R(String string, int x, int y, int s) //string,X,Y,speed --> print right with delay animation 239 | * printText_RC(String string, int x, int y, int s) //string,X,Y,speed --> print right with delay and cursor animation 240 | * printText_L(String string, int x, int y, int s) //string,X,Y,speed --> print left with delay animation (x = pixel in right position / end text) 241 | * printText_LC(String string, int x, int y, int s) //string,X,Y,speed --> print left with delay and cursor animation 242 | * scanText_L(String string, int x, int y, int s) //string,X,Y,speed --> scan left animation 243 | * scanText_R(String string, int x, int y, int s) //string,X,Y,speed --> scan right animation 244 | * 245 | * Font library from MD_MAX72xx / Parola (just font byte --> not use MD_MAX72xx library) 246 | * Default small font from HUB08SPI not use --> i like font design from MD_MAX72xx, so i use from there..... ^___^ 247 | * You can use "Font Builder.xlsm" create new font (modified from "Font Builder v2.xlsm" in MD_MAX72xx library) 248 | * Big font (16x16) use from HUB08SPI library, check on function printBigText(string,X) 249 | * ******************************************************************************************************************* 250 | */ 251 | void printText(String text, int x=0, int y=0){ //string,X,Y 252 | x_pos = x; 253 | char* string = text.c_str(); 254 | while (*string != '\0'){ 255 | byte c = *string; 256 | printChar(c,y,0,0); 257 | string++; 258 | } 259 | } 260 | void printText_R(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 261 | x_pos = x; 262 | char* string = text.c_str(); 263 | while (*string != '\0'){ 264 | byte c = *string; 265 | printChar(c,y,s,0); 266 | string++; 267 | } 268 | } 269 | void printText_RC(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 270 | x_pos = x; 271 | char* string = text.c_str(); 272 | while (*string != '\0'){ 273 | byte c = *string; 274 | printChar(c,y,s,1); 275 | string++; 276 | } 277 | } 278 | void printText_L(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 279 | char* string = text.c_str(); 280 | x_pos = x + getLastPositionText(string) - 1; 281 | for(int i=strlen(string)-1;i>=0;i--){ 282 | printCharLeft(string[i],y,s,0); 283 | } 284 | } 285 | void printText_LC(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 286 | char* string = text.c_str(); 287 | x_pos = x + getLastPositionText(string) - 1; 288 | for(int i=strlen(string)-1;i>=0;i--){ 289 | printCharLeft(string[i],y,s,1); 290 | } 291 | } 292 | 293 | void scanText_L(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 294 | char* string = text.c_str(); 295 | x_pos = x + getLastPositionText(string) - 1; 296 | for(int i=strlen(string)-1;i>=0;i--){ 297 | printCharLeft(string[i],y,s,2); 298 | } 299 | printText_RC(text, x, y, s/4); 300 | } 301 | void scanText_R(String text, int x=0, int y=0, int s=10){ //string,X,Y,speed 302 | x_pos = x; 303 | char* string = text.c_str(); 304 | while (*string != '\0'){ 305 | byte c = *string; 306 | printChar(c,y,s,2); 307 | string++; 308 | } 309 | printText_LC(text, x, y, s/4); 310 | } 311 | 312 | /* ******************************************************************************************************************* 313 | * VERTICAL SCROLL 314 | * ******************************************************************************************************************* 315 | * scrollText_U(String string, int x, int y, int w, int s=20) //String,X,Y,width,speed --> scroll text up 316 | * scrollText_D(String string, int x, int y, int w, int s=20) //String,X,Y,width,speed --> scroll text down 317 | * ******************************************************************************************************************* 318 | */ 319 | void scrollText_U(String string, int x=0, int y=0, int w=WIDTH, int s=20){ //String,X,Y,width,speed 320 | for (uint16_t row=0; row0; row--){ 335 | x_pos = x; 336 | buff.scrollDown(x,y,w,height_font); 337 | buff.lineAcross(x,y,w,0); 338 | //char* chr = string; 339 | char* chr = string.c_str(); 340 | while (*chr != '\0'){ 341 | byte c = *chr; 342 | scrollCharVertical(c,x,y,w,row-1); 343 | chr++; 344 | } 345 | delay(s); 346 | } 347 | } 348 | 349 | 350 | /* ******************************************************************************************************************* 351 | * HORISONTAL SCROLL 352 | * ******************************************************************************************************************* 353 | * NOTE : To left only, scroll to right cannot read text ^___^ 354 | * 355 | * Scroll to left until first character in X position (until left character) 356 | * scrollText_LL(String string, int x, int y, int w, int s) //String,X,Y,width,speed (height auto from font height) 357 | * 358 | * Scroll to left until last character (until right character) 359 | * You can use this function for continues scroll text --> put on loop 360 | * scrollText_LR(String string, int x, int y, int w, int s) //String,X,Y,width,speed (height auto from font height) 361 | * 362 | * ******************************************************************************************************************* 363 | */ 364 | void scrollText_LR(char* string, int x=0, int y=0, int w=WIDTH, int s=20){//String,X,Y,width,speed (height auto from font height) 365 | if(x<0) return; 366 | while (*string != '\0'){ 367 | byte c = *string; 368 | scrollChar_LR(c,x,y,w,s); 369 | string++; 370 | } 371 | for (int a=x+w-1;a>0;a--){ 372 | buff.scrollLeft(x, y, w, height_font); 373 | delay(s); 374 | } 375 | } 376 | void scrollText_LL(char* string, int x=0, int y=0, int w=WIDTH, int s=10){ //string,X,Y,width,speed 377 | if(x<0) return; 378 | x_pos=w-1; 379 | while (*string != '\0'){ 380 | byte c = *string; 381 | scrollChar_LL(c,x,y,w,s); 382 | string++; 383 | } 384 | 385 | if(x_pos > 1){ 386 | for (uint16_t i = 0 ; i < x_pos ; i++){ 387 | buff.scrollLeft(x, y, w, height_font); 388 | delay(s); 389 | } 390 | } 391 | } 392 | 393 | 394 | /* ******************************************************************************************************************* 395 | * BIG FONT PRINT 396 | * ******************************************************************************************************************* 397 | * printBigText(char* string, int x){ //string,X --> 16 pixel height, y always 0 398 | * 399 | * Font library from HUB08SPI 400 | * setFont not use in here 401 | * ******************************************************************************************************************* 402 | */ 403 | void printBigChar(byte c, int x, int y){ //char,X,Y 404 | byte l = pgm_read_byte_near(font_BIG + (c * 33))+1; //get pixel width of character 405 | for (int a=0;a<16;a++){ 406 | buff.writeByte(x,y+a,pgm_read_byte_near(font_BIG + (c * 33) +a*2 +1),1); 407 | buff.writeByte(x+8,y+a,pgm_read_byte_near(font_BIG + (c * 33) +a*2 +2),1); 408 | } 409 | } 410 | void printBigText(char* string, int x){ //string,X --> 16 pixel height, y always 0 411 | while (*string){ 412 | byte c = *string-32; 413 | printBigChar(c,x,0); 414 | x+=pgm_read_byte_near(font_BIG + (c * 33))+1; 415 | string++; 416 | } 417 | } 418 | 419 | 420 | 421 | /* ******************************************************************************************************************* 422 | * CLEAR ANIMATION 423 | * ******************************************************************************************************************* 424 | * Clear spesific location 425 | * clear_L(int x, int y, int w, int h, int m) //X,Y,width,height,mode(SCROLL,CLEAR) --> clear left 426 | * clear_R(int x, int y, int w, int h, int m) //X,Y,width,height,mode(SCROLL,CLEAR) --> clear right 427 | * clear_D(int x, int y, int w, int h, int m) //X,Y,width,height,mode(SCROLL,CLEAR) --> clear down 428 | * clear_U(int x, int y, int w, int h, int m) //X,Y,width,height,mode(SCROLL,CLEAR) --> clear up 429 | * 430 | * Clear all pixel on display 431 | * clear_L(int m) //mode(SCROLL,CLEAR) --> clear left 432 | * clear_R(int m) //mode(SCROLL,CLEAR) --> clear right 433 | * clear_D(int m) //mode(SCROLL,CLEAR) --> clear down 434 | * clear_U(int m) //mode(SCROLL,CLEAR) --> clear up 435 | * 436 | * Clear slice 437 | * clearSlice_L(int x, int y, int w, int h) //X,Y,width,height --> clear slice left 438 | * clearSlice_R(int x, int y, int w, int h) //X,Y,width,height --> clear slice right 439 | * clearSlice_L() // all pixel --> clear slice left 440 | * clearSlice_R() // all pixel --> clear slice right 441 | * 442 | * Other clear animation 443 | * clear_A1() // all pixel --> random pixel and scroll to center 444 | * clear_A2() // all pixel --> blink out 445 | * ******************************************************************************************************************* 446 | */ 447 | 448 | 449 | void clear_L(int x, int y, int w, int h, int m=SCROLL){//X,Y,width,height,mode(SCROLL,CLEAR) 450 | for (uint16_t col = x+w; col >x; col--){ 451 | m==SCROLL? 452 | buff.scrollLeft(x,y,w,h): 453 | buff.line(col-1,y,col-1,y+h-1,OFF); 454 | delay(5); 455 | }//=1+62-1// 456 | } 457 | uint8_t clear_L(int m=SCROLL){ //mode 458 | clear_L(0,0,WIDTH,HEIGHT,m); 459 | } 460 | void clear_R(int x, int y, int w, int h,int m=SCROLL){//X,Y,width,height,mode(SCROLL,CLEAR) 461 | for (uint16_t col = x; col < x+w; col++){ 462 | m==SCROLL? 463 | buff.scrollRight(x,y,w,h): 464 | buff.line(col,y,col,y+h-1,OFF); 465 | delay(5); 466 | } 467 | } 468 | uint8_t clear_R(int m=SCROLL){ //mode 469 | clear_R(0,0,WIDTH,HEIGHT,m); 470 | } 471 | void clear_D(int x, int y, int w, int h, int m=SCROLL){//X,Y,width,height,mode(SCROLL,CLEAR) 472 | for (uint16_t row = y; row < y+h; row++){ 473 | if(m==SCROLL){ 474 | buff.scrollDown(x,y,w,h); 475 | buff.lineAcross(x,y,w,0); 476 | } 477 | else 478 | buff.line(x,row,x+w-1,row,OFF); 479 | delay(20); 480 | } 481 | } 482 | uint8_t clear_D(int m=SCROLL){ //mode 483 | clear_D(0,0,WIDTH,HEIGHT,m); 484 | } 485 | void clear_U(int x, int y, int w, int h, int m=SCROLL){//X,Y,width,height 486 | for (uint16_t row = 0; row < h; row++){ 487 | if(m==SCROLL){ 488 | buff.scrollUp(x,y,w,h); 489 | buff.lineAcross(x,y+h-1,w,0); 490 | } 491 | else 492 | buff.line(x,y+h-row-1,x+w-1,y+h-row-1,OFF); 493 | delay(20); 494 | } 495 | } 496 | uint8_t clear_U(int m=SCROLL){ //mode 497 | clear_U(0,0,WIDTH,HEIGHT,m); 498 | } 499 | void clearSlice_L(int x, int y, int w, int h){//X,Y,width,height 500 | for (uint16_t col = x; col < x+w+1; col++){ 501 | bool bufPixel = 0; 502 | for (uint16_t i = 0; i < h; i++){//escape empty column pixel 503 | bufPixel|=buff.getPixel(col,y+i); 504 | } 505 | if(!bufPixel)continue; 506 | else if(col-x==0)buff.line(x,y,x,y+h-1,0);//first column 507 | else{ 508 | for (uint16_t i = x; i < col+1; i++){ 509 | buff.scrollLeft(x,y,col-x+1,y+h); 510 | //delay(col-x<10?15-(col-x):5); 511 | if(i-x+1>8)continue;//make fast animation... 512 | delay(5); 513 | } 514 | } 515 | buff.line(x,y,x,y+h-1,0); 516 | } 517 | } 518 | uint8_t clearSlice_L(){ 519 | clearSlice_L(0,0,WIDTH,HEIGHT); 520 | } 521 | void clearSlice_R(int x, int y, int w, int h){//X,Y,width,height 522 | for (uint16_t col = x+w; col > x; col--){ 523 | bool bufPixel = 0; 524 | for (uint16_t i = 0; i < h; i++){//escape empty column pixel 525 | bufPixel|=buff.getPixel(col-1,y+i); 526 | } 527 | if(!bufPixel)continue; 528 | else if(col==x+w)buff.line(col-1,y,col-1,y+h-1,0);//first column 529 | else{ 530 | for (uint16_t i = col-1; i < w+x; i++){ 531 | buff.scrollRight(col-1,y,x+w-col+1,y+h); 532 | if(i+1-col>8)continue; //make fast animation... 533 | delay(7); 534 | } 535 | } 536 | buff.line(x+w-1,y,x+w-1,y+h-1,0); 537 | } 538 | } 539 | uint8_t clearSlice_R(){ 540 | clearSlice_R(0,0,WIDTH,HEIGHT); 541 | } 542 | 543 | 544 | void clear_A1(){ 545 | for (uint16_t t = 0; t < 2000; t++){ 546 | uint16_t x = random(0,WIDTH); 547 | uint16_t y = random(0,HEIGHT); 548 | display.drawPoint(x,y,1); 549 | delay(1); 550 | } 551 | 552 | for (uint16_t x = 0; x < WIDTH/2; x++){ 553 | display.drawRect(x,0,1,HEIGHT,0); 554 | display.drawRect(WIDTH-1-x,0,1,HEIGHT,0); 555 | delay(10); 556 | } 557 | } 558 | void clear_A2(){ 559 | for (uint16_t t = 0; t < 4; t++){ 560 | buff.invert(); 561 | delay(100); 562 | } 563 | display.drawRect(0,0,WIDTH,HEIGHT,1); 564 | delay(100); 565 | buff.clear(); 566 | } 567 | 568 | 569 | 570 | 571 | 572 | /* *********************************************************************************************************************************** 573 | * MOVE ANIMATION 574 | * *********************************************************************************************************************************** 575 | * Move 576 | * move_U(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height --> move up 577 | * move_L(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height --> move left 578 | * move_R(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height --> move right 579 | * move_D(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height --> move down 580 | * 581 | * Move To 582 | * moveTo(char* moving[], int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){//array direction & step,speed,X,Y,width,height 583 | * example : 584 | * char* moving[] = {"D:6", "P:500", "L:20", "U:2","R:41"}; 585 | * ronn.moveTo(moving); 586 | * Result: 587 | * move down 6 pixel --> Parking 500ms --> move left 20 pixel --> move up 2 pixel --> move right 41 pixel 588 | * *********************************************************************************************************************************** 589 | */ 590 | 591 | void move_L(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height 592 | //x_pos = x; 593 | for (int i = 0; i < st; i++){ 594 | buff.scrollLeft(x-1-i,y,w+1,h);//Serial.println(String(x_pos) + ", " + String(y_pos)); 595 | x_pos--; 596 | delay(sp); 597 | } 598 | } 599 | void move_R(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height 600 | //x_pos = x; 601 | for (int i = 0; i < st; i++){ 602 | buff.scrollRight(x+i,y,w+1,h);//Serial.println(String(x_pos) + ", " + String(y_pos)); 603 | x_pos++; 604 | delay(sp); 605 | } 606 | } 607 | void move_D(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height 608 | //y_pos = y; 609 | //SOMTHING WRONG IN buff.scrollDown 610 | //Some location move_D error ^___^ 611 | for (int i = 0; i < st; i++){ 612 | buff.scrollDown(x,y+i,w,h+1); 613 | buff.line(x,y+i,x+w,y+i,0);//Serial.println(String(x_pos) + ", " + String(y_pos)); 614 | y_pos++; 615 | delay(sp); 616 | } 617 | } 618 | void move_U(int st=1, int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){ //step,speed,X,Y,width,height 619 | //y_pos = y; 620 | for (int i = 0; i < st; i++){ 621 | buff.scrollUp(x,y-i-1,w,h+1); 622 | buff.line(x,y+h-i-1,x+w,y+h-i-1,0);//Serial.println(String(x_pos) + ", " + String(y_pos)); 623 | y_pos--; 624 | delay(sp); 625 | } 626 | } 627 | 628 | 629 | void moveTo(char* moving[], int sp=35, int x=0, int y=0, int w=WIDTH, int h=HEIGHT){//array direction & step,speed,X,Y,width,height 630 | int i = 0; 631 | x_pos = x; 632 | y_pos = y; 633 | while(checkMove(moving[i],sp,x_pos,y_pos,w,h)) i++; 634 | } 635 | 636 | 637 | 638 | 639 | //END CLASS /////////////////////////////////////////////////////////////// 640 | }; 641 | 642 | 643 | //auto call class 644 | ronnAnimation ronn; 645 | -------------------------------------------------------------------------------- /ronnFont.h: -------------------------------------------------------------------------------- 1 | 2 | /* ******************************************************************************************************************* 3 | * FONT FROM LIBRARY MD_MAX72xx 4 | * ******************************************************************************************************************* 5 | FONT INFO in first 5 (0 to 4) array char font --> default from library MD_MAX72xx 6 | in this case, font info use : 7 | 0: double height (T:TRUE; F:FALSE) --> double height of font 10x16 8 | 1: not use 9 | 2: first char font 10 | 3: last char font 11 | 4: height font 12 | You can use "Font Builder.xlsm" create new font (check on "Tool" folder) 13 | ***this tool is modify from "Parola MD_MAX72xx Font Builder v2.xlsm" in MajicDesigns/MD_MAX72XX library : 14 | https://github.com/MajicDesigns/MD_MAX72XX/tree/main/Font%20Builder/Excel 15 | 16 | 17 | Exixting font: 18 | - font_DEFAULT --> default font (5x8) [DO NOT RENAME THIS FONT VARIABLE NAME] 19 | - B_7SEGMENT --> Big font 7 segment (10x16) [number only] 20 | - N_7SEGMENT --> Normal size 7 segment (5x8) [number only] 21 | - B_STD --> Big font standart (10x16) 22 | - S_STD --> Small font standart (3x5) 23 | * ******************************************************************************************************************* 24 | */ 25 | 26 | const uint8_t font_DEFAULT[] PROGMEM = { 27 | 'F', 0, 0, 255, 8, //-----------------------------------------> THIS IS FONT INFO 28 | 0, // 0 - 'Empty Cell' 29 | 5, 62, 91, 79, 91, 62, // 1 - 'Sad Smiley' 30 | 5, 62, 107, 79, 107, 62, // 2 - 'Happy Smiley' 31 | 5, 28, 62, 124, 62, 28, // 3 - 'Heart' 32 | 5, 24, 60, 126, 60, 24, // 4 - 'Diamond' 33 | 5, 28, 87, 125, 87, 28, // 5 - 'Clubs' 34 | 5, 28, 94, 127, 94, 28, // 6 - 'Spades' 35 | 4, 0, 24, 60, 24, // 7 - 'Bullet Point' 36 | 5, 255, 231, 195, 231, 255, // 8 - 'Rev Bullet Point' 37 | 4, 0, 24, 36, 24, // 9 - 'Hollow Bullet Point' 38 | 5, 255, 231, 219, 231, 255, // 10 - 'Rev Hollow BP' 39 | 5, 48, 72, 58, 6, 14, // 11 - 'Male' 40 | 5, 38, 41, 121, 41, 38, // 12 - 'Female' 41 | 5, 64, 127, 5, 5, 7, // 13 - 'Music Note 1' 42 | 5, 64, 127, 5, 37, 63, // 14 - 'Music Note 2' 43 | 5, 90, 60, 231, 60, 90, // 15 - 'Snowflake' 44 | 5, 127, 62, 28, 28, 8, // 16 - 'Right Pointer' 45 | 5, 8, 28, 28, 62, 127, // 17 - 'Left Pointer' 46 | 5, 20, 34, 127, 34, 20, // 18 - 'UpDown Arrows' 47 | 5, 255, 255, 255, 255, 255, // 19 - 'Full Block' 48 | 5, 240, 240, 240, 240, 240, // 20 - 'Half Block Bottom' 49 | 3, 255, 255, 255, // 21 - 'Half Block LHS' 50 | 5, 0, 0, 0, 255, 255, // 22 - 'Half Block RHS' 51 | 5, 15, 15, 15, 15, 15, // 23 - 'Half Block Top' 52 | 5, 8, 4, 126, 4, 8, // 24 - 'Up Arrow' 53 | 5, 16, 32, 126, 32, 16, // 25 - 'Down Arrow' 54 | 5, 8, 8, 42, 28, 8, // 26 - 'Right Arrow' 55 | 5, 8, 28, 42, 8, 8, // 27 - 'Left Arrow' 56 | 5, 170, 0, 85, 0, 170, // 28 - '30% shading' 57 | 5, 170, 85, 170, 85, 170, // 29 - '50% shading' 58 | 5, 48, 56, 62, 56, 48, // 30 - 'Up Pointer' 59 | 5, 6, 14, 62, 14, 6, // 31 - 'Down Pointer' 60 | 2, 0, 0, // 32 - 'Space' 61 | 1, 95, // 33 - '!' 62 | 3, 7, 0, 7, // 34 - '""' 63 | 5, 20, 127, 20, 127, 20, // 35 - '#' 64 | 5, 68, 74, 255, 74, 50, // 36 - '$' 65 | 5, 99, 19, 8, 100, 99, // 37 - '%' 66 | 5, 54, 73, 73, 54, 72, // 38 - '&' 67 | 1, 7, // 39 - ''' 68 | 3, 62, 65, 65, // 40 - '(' 69 | 3, 65, 65, 62, // 41 - ')' 70 | 5, 8, 42, 28, 42, 8, // 42 - '*' 71 | 5, 8, 8, 62, 8, 8, // 43 - '+' 72 | 2, 96, 224, // 44 - ',' 73 | 4, 8, 8, 8, 8, // 45 - '-' 74 | 2, 96, 96, // 46 - '.' 75 | 5, 96, 16, 8, 4, 3, // 47 - '/' 76 | 5, 62, 81, 73, 69, 62, // 48 - '0' 77 | 3, 66, 127, 64, // 49 - '1' 78 | 5, 113, 73, 73, 73, 70, // 50 - '2' 79 | 5, 65, 73, 73, 73, 54, // 51 - '3' 80 | 5, 15, 8, 8, 8, 127, // 52 - '4' 81 | 5, 79, 73, 73, 73, 49, // 53 - '5' 82 | 5, 62, 73, 73, 73, 48, // 54 - '6' 83 | 5, 3, 1, 1, 1, 127, // 55 - '7' 84 | 5, 54, 73, 73, 73, 54, // 56 - '8' 85 | 5, 6, 73, 73, 73, 62, // 57 - '9' 86 | 2, 108, 108, // 58 - ':' 87 | 2, 108, 236, // 59 - ';' 88 | 3, 8, 20, 34, // 60 - '<' 89 | 4, 20, 20, 20, 20, // 61 - '=' 90 | 3, 34, 20, 8, // 62 - '>' 91 | 5, 1, 89, 9, 9, 6, // 63 - '?' 92 | 5, 62, 65, 93, 89, 78, // 64 - '@' 93 | 5, 126, 9, 9, 9, 126, // 65 - 'A' 94 | 5, 127, 73, 73, 73, 54, // 66 - 'B' 95 | 5, 62, 65, 65, 65, 65, // 67 - 'C' 96 | 5, 127, 65, 65, 65, 62, // 68 - 'D' 97 | 5, 127, 73, 73, 73, 65, // 69 - 'E' 98 | 5, 127, 9, 9, 9, 1, // 70 - 'F' 99 | 5, 62, 65, 65, 73, 121, // 71 - 'G' 100 | 5, 127, 8, 8, 8, 127, // 72 - 'H' 101 | 3, 65, 127, 65, // 73 - 'I' 102 | 5, 48, 65, 65, 65, 63, // 74 - 'J' 103 | 5, 127, 8, 20, 34, 65, // 75 - 'K' 104 | 5, 127, 64, 64, 64, 64, // 76 - 'L' 105 | 5, 127, 2, 12, 2, 127, // 77 - 'M' 106 | 5, 127, 4, 8, 16, 127, // 78 - 'N' 107 | 5, 62, 65, 65, 65, 62, // 79 - 'O' 108 | 5, 127, 9, 9, 9, 6, // 80 - 'P' 109 | 5, 62, 65, 65, 97, 126, // 81 - 'Q' 110 | 5, 127, 9, 25, 41, 70, // 82 - 'R' 111 | 5, 70, 73, 73, 73, 49, // 83 - 'S' 112 | 5, 1, 1, 127, 1, 1, // 84 - 'T' 113 | 5, 63, 64, 64, 64, 63, // 85 - 'U' 114 | 5, 31, 32, 64, 32, 31, // 86 - 'V' 115 | 5, 63, 64, 56, 64, 63, // 87 - 'W' 116 | 5, 99, 20, 8, 20, 99, // 88 - 'X' 117 | 5, 3, 4, 120, 4, 3, // 89 - 'Y' 118 | 5, 97, 81, 73, 69, 67, // 90 - 'Z' 119 | 3, 127, 65, 65, // 91 - '[' 120 | 5, 3, 4, 8, 16, 96, // 92 - '\' 121 | 3, 65, 65, 127, // 93 - ']' 122 | 5, 4, 2, 1, 2, 4, // 94 - '^' 123 | 4, 128, 128, 128, 128, // 95 - '_' 124 | 3, 1, 2, 4, // 96 - '`' 125 | 4, 56, 68, 68, 124, // 97 - 'a' 126 | 4, 127, 68, 68, 56, // 98 - 'b' 127 | 4, 56, 68, 68, 68, // 99 - 'c' 128 | 4, 56, 68, 68, 127, // 100 - 'd' 129 | 4, 56, 84, 84, 88, // 101 - 'e' 130 | 4, 4, 126, 5, 1, // 102 - 'f' 131 | 4, 24, 164, 164, 124, // 103 - 'g' 132 | 4, 127, 4, 4, 120, // 104 - 'h' 133 | 1, 125, // 105 - 'i' 134 | 3, 132, 133, 124, // 106 - 'j' 135 | 4, 127, 16, 40, 68, // 107 - 'k' 136 | 1, 127, // 108 - 'l' 137 | 5, 124, 4, 120, 4, 120, // 109 - 'm' 138 | 4, 124, 4, 4, 120, // 110 - 'n' 139 | 4, 56, 68, 68, 56, // 111 - 'o' 140 | 4, 252, 36, 36, 24, // 112 - 'p' 141 | 4, 24, 36, 36, 252, // 113 - 'q' 142 | 4, 124, 4, 4, 8, // 114 - 'r' 143 | 4, 88, 84, 84, 52, // 115 - 's' 144 | 3, 4, 127, 4, // 116 - 't' 145 | 4, 60, 64, 64, 124, // 117 - 'u' 146 | 4, 28, 32, 64, 124, // 118 - 'v' 147 | 5, 60, 64, 48, 64, 60, // 119 - 'w' 148 | 4, 108, 16, 16, 108, // 120 - 'x' 149 | 4, 28, 160, 160, 124, // 121 - 'y' 150 | 4, 100, 84, 84, 76, // 122 - 'z' 151 | 4, 8, 54, 65, 65, // 123 - '{' 152 | 1, 127, // 124 - '|' 153 | 4, 65, 65, 54, 8, // 125 - '}' 154 | 4, 2, 1, 2, 1, // 126 - '~' 155 | 5, 127, 65, 65, 65, 127, // 127 - 'Hollow Block' 156 | 5, 62, 85, 85, 85, 65, // 128 - 'Euro symbol' 157 | 5, 56, 68, 68, 56, 68, // 129 - 'Alpha' 158 | 5, 124, 42, 42, 62, 20, // 130 - 'Beta' 159 | 5, 126, 2, 2, 6, 6, // 131 - 'Gamma' 160 | 5, 2, 126, 2, 126, 2, // 132 - 'Pi' 161 | 5, 99, 85, 73, 65, 99, // 133 - 'Sigma' 162 | 5, 56, 68, 68, 60, 4, // 134 - 'Theta' 163 | 5, 64, 126, 32, 30, 32, // 135 - 'mu' 164 | 5, 6, 2, 126, 2, 2, // 136 - 'Tau' 165 | 8, 99, 19, 8, 100, 99, 0, 96, 96, // 137 - 'Percent 00' 166 | 5, 42, 42, 42, 42, 42, // 138 - '3 Bar Equals' 167 | 3, 81, 74, 68, // 139 - '>=' 168 | 3, 68, 74, 81, // 140 - '<=' 169 | 5, 0, 0, 255, 1, 3, // 141 - 'Top of Integral' 170 | 3, 224, 128, 255, // 142 - 'Bot of Integral' 171 | 5, 54, 18, 54, 36, 54, // 143 - 'Wavy =' 172 | 3, 2, 5, 2, // 144 - 'Degree' 173 | 2, 24, 24, // 145 - 'Math Product' 174 | 2, 16, 16, // 146 - 'Short Dash' 175 | 5, 48, 64, 255, 1, 1, // 147 - 'Square Root' 176 | 4, 31, 1, 1, 30, // 148 - 'Superscript n' 177 | 0, // 149 178 | 0, // 150 179 | 0, // 151 180 | 0, // 152 181 | 9, 1, 1, 127, 1, 127, 2, 12, 2, 127, // 153 - 'Trademark' 182 | 0, // 154 183 | 0, // 155 184 | 0, // 156 185 | 0, // 157 186 | 0, // 158 187 | 0, // 159 188 | 1, 0, // 160 - ' Non-breaking space' 189 | 1, 125, // 161 - '¡ Inverted Exclamation Mark' 190 | 4, 24, 36, 126, 36, // 162 - '¢ Cent sign' 191 | 4, 68, 126, 69, 65, // 163 - '£ Pound sign' 192 | 5, 34, 28, 20, 28, 34, // 164 - '¤ Currency sign' 193 | 5, 1, 42, 124, 42, 1, // 165 - '¥ Yen sign' 194 | 1, 119, // 166 - '¦ Broken bar' 195 | 4, 78, 85, 85, 57, // 167 - '§ Section sign' 196 | 3, 2, 0, 2, // 168 - '¨ Diaeresis (Umlaut)' 197 | 7, 126, 129, 189, 165, 165, 129, 126, // 169 - '© Copyright sign' 198 | 3, 38, 41, 47, // 170 - 'ª Feminine Ordinal Indicator' 199 | 5, 8, 20, 42, 20, 34, // 171 - '« Left-pointing double angle quotation mark' 200 | 4, 8, 8, 8, 24, // 172 - '¬ Not sign' 201 | 3, 8, 8, 8, // 173 - ' Soft hyphen' 202 | 7, 126, 129, 189, 149, 169, 129, 126, // 174 - '® Registered sign' 203 | 5, 1, 1, 1, 1, 1, // 175 - '¯ macron' 204 | 3, 2, 5, 2, // 176 - '° Degree symbol' 205 | 3, 36, 46, 36, // 177 - '± Plus-minus sign' 206 | 3, 25, 21, 18, // 178 - '² Superscript two' 207 | 3, 21, 21, 10, // 179 - '³ Superscript three' 208 | 2, 2, 1, // 180 - '´ Acute accent' 209 | 4, 248, 32, 64, 120, // 181 - 'µ Micro sign' 210 | 5, 6, 9, 127, 1, 127, // 182 - 'Pilcrow sign' 211 | 2, 24, 24, // 183 - '· Middle dot' 212 | 4, 0, 128, 160, 192, // 184 - '¸ Cedilla' 213 | 3, 18, 31, 16, // 185 - '¹ Superscript one' 214 | 3, 38, 41, 38, // 186 - 'º Masculine ordinal indicator' 215 | 5, 34, 20, 42, 20, 8, // 187 - '» Right-pointing double angle quotation mark' 216 | 8, 64, 47, 16, 8, 4, 30, 17, 124, // 188 - '¼ Vulgar fraction one quarter' 217 | 8, 64, 47, 16, 8, 4, 98, 85, 76, // 189 - '½ Vulgar fraction one half' 218 | 9, 21, 85, 63, 16, 8, 4, 30, 17, 124, // 190 - '¾ Vulgar fraction three quarters' 219 | 5, 48, 72, 72, 77, 64, // 191 - '¿ Inverted Question Mark' 220 | 5, 120, 21, 22, 20, 120, // 192 - 'À Latin Capital Letter A with grave' 221 | 5, 120, 20, 22, 21, 120, // 193 - 'Á Latin Capital letter A with acute' 222 | 5, 122, 21, 20, 21, 122, // 194 - 'Â Latin Capital letter A with circumflex' 223 | 5, 120, 22, 21, 22, 121, // 195 - 'Ã Latin Capital letter A with tilde' 224 | 5, 120, 21, 20, 21, 120, // 196 - 'Ä Latin Capital letter A with diaeresis' 225 | 5, 120, 20, 21, 20, 120, // 197 - 'Å Latin Capital letter A with ring above' 226 | 7, 126, 9, 9, 127, 73, 73, 65, // 198 - 'Æ Latin Capital letter Æ' 227 | 5, 158, 161, 97, 33, 33, // 199 - 'Ç Latin Capital letter C with cedilla' 228 | 5, 124, 84, 85, 70, 68, // 200 - 'È Latin Capital letter E with grave' 229 | 5, 124, 84, 86, 69, 68, // 201 - 'É Latin Capital letter E with acute' 230 | 5, 126, 85, 84, 69, 70, // 202 - 'Ê Latin Capital letter E with circumflex' 231 | 5, 124, 85, 84, 69, 68, // 203 - 'Ë Latin Capital letter E with diaeresis' 232 | 3, 69, 126, 68, // 204 - 'Ì Latin Capital letter I with grave' 233 | 3, 68, 126, 69, // 205 - 'Í Latin Capital letter I with acute' 234 | 3, 70, 125, 70, // 206 - 'Î Latin Capital letter I with circumflex' 235 | 3, 69, 124, 69, // 207 - 'Ï Latin Capital letter I with diaeresis' 236 | 5, 8, 127, 73, 65, 62, // 208 - 'Ð Latin Capital letter Eth' 237 | 5, 124, 10, 17, 34, 125, // 209 - 'Ñ Latin Capital letter N with tilde' 238 | 5, 56, 68, 69, 70, 56, // 210 - 'Ò Latin Capital letter O with grave' 239 | 5, 56, 68, 70, 69, 56, // 211 - 'Ó Latin Capital letter O with acute' 240 | 5, 58, 69, 68, 69, 58, // 212 - 'Ô Latin Capital letter O with circumflex' 241 | 5, 56, 70, 69, 70, 57, // 213 - 'Õ Latin Capital letter O with tilde' 242 | 5, 56, 69, 68, 69, 56, // 214 - 'Ö Latin Capital letter O with diaeresis' 243 | 5, 34, 20, 8, 20, 34, // 215 - '× Multiplication sign' 244 | 5, 124, 98, 90, 70, 62, // 216 - 'Ø Latin Capital letter O with stroke' 245 | 5, 60, 64, 65, 66, 60, // 217 - 'Ù Latin Capital letter U with grave' 246 | 5, 60, 64, 66, 65, 60, // 218 - 'Ú Latin Capital letter U with acute' 247 | 5, 60, 66, 65, 66, 60, // 219 - 'Û Latin Capital Letter U with circumflex' 248 | 5, 60, 65, 64, 65, 60, // 220 - 'Ü Latin Capital Letter U with diaeresis' 249 | 5, 2, 4, 122, 5, 2, // 221 - 'Ý Latin Capital Letter Y with acute' 250 | 4, 63, 18, 18, 12, // 222 - 'Þ Latin Capital Letter Thorn' 251 | 5, 126, 73, 73, 78, 48, // 223 - 'ß Latin Small Letter sharp S' 252 | 4, 56, 69, 70, 124, // 224 - 'à Latin Small Letter A with grave' 253 | 4, 56, 68, 70, 125, // 225 - 'á Latin Small Letter A with acute' 254 | 4, 56, 70, 69, 126, // 226 - 'â Latin Small Letter A with circumflex' 255 | 4, 58, 69, 70, 125, // 227 - 'ã Latin Small Letter A with tilde' 256 | 4, 56, 69, 68, 125, // 228 - 'ä Latin Small Letter A with diaeresis' 257 | 4, 48, 74, 77, 122, // 229 - 'å Latin Small Letter A with ring above' 258 | 7, 32, 84, 84, 56, 84, 84, 88, // 230 - 'æ Latin Small Letter Æ' 259 | 4, 156, 162, 98, 34, // 231 - 'ç Latin Small Letter C with cedilla' 260 | 4, 56, 85, 86, 88, // 232 - 'è Latin Small Letter E with grave' 261 | 4, 56, 84, 86, 89, // 233 - 'é Latin Small Letter E with acute' 262 | 4, 56, 86, 85, 90, // 234 - 'ê Latin Small Letter E with circumflex' 263 | 4, 56, 85, 84, 89, // 235 - 'ë Latin Small Letter E with diaeresis' 264 | 2, 1, 122, // 236 - 'ì Latin Small Letter I with grave' 265 | 2, 122, 1, // 237 - 'í Latin Small Letter I with acute' 266 | 3, 2, 121, 2, // 238 - 'î Latin Small Letter I with circumflex' 267 | 3, 2, 120, 2, // 239 - 'ï Latin Small Letter I with diaeresis' 268 | 4, 48, 75, 75, 60, // 240 - 'ð Latin Small Letter Eth' 269 | 4, 122, 9, 10, 113, // 241 - 'ñ Latin Small Letter N with tilde' 270 | 4, 48, 73, 74, 48, // 242 - 'ò Latin Small Letter O with grave' 271 | 4, 48, 72, 74, 49, // 243 - 'ó Latin Small Letter O with acute' 272 | 4, 48, 74, 73, 50, // 244 - 'ô Latin Small Letter O with circumflex' 273 | 4, 50, 73, 74, 49, // 245 - 'õ Latin Small Letter O with tilde' 274 | 4, 57, 68, 68, 57, // 246 - 'ö Latin Small Letter O with diaeresis' 275 | 5, 8, 8, 42, 8, 8, // 247 - '÷ Division sign' 276 | 4, 56, 84, 76, 56, // 248 - 'ø Latin Small Letter O with stroke' 277 | 4, 56, 65, 66, 120, // 249 - 'ù Latin Small Letter U with grave' 278 | 4, 56, 64, 66, 121, // 250 - 'ú Latin Small Letter U with acute' 279 | 4, 56, 66, 65, 122, // 251 - 'û Latin Small Letter U with circumflex' 280 | 4, 58, 64, 64, 122, // 252 - 'ü Latin Small Letter U with diaeresis' 281 | 4, 24, 160, 162, 121, // 253 - 'ý Latin Small Letter Y with acute' 282 | 4, 252, 40, 40, 16, // 254 - 'þ Latin Small Letter Thorn' 283 | 4, 26, 160, 160, 122, // 255 - 'ÿ Latin Small Letter Y with diaeresis' 284 | }; 285 | 286 | //Big 7 Segmen 287 | const uint8_t B_7SEGMENT[] PROGMEM = { 288 | 'T', 1, 0, 255, 16, 289 | 0, // 0 290 | 0, // 1 291 | 0, // 2 292 | 0, // 3 293 | 0, // 4 294 | 0, // 5 295 | 0, // 6 296 | 0, // 7 297 | 0, // 8 298 | 0, // 9 299 | 0, // 10 300 | 0, // 11 301 | 0, // 12 302 | 0, // 13 303 | 0, // 14 304 | 0, // 15 305 | 0, // 16 306 | 0, // 17 307 | 0, // 18 308 | 0, // 19 309 | 0, // 20 310 | 0, // 21 311 | 0, // 22 312 | 0, // 23 313 | 0, // 24 314 | 0, // 25 315 | 0, // 26 316 | 0, // 27 317 | 0, // 28 318 | 0, // 29 319 | 0, // 30 320 | 0, // 31 321 | 2, 0, 0, // 32 - 'Space' 322 | 0, // 33 - '!' 323 | 0, // 34 - '""' 324 | 0, // 35 - '#' 325 | 0, // 36 - '$' 326 | 0, // 37 - '%' 327 | 0, // 38 - '&' 328 | 0, // 39 - ''' 329 | 0, // 40 - '(' 330 | 0, // 41 - ')' 331 | 0, // 42 - '*' 332 | 0, // 43 - '+' 333 | 0, // 44 - ',' 334 | 0, // 45 - '-' 335 | 2, 48, 48, // 46 - '.' 336 | 0, // 47 - '/' 337 | 10, 62, 127, 192, 192, 192, 192, 192, 192, 127, 62, // 48 - '0' 338 | 10, 0, 0, 0, 0, 0, 0, 0, 0, 127, 62, // 49 - '1' 339 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 64, 0, // 50 - '2' 340 | 10, 0, 65, 193, 193, 193, 193, 193, 193, 127, 62, // 51 - '3' 341 | 10, 0, 0, 1, 1, 1, 1, 1, 1, 127, 62, // 52 - '4' 342 | 10, 0, 64, 193, 193, 193, 193, 193, 193, 127, 62, // 53 - '5' 343 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 54 - '6' 344 | 10, 0, 0, 0, 0, 0, 0, 0, 0, 127, 62, // 55 - '7' 345 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 56 - '8' 346 | 10, 0, 64, 193, 193, 193, 193, 193, 193, 127, 62, // 57 - '9' 347 | 2, 6, 6, // 58 - ':' 348 | 0, // 59 - ';' 349 | 0, // 60 - '<' 350 | 0, // 61 - '=' 351 | 0, // 62 - '>' 352 | 0, // 63 - '?' 353 | 0, // 64 - '@' 354 | 10, 62, 127, 1, 1, 1, 1, 1, 1, 127, 62, // 65 - 'A' 355 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 66 - 'B' 356 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 65, 0, // 67 - 'C' 357 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 68 - 'D' 358 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 65, 0, // 69 - 'E' 359 | 10, 62, 127, 1, 1, 1, 1, 1, 1, 1, 0, // 70 - 'F' 360 | 0, // 71 - 'G' 361 | 0, // 72 - 'H' 362 | 0, // 73 - 'I' 363 | 0, // 74 - 'J' 364 | 0, // 75 - 'K' 365 | 0, // 76 - 'L' 366 | 0, // 77 - 'M' 367 | 0, // 78 - 'N' 368 | 0, // 79 - 'O' 369 | 0, // 80 - 'P' 370 | 0, // 81 - 'Q' 371 | 0, // 82 - 'R' 372 | 0, // 83 - 'S' 373 | 0, // 84 - 'T' 374 | 0, // 85 - 'U' 375 | 0, // 86 - 'V' 376 | 0, // 87 - 'W' 377 | 0, // 88 - 'X' 378 | 0, // 89 - 'Y' 379 | 0, // 90 - 'Z' 380 | 0, // 91 - '[' 381 | 0, // 92 - '\' 382 | 0, // 93 - ']' 383 | 0, // 94 - '^' 384 | 0, // 95 - '_' 385 | 0, // 96 - '`' 386 | 10, 62, 127, 1, 1, 1, 1, 1, 1, 127, 62, // 97 - 'a' 387 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 98 - 'b' 388 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 65, 0, // 99 - 'c' 389 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 127, 62, // 100 - 'd' 390 | 10, 62, 127, 193, 193, 193, 193, 193, 193, 65, 0, // 101 - 'e' 391 | 10, 62, 127, 1, 1, 1, 1, 1, 1, 1, 0, // 102 - 'f' 392 | 0, // 103 - 'g' 393 | 0, // 104 - 'h' 394 | 0, // 105 - 'i' 395 | 0, // 106 - 'j' 396 | 0, // 107 - 'k' 397 | 0, // 108 - 'l' 398 | 0, // 109 - 'm' 399 | 0, // 110 - 'n' 400 | 0, // 111 - 'o' 401 | 0, // 112 - 'p' 402 | 0, // 113 - 'q' 403 | 0, // 114 - 'r' 404 | 0, // 115 - 's' 405 | 0, // 116 - 't' 406 | 0, // 117 - 'u' 407 | 0, // 118 - 'v' 408 | 0, // 119 - 'w' 409 | 0, // 120 - 'x' 410 | 0, // 121 - 'y' 411 | 0, // 122 - 'z' 412 | 0, // 123 - '{' 413 | 2, 255, 255, // 124 - '|' 414 | 0, // 125 415 | 0, // 126 416 | 0, // 127 417 | 0, // 128 418 | 0, // 129 419 | 0, // 130 420 | 0, // 131 421 | 0, // 132 422 | 0, // 133 423 | 0, // 134 424 | 0, // 135 425 | 0, // 136 426 | 0, // 137 427 | 0, // 138 428 | 0, // 139 429 | 0, // 140 430 | 0, // 141 431 | 0, // 142 432 | 0, // 143 433 | 0, // 144 434 | 0, // 145 435 | 0, // 146 436 | 0, // 147 437 | 0, // 148 438 | 0, // 149 439 | 0, // 150 440 | 0, // 151 441 | 0, // 152 442 | 0, // 153 443 | 0, // 154 444 | 0, // 155 445 | 0, // 156 446 | 0, // 157 447 | 0, // 158 448 | 0, // 159 449 | 2, 0, 0, // 160 450 | 0, // 161 451 | 0, // 162 452 | 0, // 163 453 | 0, // 164 454 | 0, // 165 455 | 0, // 166 456 | 0, // 167 457 | 0, // 168 458 | 0, // 169 459 | 0, // 170 460 | 0, // 171 461 | 0, // 172 462 | 0, // 173 463 | 2, 0, 0, // 174 464 | 0, // 175 465 | 10, 124, 254, 3, 3, 3, 3, 3, 3, 254, 124, // 176 466 | 10, 0, 0, 0, 0, 0, 0, 0, 0, 254, 124, // 177 467 | 10, 0, 2, 131, 131, 131, 131, 131, 131, 254, 124, // 178 468 | 10, 0, 130, 131, 131, 131, 131, 131, 131, 254, 124, // 179 469 | 10, 124, 254, 128, 128, 128, 128, 128, 128, 254, 124, // 180 470 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 2, 0, // 181 471 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 2, 0, // 182 472 | 10, 0, 2, 3, 3, 3, 3, 3, 3, 254, 124, // 183 473 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 254, 124, // 184 474 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 254, 124, // 185 475 | 2, 96, 96, // 186 476 | 0, // 187 477 | 0, // 188 478 | 0, // 189 479 | 0, // 190 480 | 0, // 191 481 | 0, // 192 482 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 254, 124, // 193 483 | 10, 124, 254, 128, 128, 128, 128, 128, 128, 0, 0, // 194 484 | 10, 0, 0, 128, 128, 128, 128, 128, 128, 0, 0, // 195 485 | 10, 0, 0, 128, 128, 128, 128, 128, 128, 254, 124, // 196 486 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 130, 0, // 197 487 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 130, 0, // 198 488 | 0, // 199 489 | 0, // 200 490 | 0, // 201 491 | 0, // 202 492 | 0, // 203 493 | 0, // 204 494 | 0, // 205 495 | 0, // 206 496 | 0, // 207 497 | 0, // 208 498 | 0, // 209 499 | 0, // 210 500 | 0, // 211 501 | 0, // 212 502 | 0, // 213 503 | 0, // 214 504 | 0, // 215 505 | 0, // 216 506 | 0, // 217 507 | 0, // 218 508 | 0, // 219 509 | 0, // 220 510 | 0, // 221 511 | 0, // 222 512 | 0, // 223 513 | 0, // 224 514 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 254, 124, // 225 515 | 10, 124, 254, 128, 128, 128, 128, 128, 128, 0, 0, // 226 516 | 10, 0, 0, 128, 128, 128, 128, 128, 128, 0, 0, // 227 517 | 10, 0, 0, 128, 128, 128, 128, 128, 128, 254, 124, // 228 518 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 130, 0, // 229 519 | 10, 124, 254, 131, 131, 131, 131, 131, 131, 130, 0, // 230 520 | 0, // 231 521 | 0, // 232 522 | 0, // 233 523 | 0, // 234 524 | 0, // 235 525 | 0, // 236 526 | 0, // 237 527 | 0, // 238 528 | 0, // 239 529 | 0, // 240 530 | 0, // 241 531 | 0, // 242 532 | 0, // 243 533 | 0, // 244 534 | 0, // 245 535 | 0, // 246 536 | 0, // 247 537 | 0, // 248 538 | 0, // 249 539 | 0, // 250 540 | 0, // 251 541 | 2, 255, 255, // 252 542 | 0, // 253 543 | 0, // 254 544 | 0, // 255 545 | }; 546 | 547 | 548 | //Big Standart 549 | const uint8_t B_STD[] PROGMEM = { 550 | 'T', 1, 0, 255, 16, 551 | 0, // 0 552 | 0, // 1 553 | 0, // 2 554 | 0, // 3 555 | 0, // 4 556 | 0, // 5 557 | 0, // 6 558 | 0, // 7 559 | 0, // 8 560 | 0, // 9 561 | 0, // 10 562 | 0, // 11 563 | 0, // 12 564 | 0, // 13 565 | 0, // 14 566 | 0, // 15 567 | 0, // 16 568 | 0, // 17 569 | 0, // 18 570 | 0, // 19 571 | 0, // 20 572 | 0, // 21 573 | 0, // 22 574 | 0, // 23 575 | 0, // 24 576 | 0, // 25 577 | 0, // 26 578 | 0, // 27 579 | 0, // 28 580 | 0, // 29 581 | 0, // 30 582 | 0, // 31 583 | 4, 0, 0, 0, 0, // 32 - 'Space lower' 584 | 2, 51, 51, // 33 - '! lower' 585 | 6, 0, 0, 0, 0, 0, 0, // 34 - '"" lower' 586 | 10, 3, 3, 63, 63, 3, 3, 63, 63, 3, 3, // 35 - '# lower' 587 | 10, 24, 56, 48, 48, 127, 127, 48, 57, 31, 15, // 36 - '$ lower' 588 | 8, 48, 60, 15, 3, 24, 36, 36, 24, // 37 - '% lower' 589 | 10, 15, 31, 57, 48, 48, 59, 31, 14, 63, 51, // 38 - '& lower' 590 | 2, 0, 0, // 39 - ' lower' 591 | 5, 3, 15, 28, 56, 48, // 40 - '( lower' 592 | 5, 48, 56, 28, 15, 3, // 41 - ') lower' 593 | 10, 6, 7, 7, 1, 31, 31, 1, 3, 7, 6, // 42 - '* lower' 594 | 10, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, // 43 - '+ lower' 595 | 2, 176, 112, // 44 - ', lower' 596 | 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 45 - '- lower' 597 | 2, 48, 48, // 46 - '. lower' 598 | 8, 48, 60, 15, 3, 0, 0, 0, 0, // 47 - '/ lower' 599 | 10, 15, 31, 57, 48, 48, 48, 48, 56, 31, 15, // 48 - '0 lower' 600 | 5, 0, 48, 63, 63, 48, // 49 - '1 lower' 601 | 10, 63, 63, 49, 48, 48, 48, 48, 48, 48, 48, // 50 - '2 lower' 602 | 10, 12, 28, 56, 48, 48, 48, 48, 56, 31, 15, // 51 - '3 lower' 603 | 10, 3, 3, 3, 3, 3, 3, 3, 63, 63, 3, // 52 - '4 lower' 604 | 10, 12, 28, 56, 48, 48, 48, 48, 56, 31, 15, // 53 - '5 lower' 605 | 10, 15, 31, 56, 48, 48, 48, 48, 56, 31, 15, // 54 - '6 lower' 606 | 10, 0, 0, 0, 63, 63, 0, 0, 0, 0, 0, // 55 - '7 lower' 607 | 10, 15, 31, 57, 48, 48, 48, 48, 57, 31, 15, // 56 - '8 lower' 608 | 10, 0, 0, 0, 0, 0, 0, 0, 0, 63, 63, // 57 - '9 lower' 609 | 2, 24, 24, // 58 - ': lower' 610 | 2, 88, 56, // 59 - '; lower' 611 | 8, 0, 1, 3, 7, 14, 28, 56, 48, // 60 - '< lower' 612 | 9, 6, 6, 6, 6, 6, 6, 6, 6, 6, // 61 - '= lower' 613 | 8, 48, 56, 28, 14, 7, 3, 1, 0, // 62 - '> lower' 614 | 10, 0, 0, 0, 0, 55, 55, 1, 0, 0, 0, // 63 - '? lower' 615 | 10, 15, 31, 56, 51, 54, 54, 51, 54, 55, 19, // 64 - '@ lower' 616 | 10, 63, 63, 1, 1, 1, 1, 1, 1, 63, 63, // 65 - 'A lower' 617 | 10, 63, 63, 48, 48, 48, 48, 48, 57, 31, 15, // 66 - 'B lower' 618 | 10, 15, 31, 56, 48, 48, 48, 48, 56, 28, 12, // 67 - 'C lower' 619 | 10, 63, 63, 48, 48, 48, 48, 48, 56, 31, 15, // 68 - 'D lower' 620 | 9, 63, 63, 48, 48, 48, 48, 48, 48, 48, // 69 - 'E lower' 621 | 9, 63, 63, 0, 0, 0, 0, 0, 0, 0, // 70 - 'F lower' 622 | 10, 15, 31, 56, 48, 48, 48, 49, 57, 31, 15, // 71 - 'G lower' 623 | 10, 63, 63, 0, 0, 0, 0, 0, 0, 63, 63, // 72 - 'H lower' 624 | 4, 48, 63, 63, 48, // 73 - 'I lower' 625 | 8, 12, 28, 56, 48, 48, 56, 31, 15, // 74 - 'J lower' 626 | 9, 63, 63, 1, 3, 7, 14, 28, 56, 48, // 75 - 'K lower' 627 | 9, 63, 63, 48, 48, 48, 48, 48, 48, 48, // 76 - 'L lower' 628 | 10, 63, 63, 0, 0, 0, 0, 0, 0, 63, 63, // 77 - 'M lower' 629 | 10, 63, 63, 0, 0, 0, 0, 1, 3, 63, 63, // 78 - 'N lower' 630 | 10, 15, 31, 56, 48, 48, 48, 48, 56, 31, 15, // 79 - 'O lower' 631 | 10, 63, 63, 0, 0, 0, 0, 0, 0, 0, 0, // 80 - 'P lower' 632 | 10, 15, 31, 56, 48, 48, 54, 62, 28, 63, 55, // 81 - 'Q lower' 633 | 10, 63, 63, 0, 1, 3, 7, 14, 28, 56, 48, // 82 - 'R lower' 634 | 10, 24, 56, 48, 48, 48, 48, 48, 57, 31, 15, // 83 - 'S lower' 635 | 8, 0, 0, 0, 63, 63, 0, 0, 0, // 84 - 'T lower' 636 | 10, 15, 31, 56, 48, 48, 48, 48, 56, 31, 15, // 85 - 'U lower' 637 | 10, 3, 7, 14, 28, 56, 56, 28, 14, 7, 3, // 86 - 'V lower' 638 | 10, 15, 31, 56, 60, 31, 31, 60, 56, 31, 15, // 87 - 'W lower' 639 | 10, 60, 62, 7, 3, 1, 1, 3, 7, 62, 60, // 88 - 'X lower' 640 | 10, 0, 0, 0, 0, 63, 63, 0, 0, 0, 0, // 89 - 'Y lower' 641 | 10, 60, 62, 55, 51, 49, 48, 48, 48, 48, 48, // 90 - 'Z lower' 642 | 4, 63, 63, 48, 48, // 91 - '[ lower' 643 | 8, 0, 0, 0, 0, 3, 15, 60, 48, // 92 - '\ lower' 644 | 4, 48, 48, 63, 63, // 93 - '] lower' 645 | 8, 0, 0, 0, 0, 0, 0, 0, 0, // 94 - '^ lower' 646 | 10, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 95 - '_ lower' 647 | 3, 0, 0, 0, // 96 - '` lower' 648 | 10, 15, 31, 56, 48, 48, 48, 48, 48, 63, 63, // 97 - 'a lower' 649 | 10, 63, 63, 48, 48, 48, 48, 48, 56, 31, 15, // 98 - 'b lower' 650 | 9, 15, 31, 56, 48, 48, 48, 48, 48, 48, // 99 - 'c lower' 651 | 10, 15, 31, 56, 48, 48, 48, 48, 48, 63, 63, // 100 - 'd lower' 652 | 9, 15, 31, 59, 51, 51, 51, 51, 51, 51, // 101 - 'e lower' 653 | 7, 0, 63, 63, 0, 0, 0, 0, // 102 - 'f lower' 654 | 9, 195, 199, 206, 204, 204, 204, 236, 127, 63, // 103 - 'g lower' 655 | 9, 63, 63, 0, 0, 0, 0, 0, 63, 63, // 104 - 'h lower' 656 | 2, 63, 63, // 105 - 'i lower' 657 | 8, 96, 224, 192, 192, 192, 224, 127, 63, // 106 - 'j lower' 658 | 8, 63, 63, 3, 7, 15, 28, 56, 48, // 107 - 'k lower' 659 | 4, 0, 63, 63, 48, // 108 - 'l lower' 660 | 10, 63, 63, 0, 0, 63, 63, 0, 0, 63, 63, // 109 - 'm lower' 661 | 9, 63, 63, 0, 0, 0, 0, 0, 63, 63, // 110 - 'n lower' 662 | 9, 15, 31, 56, 48, 48, 48, 56, 31, 15, // 111 - 'o lower' 663 | 9, 255, 255, 12, 12, 12, 12, 14, 7, 3, // 112 - 'p lower' 664 | 9, 3, 7, 14, 12, 12, 12, 12, 255, 255, // 113 - 'q lower' 665 | 9, 63, 63, 0, 0, 0, 0, 0, 0, 0, // 114 - 'r lower' 666 | 9, 48, 49, 51, 51, 51, 51, 51, 30, 12, // 115 - 's lower' 667 | 6, 0, 31, 63, 48, 48, 16, // 116 - 't lower' 668 | 9, 15, 31, 56, 48, 48, 48, 48, 63, 63, // 117 - 'u lower' 669 | 9, 7, 15, 28, 56, 48, 56, 28, 15, 7, // 118 - 'v lower' 670 | 10, 15, 31, 56, 56, 31, 31, 56, 56, 31, 15, // 119 - 'w lower' 671 | 10, 48, 56, 28, 15, 7, 7, 15, 28, 56, 48, // 120 - 'x lower' 672 | 9, 193, 195, 199, 198, 198, 198, 230, 127, 63, // 121 - 'y lower' 673 | 10, 48, 56, 60, 62, 55, 51, 49, 48, 48, 48, // 122 - 'z lower' 674 | 6, 0, 1, 15, 31, 56, 48, // 123 - '{ lower' 675 | 2, 255, 255, // 124 - '| lower' 676 | 6, 48, 56, 31, 15, 1, 0, // 125 - '} lower' 677 | 0, // 126 678 | 0, // 127 679 | 0, // 128 680 | 0, // 129 681 | 0, // 130 682 | 0, // 131 683 | 0, // 132 684 | 0, // 133 685 | 0, // 134 686 | 0, // 135 687 | 0, // 136 688 | 0, // 137 689 | 0, // 138 690 | 0, // 139 691 | 0, // 140 692 | 0, // 141 693 | 0, // 142 694 | 0, // 143 695 | 0, // 144 696 | 0, // 145 697 | 0, // 146 698 | 0, // 147 699 | 0, // 148 700 | 0, // 149 701 | 0, // 150 702 | 0, // 151 703 | 0, // 152 704 | 0, // 153 705 | 0, // 154 706 | 0, // 155 707 | 0, // 156 708 | 0, // 157 709 | 0, // 158 710 | 0, // 159 711 | 4, 0, 0, 0, 0, // 160 - 'Space upper' 712 | 2, 255, 255, // 161 - '! upper' 713 | 6, 15, 15, 0, 0, 15, 15, // 162 - '"" upper' 714 | 10, 48, 48, 255, 255, 48, 48, 255, 255, 48, 48, // 163 - '# upper' 715 | 10, 56, 124, 238, 198, 255, 255, 198, 198, 142, 12, // 164 - '$ upper' 716 | 8, 6, 9, 9, 198, 240, 60, 15, 3, // 165 - '% upper' 717 | 10, 0, 128, 204, 254, 243, 243, 158, 12, 0, 0, // 166 - '& upper' 718 | 2, 15, 15, // 167 - '' upper' 719 | 5, 240, 252, 14, 7, 3, // 168 - '( upper' 720 | 5, 3, 7, 14, 252, 240, // 169 - ') upper' 721 | 10, 48, 112, 224, 192, 252, 252, 192, 224, 112, 48, // 170 - '* upper' 722 | 10, 192, 192, 192, 192, 252, 252, 192, 192, 192, 192, // 171 - '+ upper' 723 | 2, 0, 0, // 172 - ', upper' 724 | 9, 192, 192, 192, 192, 192, 192, 192, 192, 192, // 173 - '- upper' 725 | 2, 0, 0, // 174 - '. upper' 726 | 8, 0, 0, 0, 192, 240, 60, 15, 3, // 175 - '/ upper' 727 | 10, 252, 254, 135, 195, 99, 51, 27, 15, 254, 252, // 176 - '0 upper' 728 | 5, 4, 6, 255, 255, 0, // 177 - '1 upper' 729 | 10, 12, 142, 199, 195, 195, 195, 195, 231, 126, 60, // 178 - '2 upper' 730 | 10, 12, 14, 7, 3, 3, 195, 195, 199, 254, 60, // 179 - '3 upper' 731 | 10, 128, 192, 224, 112, 56, 28, 14, 255, 255, 0, // 180 - '4 upper' 732 | 10, 63, 63, 51, 51, 51, 51, 51, 115, 227, 195, // 181 - '5 upper' 733 | 10, 252, 254, 231, 99, 99, 99, 99, 231, 198, 132, // 182 - '6 upper' 734 | 10, 3, 3, 3, 131, 195, 227, 115, 59, 31, 15, // 183 - '7 upper' 735 | 10, 28, 190, 247, 227, 195, 195, 227, 247, 190, 28, // 184 - '8 upper' 736 | 10, 60, 126, 231, 195, 195, 195, 195, 231, 255, 254, // 185 - '9 upper' 737 | 2, 48, 48, // 186 - ': upper' 738 | 2, 48, 48, // 187 - '; upper' 739 | 8, 192, 224, 240, 56, 28, 14, 7, 3, // 188 - '< upper' 740 | 9, 96, 96, 96, 96, 96, 96, 96, 96, 96, // 189 - '= upper' 741 | 8, 3, 7, 14, 28, 56, 240, 224, 192, // 190 - '> upper' 742 | 10, 12, 14, 7, 3, 3, 131, 195, 231, 126, 60, // 191 - '? upper' 743 | 10, 252, 254, 7, 243, 27, 27, 243, 7, 254, 252, // 192 - '@ upper' 744 | 10, 248, 254, 134, 131, 131, 131, 131, 134, 254, 248, // 193 - 'A upper' 745 | 10, 255, 255, 195, 195, 195, 195, 195, 231, 254, 60, // 194 - 'B upper' 746 | 10, 252, 254, 7, 3, 3, 3, 3, 7, 14, 12, // 195 - 'C upper' 747 | 10, 255, 255, 3, 3, 3, 3, 3, 7, 254, 252, // 196 - 'D upper' 748 | 9, 255, 255, 195, 195, 195, 195, 195, 3, 3, // 197 - 'E upper' 749 | 9, 255, 255, 195, 195, 195, 195, 195, 3, 3, // 198 - 'F upper' 750 | 10, 252, 254, 7, 3, 3, 3, 131, 135, 142, 140, // 199 - 'G upper' 751 | 10, 255, 255, 192, 192, 192, 192, 192, 192, 255, 255, // 200 - 'H upper' 752 | 4, 3, 255, 255, 3, // 201 - 'I upper' 753 | 8, 3, 3, 3, 3, 3, 3, 255, 255, // 202 - 'J upper' 754 | 9, 255, 255, 224, 240, 56, 28, 14, 7, 3, // 203 - 'K upper' 755 | 9, 255, 255, 0, 0, 0, 0, 0, 0, 0, // 204 - 'L upper' 756 | 10, 255, 255, 14, 28, 120, 120, 28, 14, 255, 255, // 205 - 'M upper' 757 | 10, 255, 255, 28, 56, 112, 224, 192, 128, 255, 255, // 206 - 'N upper' 758 | 10, 252, 254, 7, 3, 3, 3, 3, 7, 254, 252, // 207 - 'O upper' 759 | 10, 255, 255, 195, 195, 195, 195, 195, 231, 126, 60, // 208 - 'P upper' 760 | 10, 252, 254, 7, 3, 3, 3, 3, 7, 254, 252, // 209 - 'Q upper' 761 | 10, 255, 255, 195, 195, 195, 195, 195, 231, 126, 60, // 210 - 'R upper' 762 | 10, 60, 126, 231, 195, 195, 195, 195, 195, 135, 6, // 211 - 'S upper' 763 | 8, 3, 3, 3, 255, 255, 3, 3, 3, // 212 - 'T upper' 764 | 10, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, // 213 - 'U upper' 765 | 10, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, // 214 - 'V upper' 766 | 10, 255, 255, 0, 0, 0, 0, 0, 0, 255, 255, // 215 - 'W upper' 767 | 10, 15, 31, 56, 240, 224, 224, 240, 56, 31, 15, // 216 - 'X upper' 768 | 10, 15, 31, 56, 112, 224, 224, 112, 56, 31, 15, // 217 - 'Y upper' 769 | 10, 3, 3, 3, 131, 195, 227, 115, 59, 31, 15, // 218 - 'Z upper' 770 | 4, 255, 255, 3, 3, // 219 - '[ upper' 771 | 8, 3, 15, 60, 240, 192, 0, 0, 0, // 220 - '\ upper' 772 | 4, 3, 3, 255, 255, // 221 - '] upper' 773 | 8, 24, 12, 6, 3, 3, 6, 12, 24, // 222 - '^ upper' 774 | 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 223 - '_ upper' 775 | 3, 3, 15, 12, // 224 - '` upper' 776 | 10, 192, 224, 112, 48, 48, 48, 48, 48, 240, 240, // 225 - 'a upper' 777 | 10, 255, 255, 48, 48, 48, 48, 48, 112, 224, 192, // 226 - 'b upper' 778 | 9, 192, 224, 112, 48, 48, 48, 48, 48, 48, // 227 - 'c upper' 779 | 10, 192, 224, 112, 48, 48, 48, 48, 48, 255, 255, // 228 - 'd upper' 780 | 9, 192, 224, 112, 48, 48, 48, 112, 224, 192, // 229 - 'e upper' 781 | 7, 192, 252, 254, 199, 195, 195, 3, // 230 - 'f upper' 782 | 9, 192, 224, 112, 48, 48, 48, 48, 240, 240, // 231 - 'g upper' 783 | 9, 255, 255, 48, 48, 48, 48, 112, 224, 192, // 232 - 'h upper' 784 | 2, 246, 246, // 233 - 'i upper' 785 | 8, 0, 0, 0, 0, 0, 0, 246, 246, // 234 - 'j upper' 786 | 8, 254, 254, 0, 128, 192, 224, 112, 48, // 235 - 'k upper' 787 | 4, 3, 255, 255, 0, // 236 - 'l upper' 788 | 10, 240, 240, 48, 48, 240, 240, 48, 48, 240, 224, // 237 - 'm upper' 789 | 9, 240, 240, 48, 48, 48, 48, 112, 224, 192, // 238 - 'n upper' 790 | 9, 192, 224, 112, 48, 48, 48, 112, 224, 192, // 239 - 'o upper' 791 | 9, 240, 240, 48, 48, 48, 48, 112, 224, 192, // 240 - 'p upper' 792 | 9, 192, 224, 112, 48, 48, 48, 48, 240, 240, // 241 - 'q upper' 793 | 9, 240, 240, 48, 48, 48, 48, 112, 224, 192, // 242 - 'r upper' 794 | 9, 192, 224, 48, 48, 48, 48, 48, 48, 48, // 243 - 's upper' 795 | 6, 96, 252, 252, 96, 96, 0, // 244 - 't upper' 796 | 9, 240, 240, 0, 0, 0, 0, 0, 240, 240, // 245 - 'u upper' 797 | 9, 240, 240, 0, 0, 0, 0, 0, 240, 240, // 246 - 'v upper' 798 | 10, 240, 240, 0, 0, 0, 0, 0, 0, 240, 240, // 247 - 'w upper' 799 | 10, 48, 112, 224, 192, 128, 128, 192, 224, 112, 48, // 248 - 'x upper' 800 | 9, 240, 240, 0, 0, 0, 0, 0, 240, 240, // 249 - 'y upper' 801 | 10, 48, 48, 48, 48, 48, 176, 240, 240, 112, 48, // 250 - 'z upper' 802 | 6, 192, 224, 252, 62, 7, 3, // 251 - '{ upper' 803 | 2, 255, 255, // 252 - '| upper' 804 | 6, 3, 7, 62, 252, 224, 192, // 253 - '} upper' 805 | 0, // 254 806 | 0, // 255 807 | }; 808 | 809 | 810 | 811 | 812 | const uint8_t S_STD[] PROGMEM = { 813 | 'F', 1, 32, 127, 8, 814 | 2, 0, 0, // 32 - 'Space' 815 | 1, 23, // 33 - '!' 816 | 3, 3, 0, 3, // 34 - '""' 817 | 3, 31, 10, 31, // 35 - '#' 818 | 3, 22, 31, 13, // 36 - '$' 819 | 3, 9, 4, 18, // 37 - '%' 820 | 3, 10, 21, 26, // 38 - '&' 821 | 1, 3, // 39 822 | 2, 14, 17, // 40 - '(' 823 | 2, 17, 14, // 41 - ')' 824 | 3, 10, 4, 10, // 42 - '*' 825 | 3, 4, 14, 4, // 43 - '+' 826 | 2, 16, 8, // 44 - ',' 827 | 3, 4, 4, 4, // 45 - '-' 828 | 1, 16, // 46 - '.' 829 | 3, 8, 4, 2, // 47 - '/' 830 | 3, 14, 17, 14, // 48 - '0' 831 | 2, 0, 31, // 49 - '1' 832 | 3, 29, 21, 23, // 50 - '2' 833 | 3, 17, 21, 31, // 51 - '3' 834 | 3, 15, 8, 28, // 52 - '4' 835 | 3, 23, 21, 29, // 53 - '5' 836 | 3, 31, 21, 29, // 54 - '6' 837 | 3, 1, 1, 31, // 55 - '7' 838 | 3, 31, 21, 31, // 56 - '8' 839 | 3, 23, 21, 31, // 57 - '9' 840 | 1, 10, // 58 - ':' 841 | 2, 16, 10, // 59 - ';' 842 | 3, 4, 10, 17, // 60 - '<' 843 | 3, 10, 10, 10, // 61 - '=' 844 | 3, 17, 10, 4, // 62 - '>' 845 | 3, 1, 21, 3, // 63 - '?' 846 | 3, 14, 21, 22, // 64 - '@' 847 | 3, 30, 5, 30, // 65 - 'A' 848 | 3, 31, 21, 10, // 66 - 'B' 849 | 3, 14, 17, 17, // 67 - 'C' 850 | 3, 31, 17, 14, // 68 - 'D' 851 | 3, 31, 21, 17, // 69 - 'E' 852 | 3, 31, 5, 1, // 70 - 'F' 853 | 3, 14, 17, 29, // 71 - 'G' 854 | 3, 31, 4, 31, // 72 - 'H' 855 | 3, 17, 31, 17, // 73 - 'I' 856 | 3, 8, 16, 15, // 74 - 'J' 857 | 3, 31, 4, 27, // 75 - 'K' 858 | 3, 31, 16, 16, // 76 - 'L' 859 | 3, 31, 2, 31, // 77 - 'M' 860 | 3, 31, 14, 31, // 78 - 'N' 861 | 3, 14, 17, 14, // 79 - 'O' 862 | 3, 31, 5, 2, // 80 - 'P' 863 | 3, 14, 25, 30, // 81 - 'Q' 864 | 3, 31, 5, 26, // 82 - 'R' 865 | 3, 18, 21, 9, // 83 - 'S' 866 | 3, 1, 31, 1, // 84 - 'T' 867 | 3, 15, 16, 15, // 85 - 'U' 868 | 3, 7, 24, 7, // 86 - 'V' 869 | 3, 15, 28, 15, // 87 - 'W' 870 | 3, 27, 4, 27, // 88 - 'X' 871 | 3, 3, 28, 3, // 89 - 'Y' 872 | 3, 25, 21, 19, // 90 - 'Z' 873 | 3, 31, 17, 17, // 91 - '[' 874 | 3, 2, 4, 8, // 92 - '\' 875 | 3, 17, 17, 31, // 93 - ']' 876 | 3, 2, 1, 2, // 94 - '^' 877 | 3, 16, 16, 16, // 95 - '_' 878 | 2, 1, 2, // 96 - '`' 879 | 3, 12, 18, 28, // 97 - 'a' 880 | 3, 31, 18, 12, // 98 - 'b' 881 | 3, 12, 18, 18, // 99 - 'c' 882 | 3, 12, 18, 31, // 100 - 'd' 883 | 3, 12, 26, 20, // 101 - 'e' 884 | 3, 4, 31, 5, // 102 - 'f' 885 | 3, 20, 26, 12, // 103 - 'g' 886 | 3, 31, 2, 28, // 104 - 'h' 887 | 1, 29, // 105 - 'i' 888 | 2, 16, 13, // 106 - 'j' 889 | 3, 31, 8, 20, // 107 - 'k' 890 | 1, 31, // 108 - 'l' 891 | 3, 30, 6, 30, // 109 - 'm' 892 | 3, 30, 2, 28, // 110 - 'n' 893 | 3, 12, 18, 12, // 111 - 'o' 894 | 3, 30, 10, 4, // 112 - 'p' 895 | 3, 4, 10, 30, // 113 - 'q' 896 | 2, 30, 4, // 114 - 'r' 897 | 3, 20, 30, 10, // 115 - 's' 898 | 3, 4, 30, 4, // 116 - 't' 899 | 3, 14, 16, 14, // 117 - 'u' 900 | 3, 14, 24, 14, // 118 - 'v' 901 | 3, 14, 24, 14, // 119 - 'w' 902 | 3, 18, 12, 18, // 120 - 'x' 903 | 3, 22, 24, 14, // 121 - 'y' 904 | 3, 26, 30, 22, // 122 - 'z' 905 | 3, 4, 27, 17, // 123 - '{' 906 | 1, 27, // 124 - '|' 907 | 3, 17, 27, 4, // 125 - '}' 908 | 3, 6, 2, 3, // 126 - '~' 909 | 3, 31, 31, 31, // 127 - 'Full Block' 910 | }; 911 | 912 | 913 | const uint8_t N_7SEGMENT[] PROGMEM = {//Normal 7 segment 914 | 'F', 1, 46, 58, 8, 915 | 1, 64, // 46 - '.' 916 | 0, // 47 - '/' 917 | 5, 127, 65, 65, 65, 127, // 48 - '0' 918 | 5, 0, 0, 127, 0, 0, // 49 - '1' 919 | 5, 121, 73, 73, 73, 79, // 50 - '2' 920 | 5, 73, 73, 73, 73, 127, // 51 - '3' 921 | 5, 15, 8, 8, 8, 127, // 52 - '4' 922 | 5, 79, 73, 73, 73, 121, // 53 - '5' 923 | 5, 127, 73, 73, 73, 121, // 54 - '6' 924 | 5, 1, 1, 1, 1, 127, // 55 - '7' 925 | 5, 127, 73, 73, 73, 127, // 56 - '8' 926 | 5, 79, 73, 73, 73, 127, // 57 - '9' 927 | 5, 20, 0, 0, 0, 0, // 58 - ':' 928 | }; 929 | 930 | 931 | 932 | 933 | 934 | 935 | 936 | 937 | 938 | 939 | 940 | 941 | 942 | 943 | 944 | 945 | 946 | 947 | 948 | 949 | 950 | 951 | 952 | 953 | 954 | 955 | 956 | 957 | 958 | 959 | 960 | /* ******************************************************************************************************************* 961 | * BIG FONT 962 | * ******************************************************************************************************************* 963 | Default font from library HUB08 + Buffer 964 | 16*16 pixel font 965 | first byte in array is character width 966 | run function printBigText(string,X) to use this font 967 | * ******************************************************************************************************************* 968 | */ 969 | const PROGMEM uint8_t font_BIG[] = { 970 | 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 32 971 | 0x03, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 33: ! 972 | 0x08, 0xe7, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 34: " 973 | 0x0c, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, 0xff, 0xf0, 0xff, 0xf0, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, 0xff, 0xf0, 0xff, 0xf0, 0x39, 0xc0, 0x39, 0xc0, 0x39, 0xc0, // char 35: # 974 | 0x0b, 0x0e, 0x00, 0x0e, 0x00, 0x7f, 0xc0, 0xff, 0xe0, 0xee, 0xe0, 0xee, 0x00, 0xee, 0x00, 0xff, 0xc0, 0x7f, 0xe0, 0x0e, 0xe0, 0x0e, 0xe0, 0xee, 0xe0, 0xff, 0xe0, 0x7f, 0xc0, 0x0e, 0x00, 0x0e, 0x00, // char 36: $ 975 | 0x0c, 0x70, 0xe0, 0xf8, 0xe0, 0xd9, 0xc0, 0xf9, 0xc0, 0x73, 0x80, 0x03, 0x80, 0x07, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x1c, 0xe0, 0x39, 0xf0, 0x39, 0xb0, 0x71, 0xf0, 0x70, 0xe0, // char 37: % 976 | 0x0c, 0x1e, 0x00, 0x3f, 0x00, 0x73, 0x80, 0x73, 0x80, 0x73, 0x80, 0x73, 0x80, 0x33, 0x80, 0x3f, 0x00, 0x7e, 0x00, 0xee, 0x30, 0xe7, 0x70, 0xe3, 0xe0, 0xe1, 0xc0, 0xe3, 0xe0, 0xff, 0x70, 0x7e, 0x30, // char 38: & 977 | 0x03, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 39: ' 978 | 0x05, 0x38, 0x00, 0x78, 0x00, 0xf0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0x78, 0x00, 0x38, 0x00, // char 40: ( 979 | 0x05, 0xe0, 0x00, 0xf0, 0x00, 0x78, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf0, 0x00, 0xe0, 0x00, // char 41: ) 980 | 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x77, 0x00, 0x3e, 0x00, 0x1c, 0x00, 0xff, 0x80, 0xff, 0x80, 0x1c, 0x00, 0x3e, 0x00, 0x77, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 42: * 981 | 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0xff, 0x80, 0xff, 0x80, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 43: + 982 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x60, 0x00, 0xe0, 0x00, // char 44: , 983 | 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 45: - 984 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 46: . 985 | 0x05, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 47: / 986 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 48: 0 987 | 0x09, 0x1c, 0x00, 0x3c, 0x00, 0x7c, 0x00, 0xfc, 0x00, 0xdc, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0xff, 0x80, 0xff, 0x80, // char 49: 1 988 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0x00, 0xf0, 0x01, 0xe0, 0x03, 0xc0, 0x07, 0x80, 0x0f, 0x00, 0x1e, 0x00, 0x3c, 0x00, 0x78, 0x00, 0xf0, 0x70, 0xff, 0xf0, 0xff, 0xf0, // char 50: 2 989 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0x00, 0xe0, 0x01, 0xc0, 0x03, 0x80, 0x07, 0x00, 0x0f, 0xf0, 0x0f, 0xf0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 51: 3 990 | 0x0c, 0x03, 0x80, 0x07, 0x80, 0x07, 0x80, 0x0f, 0x80, 0x1f, 0x80, 0x3b, 0x80, 0x3b, 0x80, 0x73, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xff, 0xf0, 0xff, 0xf0, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, 0x03, 0x80, // char 52: 4 991 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xff, 0xc0, 0xff, 0xe0, 0x00, 0xf0, 0x00, 0x70, 0x00, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 53: 5 992 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xff, 0xc0, 0xff, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 54: 6 993 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0x00, 0x70, 0x00, 0xe0, 0x01, 0xc0, 0x03, 0x80, 0x07, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, // char 55: 7 994 | 0x0c, 0x1f, 0x80, 0x3f, 0xc0, 0x79, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x39, 0xc0, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 56: 8 995 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xf0, 0x3f, 0xf0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 57: 9 996 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, // char 58: : 997 | 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x60, 0x00, 0xe0, 0x00, // char 59: ; 998 | 0x08, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, // char 60: < 999 | 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 61: = 1000 | 0x08, 0x00, 0x00, 0xc0, 0x00, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xc0, 0x00, 0x00, 0x00, // char 62: > 1001 | 0x0b, 0x3f, 0x80, 0x7f, 0xc0, 0xf1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x01, 0xe0, 0x03, 0xc0, 0x07, 0x80, 0x0f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, // char 63: ? 1002 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe5, 0x70, 0xef, 0x70, 0xeb, 0x70, 0xeb, 0x70, 0xef, 0xf0, 0xef, 0xe0, 0xe7, 0x80, 0xe0, 0x00, 0xf0, 0x70, 0x7f, 0xe0, 0x3f, 0xc0, // char 64: @ 1003 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, // char 65: A 1004 | 0x0c, 0xff, 0x80, 0xff, 0xc0, 0x71, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x71, 0xc0, 0x7f, 0xc0, 0x7f, 0xc0, 0x70, 0xe0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xf0, 0xff, 0xe0, 0xff, 0xc0, // char 66: B 1005 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 67: C 1006 | 0x0c, 0xff, 0xc0, 0xff, 0xe0, 0x70, 0xf0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xf0, 0xff, 0xe0, 0xff, 0xc0, // char 68: D 1007 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0x70, 0x70, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x70, 0xff, 0xf0, 0xff, 0xf0, // char 69: E 1008 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0x70, 0x70, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x7f, 0x00, 0x7f, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, // char 70: F 1009 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe7, 0xf0, 0xe7, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 71: G 1010 | 0x0c, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, // char 72: H 1011 | 0x07, 0xfe, 0x00, 0xfe, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0xfe, 0x00, 0xfe, 0x00, // char 73: I 1012 | 0x0c, 0x07, 0xf0, 0x07, 0xf0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 74: J 1013 | 0x0c, 0xf0, 0x70, 0xf0, 0x70, 0x70, 0x70, 0x70, 0xe0, 0x71, 0xc0, 0x73, 0x80, 0x77, 0x00, 0x7e, 0x00, 0x7e, 0x00, 0x77, 0x00, 0x73, 0x80, 0x71, 0xc0, 0x70, 0xe0, 0x70, 0x70, 0xf0, 0x70, 0xf0, 0x70, // char 75: K 1014 | 0x0a, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe1, 0xc0, 0xff, 0xc0, 0xff, 0xc0, // char 76: L 1015 | 0x0b, 0xe0, 0xe0, 0xe0, 0xe0, 0xf1, 0xe0, 0xf1, 0xe0, 0xfb, 0xe0, 0xff, 0xe0, 0xff, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xe4, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, // char 77: M 1016 | 0x0b, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xe0, 0xf8, 0xe0, 0xf8, 0xe0, 0xec, 0xe0, 0xec, 0xe0, 0xe6, 0xe0, 0xe6, 0xe0, 0xe3, 0xe0, 0xe3, 0xe0, 0xe1, 0xe0, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, // char 78: N 1017 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 79: O 1018 | 0x0c, 0xff, 0xc0, 0xff, 0xe0, 0x70, 0xf0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xf0, 0x7f, 0xe0, 0x7f, 0xc0, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, // char 80: P 1019 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe6, 0x70, 0xe7, 0x70, 0xe3, 0xf0, 0xe1, 0xe0, 0xf3, 0xe0, 0x7f, 0xf0, 0x3f, 0xb0, // char 81: Q 1020 | 0x0c, 0xff, 0xc0, 0xff, 0xe0, 0x70, 0xf0, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0xf0, 0x7f, 0xe0, 0x7f, 0xc0, 0x7f, 0x00, 0x77, 0x80, 0x73, 0xc0, 0x71, 0xe0, 0x70, 0xf0, 0x70, 0x70, 0x70, 0x70, // char 82: R 1021 | 0x0c, 0x3f, 0xc0, 0x7f, 0xe0, 0xf0, 0xf0, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x00, 0xf0, 0x00, 0x7f, 0xc0, 0x3f, 0xe0, 0x00, 0xf0, 0x00, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 83: S 1022 | 0x0b, 0xff, 0xe0, 0xff, 0xe0, 0xee, 0xe0, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, // char 84: T 1023 | 0x0c, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xf0, 0xf0, 0x7f, 0xe0, 0x3f, 0xc0, // char 85: U 1024 | 0x0c, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0x70, 0xe0, 0x70, 0xe0, 0x39, 0xc0, 0x39, 0xc0, 0x1f, 0x80, 0x1f, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x06, 0x00, // char 86: V 1025 | 0x0c, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe6, 0x70, 0xe6, 0x70, 0xef, 0x70, 0x6f, 0x60, 0x7f, 0xe0, 0x7f, 0xe0, 0x79, 0xe0, 0x30, 0xc0, 0x30, 0xc0, // char 87: W 1026 | 0x0c, 0xf9, 0xf0, 0xf9, 0xf0, 0x70, 0xe0, 0x70, 0xe0, 0x39, 0xc0, 0x39, 0xc0, 0x1f, 0x80, 0x0f, 0x00, 0x0f, 0x00, 0x1f, 0x80, 0x39, 0xc0, 0x39, 0xc0, 0x70, 0xe0, 0x70, 0xe0, 0xf9, 0xf0, 0xf9, 0xf0, // char 88: X 1027 | 0x0b, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0x71, 0xc0, 0x3b, 0x80, 0x1f, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, // char 89: Y 1028 | 0x0c, 0xff, 0xf0, 0xff, 0xf0, 0xe0, 0x70, 0x00, 0x70, 0x00, 0xe0, 0x01, 0xc0, 0x03, 0x80, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xe0, 0x70, 0xff, 0xf0, 0xff, 0xf0, // char 90: Z 1029 | 0x06, 0xfc, 0x00, 0xfc, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xfc, 0x00, 0xfc, 0x00, // char 91: [ 1030 | 0x05, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 92: backslash 1031 | 0x06, 0xfc, 0x00, 0xfc, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0xfc, 0x00, 0xfc, 0x00, // char 93: ] 1032 | 0x09, 0x1c, 0x00, 0x3e, 0x00, 0x77, 0x00, 0xe3, 0x80, 0xe3, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 94: ^ 1033 | 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0xff, 0x80, // char 95: _ 1034 | 0x06, 0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 96: ` 1035 | 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80, 0x7f, 0xc0, 0x03, 0xc0, 0x01, 0xc0, 0x3f, 0xc0, 0x7f, 0xc0, 0xf1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0xe0, 0x3e, 0xe0, // char 97: a 1036 | 0x0a, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xef, 0x00, 0xff, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0xff, 0x80, 0xef, 0x00, // char 98: b 1037 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x7f, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 99: c 1038 | 0x0a, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x3d, 0xc0, 0x7f, 0xc0, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0xc0, 0x3d, 0xc0, // char 100: d 1039 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x7f, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xe0, 0x00, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 101: e 1040 | 0x08, 0x0f, 0x00, 0x1f, 0x00, 0x3c, 0x00, 0x38, 0x00, 0xff, 0x00, 0xff, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, // char 102: f 1041 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xc0, 0x7f, 0xc0, 0xf3, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0xc0, 0x3d, 0xc0, 0x01, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 103: g 1042 | 0x0a, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xef, 0x00, 0xff, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, // char 104: h 1043 | 0x05, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0x70, 0x00, 0xf8, 0x00, 0xf8, 0x00, // char 105: i 1044 | 0x07, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0xee, 0x00, 0xfe, 0x00, 0x7c, 0x00, 0x38, 0x00, // char 106: j 1045 | 0x0a, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe1, 0xc0, 0xe3, 0xc0, 0xe7, 0x80, 0xef, 0x00, 0xfe, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0xfe, 0x00, 0xef, 0x00, 0xe7, 0x80, 0xe3, 0xc0, 0xe1, 0xc0, // char 107: k 1046 | 0x04, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x70, 0x00, // char 108: l 1047 | 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x80, 0xff, 0xc0, 0xff, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, 0xee, 0xe0, // char 109: m 1048 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0xff, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, // char 110: n 1049 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x7f, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 111: o 1050 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xef, 0x00, 0xff, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0xff, 0x80, 0xef, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 112: p 1051 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xc0, 0x7f, 0xc0, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0xc0, 0x3d, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, // char 113: q 1052 | 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0xfe, 0x00, 0xf0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 114: r 1053 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x7f, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xf0, 0x00, 0x7f, 0x00, 0x3f, 0x80, 0x03, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, // char 115: s 1054 | 0x07, 0x08, 0x00, 0x18, 0x00, 0x38, 0x00, 0x38, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x1e, 0x00, 0x0e, 0x00, // char 116: t 1055 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0xc0, 0x3d, 0xc0, // char 117: u 1056 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, 0x73, 0x80, 0x73, 0x80, 0x33, 0x00, 0x3f, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x0c, 0x00, // char 118: v 1057 | 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x70, 0xe0, 0x70, 0xe0, 0x70, 0xe6, 0x70, 0xe6, 0x70, 0xef, 0x70, 0xff, 0xf0, 0x7f, 0xe0, 0x79, 0xe0, 0x79, 0xe0, 0x30, 0xc0, 0x30, 0xc0, // char 119: w 1058 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xc0, 0xe1, 0xc0, 0xf3, 0xc0, 0x7f, 0x80, 0x3f, 0x00, 0x1e, 0x00, 0x1e, 0x00, 0x3f, 0x00, 0x7f, 0x80, 0xf3, 0xc0, 0xe1, 0xc0, 0xe1, 0xc0, // char 120: x 1059 | 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0x71, 0xc0, 0x71, 0xc0, 0x3b, 0x80, 0x3b, 0x80, 0x1f, 0x00, 0x1f, 0x00, 0x0e, 0x00, 0x1e, 0x00, 0xfc, 0x00, 0x78, 0x00, // char 121: y 1060 | 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xc0, 0xff, 0xc0, 0xc1, 0xc0, 0x03, 0x80, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x70, 0x00, 0xe1, 0xc0, 0xff, 0xc0, 0xff, 0xc0, // char 122: z 1061 | 0x08, 0x0f, 0x00, 0x1f, 0x00, 0x3c, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x78, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0x78, 0x00, 0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x3c, 0x00, 0x1f, 0x00, 0x0f, 0x00, // char 123: { 1062 | 0x03, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, 0xe0, 0x00, // char 124: | 1063 | 0x08, 0xf0, 0x00, 0xf8, 0x00, 0x3c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x0f, 0x00, 0x0f, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x3c, 0x00, 0xf8, 0x00, 0xf0, 0x00, // char 125: } 1064 | 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x70, 0x7e, 0xf0, 0xf7, 0xe0, 0xe3, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // char 126: ~ 1065 | 0x09, 0xff, 0x80, 0xff, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xe3, 0x80, 0xff, 0x80, 0xff, 0x80, // char 127 1066 | }; 1067 | 1068 | 1069 | 1070 | 1071 | 1072 | 1073 | 1074 | 1075 | 1076 | 1077 | 1078 | 1079 | 1080 | 1081 | 1082 | /* ******************************************************************************************************************* 1083 | * CUSTOM BITMAP 1084 | * ******************************************************************************************************************* 1085 | * Make using "Monochrome Bitmap to Code Coverter.exe" check on "Tool" folder 1086 | * original library : 1087 | * Monochrome Bitmap to Code Converter Version: 0.1 Date: April 24 2013 Author: Marv aka emgoz 1088 | * https://github.com/emgoz/BufferGraphics/tree/master/Tools 1089 | */ 1090 | 1091 | uint8_t logo[128] = { 1092 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1093 | 0xC0, 0x01, 0x00, 0x04, 0x7F, 0x0E, 0x3F, 0x87, 1094 | 0xC0, 0x01, 0x00, 0x04, 0x3F, 0x0E, 0x1F, 0x87, 1095 | 0xC7, 0xF1, 0x1F, 0xC4, 0x1F, 0x8E, 0x0F, 0xC7, 1096 | 0xC7, 0xF1, 0x1F, 0xC4, 0x0F, 0x8E, 0x07, 0xC7, 1097 | 0xC0, 0x71, 0x1F, 0xC4, 0x07, 0x8E, 0x03, 0xC7, 1098 | 0xC0, 0x01, 0x1F, 0xC4, 0x03, 0x8E, 0x01, 0xC7, 1099 | 0xC0, 0x01, 0x1F, 0xC4, 0x01, 0x8E, 0x00, 0xC7, 1100 | 0xC4, 0x1F, 0x1F, 0xC4, 0x40, 0x8E, 0x20, 0x47, 1101 | 0xC6, 0x0F, 0x1F, 0xC4, 0x60, 0x4E, 0x30, 0x27, 1102 | 0xC7, 0x07, 0x0F, 0xC4, 0x70, 0x2E, 0x38, 0x17, 1103 | 0xC7, 0x83, 0x07, 0xC4, 0x78, 0x1E, 0x3C, 0x0F, 1104 | 0xC7, 0xC1, 0x83, 0xC4, 0x7C, 0x0E, 0x3E, 0x07, 1105 | 0xC7, 0xE0, 0xC0, 0x04, 0x7E, 0x06, 0x3F, 0x03, 1106 | 0xC7, 0xF0, 0x60, 0x04, 0x7F, 0x02, 0x3F, 0x81, 1107 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 1108 | }; 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | 1115 | 1116 | 1117 | 1118 | 1119 | 1120 | 1121 | 1122 | 1123 | 1124 | 1125 | 1126 | 1127 | 1128 | 1129 | 1130 | 1131 | 1132 | 1133 | 1134 | 1135 | 1136 | 1137 | /* ******************************************************************************************************************* 1138 | * CUSTOM FONT 1139 | * ******************************************************************************************************************* 1140 | * Make using "Font Builder.xlsm" (check on "Tool" folder) 1141 | */ 1142 | const uint8_t C_ICON[] PROGMEM = { //custom icon (9x8) 1143 | 'F', 1, 48, 57, 8, 1144 | 9, 126, 129, 185, 149, 149, 149, 185, 129, 126, // 48 - '0' --> FONT ICON 1145 | 9, 126, 129, 133, 133, 189, 133, 133, 129, 126, // 49 - '1' --> TEXT ICON 1146 | 9, 126, 129, 153, 165, 165, 165, 165, 129, 126, // 50 - '2' --> CLEAR ICON 1147 | 9, 126, 129, 189, 133, 189, 133, 189, 129, 126, // 51 - '3' --> MOVE ICON 1148 | 9, 126, 129, 145, 161, 145, 137, 133, 129, 126, // 52 - '4' --> END ICON 1149 | 5, 79, 73, 73, 73, 49, // 53 - '5' 1150 | 5, 62, 73, 73, 73, 48, // 54 - '6' 1151 | 5, 3, 1, 1, 1, 127, // 55 - '7' 1152 | 5, 54, 73, 73, 73, 54, // 56 - '8' 1153 | 5, 6, 73, 73, 73, 62, // 57 - '9' 1154 | }; 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | 1161 | --------------------------------------------------------------------------------