├── LICENSE ├── README.md ├── MAX7219array_demo.py ├── MAX7219array_ReadMe.py ├── MAX7219array.py └── MAX7219fonts.py /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 JonA1961 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MAX7219array 2 | ============ 3 | 4 | Drive an array of MAX7219 8x8 LED matrices via SPI in Python from the Raspberry Pi 5 | 6 | Files: 7 | 8 | MAX7219array.py: 9 | Library of functions for driving an array of daisy-chained MAX7219 8x8 LED matrix boards 10 | 11 | MAX7219fonts.py: 12 | Fonts data for use by the MAX7219array.py library 13 | 14 | MAX7219array_demo.py: 15 | Demonstration of the features in the MAX7219array library 16 | 17 | MAX7219array_ReadMe.py: 18 | Documentation file consisting largely of comments also included in the other files 19 | See this file for more details 20 | 21 | 22 | Installation of spidev module required to use this library: 23 | Before you use these files, unless you already have it installed on your Pi, you need to install spidev. I suggest you follow the same instructions that I used from http://www.100randomtasks.com/simple-spi-on-raspberry-pi (ignore the references to the TLC549 ADC but follow the instructions as far as the bit that reads "With all the setup now complete, it's time to write some python") 24 | 25 | To download all the MAX7219array files, enter the following on your RPi at the command line prompt: 26 | 27 | git clone https://github.com/JonA1961/MAX7219array.git 28 | 29 | This will create a folder in your current folder called MAX7219array and copy the files from Github into it. 30 | 31 | Note that the demo script is written for a set-up of 8 MAX7219 boards. It should run even if you have a different number but will not (obviously) display exactly what I intended it to. Looking at the code however you should see how to adapt it for your purposes, or how to use the library functions. 32 | 33 | The wiring setup I used for the MAX7219 boards is documented in either the MAX7219array.py or the MAX7219array_ReadMe.py files. You also need to set the value of NUM_MATRICES in the MAX7219array.py library file to the number of MAX7219 boards you have in your daisy-chain. 34 | 35 | To run the demo, in the MAX7219array folder, enter the following at the command line prompt: 36 | 37 | python MAX7219array_demo.py 38 | 39 | To use the library file as a simple command-line utility to scroll a message on the array, first alter the permissions as follows: 40 | 41 | chmod +x MAX7219array.py 42 | 43 | and you can then enter at the command line prompt: 44 | 45 | ./MAX7219array.py 'Your message goes here' 46 | 47 | 48 | Note: 49 | Written for Python 2.7. I believe the main culprits requiring attention to make the library script compatible with Python 3 would be the print statements in the last 20 or so lines 50 | -------------------------------------------------------------------------------- /MAX7219array_demo.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # --------------------------------------------------------- 3 | # Filename: MAX7219array_demo.py 4 | # --------------------------------------------------------- 5 | # Demonstration of the features in the MAX7219array library 6 | # 7 | # v1.0 8 | # JLC Archibald 2014 9 | # --------------------------------------------------------- 10 | # Inspired by and based on the max7219 module by RM Hull 11 | # (see https://github.com/rm-hull/max7219) 12 | # --------------------------------------------------------- 13 | # See MAX7219array.py library file for more details 14 | # --------------------------------------------------------- 15 | # This demo script is intended to run on an array of 8 16 | # MAX7219 boards, connected as described in the library 17 | # script. It should run without errors on other-sized 18 | # arrays, but would not then fully or correctly display 19 | # the operation of the library functions 20 | # The variable NUM_MATRICES, defined in the MAX7219array.py 21 | # library script, should always be set to be consistent 22 | # with the actual hardware setup in use. If it is not 23 | # set correctly, then the functions will not work as 24 | # intended: 25 | # a)NUM_MATRICES set > actual number or matrices: 26 | # The functions will assume the presence of the 27 | # non-existent extra matrices off to the left-hand 28 | # side of the real array, and so some data sent will 29 | # not be displayed 30 | # b)NUM_MATRICES set < actual number of matrices: 31 | # The functions should work correctly in the right- 32 | # most matrices declared to the library. Some of 33 | # the displayed data will however be duplicated on 34 | # the addition non-declared matrices 35 | # The main script calling the library functions should 36 | # send arguments appropriate for the value of 37 | # NUM_MATRICES set in the library. Error-trapping in 38 | # the library attempts to capture any inappropriate 39 | # arguments (and either set them to appropriate values 40 | # instead or simply ignore the command) but may not 41 | # correct or eliminate them all. If required, the 42 | # NUM_MATRICES variable could be imported into the 43 | # main script to allow the script to adjust to the 44 | # size of array in use 45 | # --------------------------------------------------------- 46 | 47 | import time 48 | from random import randrange 49 | 50 | # Import library 51 | import MAX7219array as m7219 52 | # Import fonts 53 | from MAX7219fonts import CP437_FONT, SINCLAIRS_FONT, LCD_FONT, TINY_FONT 54 | 55 | # The following imported variables make it easier to feed parameters to the library functions 56 | from MAX7219array import DIR_L, DIR_R, DIR_U, DIR_D 57 | from MAX7219array import DIR_LU, DIR_RU, DIR_LD, DIR_RD 58 | from MAX7219array import DISSOLVE, GFX_ON, GFX_OFF, GFX_INVERT 59 | 60 | # Initialise the library and the MAX7219/8x8LED array 61 | m7219.init() 62 | 63 | try: 64 | 65 | # Display a stationary message 66 | m7219.static_message("Welcome!") 67 | time.sleep(2) 68 | m7219.clear_all() 69 | 70 | # Cycle through the range of brightness levels - up then down 71 | m7219.brightness(0) 72 | m7219.static_message("Bright ?") 73 | for loop in range(2): 74 | for brightness in range(15*(loop%2), 16-17*(loop%2), 1-2*(loop%2)): 75 | m7219.brightness(brightness) 76 | time.sleep(0.1) 77 | time.sleep(1) 78 | 79 | # Clear the whole display and reset brightness 80 | m7219.clear_all() 81 | m7219.brightness(3) 82 | time.sleep(1) 83 | 84 | # Random flashing lights (Hollywood's version of a computer) 85 | for loop in range(16): 86 | for matrix in range(8): 87 | for col in range(8): 88 | m7219.send_matrix_reg_byte(matrix, col+1, randrange(0x100)) 89 | time.sleep(0.001) 90 | m7219.clear_all() 91 | time.sleep(1) 92 | 93 | # Display all characters from the font individually 94 | for char in range(0x100): 95 | m7219.send_matrix_letter(7-(char%8), char) 96 | time.sleep(0.02) 97 | time.sleep(0.5) 98 | m7219.clear_all() 99 | time.sleep(0.5) 100 | 101 | # Scroll characters in each of 4 directions 102 | for matrix in range(8): 103 | m7219.send_matrix_letter(matrix, 72 - matrix) 104 | time.sleep(0.5) 105 | letter_offset=0 106 | for dir in (DIR_L, DIR_R, DIR_U, DIR_D): 107 | for stage in range(8): 108 | for matrix in range(8): 109 | m7219.send_matrix_shifted_letter(matrix, 72 - matrix + letter_offset, 73 - matrix - letter_offset, stage, dir) 110 | time.sleep(0.1) 111 | letter_offset = 1 - letter_offset 112 | for dir in (DIR_R, DIR_L, DIR_D, DIR_U): 113 | for stage in range(8): 114 | for matrix in range(8): 115 | m7219.send_matrix_shifted_letter(matrix, 72 - matrix - letter_offset, 71 - matrix + letter_offset, stage, dir) 116 | time.sleep(0.1) 117 | letter_offset = 1 - letter_offset 118 | for matrix in range(8): 119 | m7219.send_matrix_letter(matrix, 72 - matrix) 120 | time.sleep(1) 121 | m7219.clear_all() 122 | 123 | # Scroll only part of a display 124 | Floors = ["B", "G", "1", "2"] 125 | m7219.static_message("Floor: " + Floors[0]) 126 | time.sleep(1) 127 | for floor, display in enumerate(Floors[:-1]): 128 | for stage in range(8): 129 | m7219.send_matrix_shifted_letter(0, ord(display), ord(Floors[floor+1]), stage, DIR_D) 130 | time.sleep(0.1) 131 | m7219.static_message("Floor: " + Floors[-1]) 132 | time.sleep(1) 133 | m7219.clear_all() 134 | 135 | # Horizontally scroll and repeat a long message 136 | for dir in [DIR_L, DIR_R]: 137 | for speed in [3,6,9]: 138 | m7219.scroll_message_horiz("Speed:"+chr(48+speed)+" ", speed/3 , speed, dir) 139 | time.sleep(1) 140 | 141 | # Vertically transition (scroll) between different lines of a message 142 | for speed in [3,6,9]: 143 | m7219.static_message("Speed: "+chr(48+speed)) 144 | time.sleep(1) 145 | m7219.scroll_message_vert("Speed: "+chr(48+speed), "Line 2",speed, DIR_U) 146 | time.sleep(0.25) 147 | m7219.scroll_message_vert("Line 2", "Line 3", speed, DIR_U) 148 | time.sleep(0.25) 149 | m7219.scroll_message_vert("Line 3", "Speed: "+chr(48+speed), speed, DIR_U) 150 | time.sleep(1) 151 | m7219.scroll_message_vert("Speed: "+chr(48+speed), "Line 5", speed, DIR_D) 152 | time.sleep(0.25) 153 | m7219.scroll_message_vert("Line 5", "Line 6", speed, DIR_D) 154 | time.sleep(0.25) 155 | m7219.scroll_message_vert("Line 6", "Speed: "+chr(48+speed), speed, DIR_D) 156 | time.sleep(1) 157 | m7219.clear_all() 158 | time.sleep(1) 159 | 160 | # Wipe/fade effects 161 | m7219.static_message("ABCDEFGH") 162 | time.sleep(1) 163 | for trans in (DIR_U, DIR_RU, DIR_R, DIR_RD, DIR_D, DIR_LD, DIR_L, DIR_LU): 164 | m7219.wipe_message("ABCDEFGH", "IJKLMNOP" ,4, trans) 165 | time.sleep(0.5) 166 | m7219.wipe_message("IJKLMNOP", "ABCDEFGH" ,4, trans) 167 | time.sleep(0.5) 168 | time.sleep(1) 169 | for repeat in range(2): 170 | m7219.wipe_message("ABCDEFGH", "Dissolve" ,4, DISSOLVE) 171 | time.sleep(0.5) 172 | m7219.wipe_message("Dissolve", "ABCDEFGH" ,4, DISSOLVE) 173 | time.sleep(0.5) 174 | time.sleep(1) 175 | m7219.clear_all() 176 | 177 | # Different fonts available in fonts.py 178 | m7219.scroll_message_horiz("CP437_FONT : ABCDEFGH abcdefgh 1234567890 +++ ", 2, 7.5, DIR_L, CP437_FONT) 179 | m7219.scroll_message_horiz("LCD_FONT : ABCDEFGH abcdefgh 1234567890 +++ ", 2, 7.5, DIR_L, LCD_FONT) 180 | m7219.scroll_message_horiz("SINCLAIRS_FONT : ABCDEFGH abcdefgh 1234567890 +++ ", 2, 7.5, DIR_L, SINCLAIRS_FONT) 181 | m7219.scroll_message_horiz("TINY_FONT : ABCDEFGH abcdefgh 1234567890 +++ ", 2, 7.5, DIR_L, TINY_FONT) 182 | 183 | # Displaying 'graphics' (a simulated ECG) by a low-level method 184 | heartbeat = [0x10, 0x10, 0x0F, 0xFC, 0x30, 0x08, 0x10, 0x10] 185 | for loop in range(2): 186 | for matrix in range(7, -1, -1): 187 | for col in range(8): 188 | m7219.send_matrix_reg_byte((matrix-1)%8, col+1, 0x00) 189 | m7219.send_matrix_reg_byte(matrix, col+1, heartbeat[col]) 190 | time.sleep(0.15) 191 | 192 | # Clear each matrix in turn 193 | for matrix in range(7, -1, -1): 194 | m7219.clear([matrix]) 195 | time.sleep(0.2) 196 | time.sleep(1) 197 | 198 | # Print text characters using gfx_ method 199 | text="MAX 7219" 200 | for letter in range(len(text)): 201 | m7219.gfx_letter(ord(text[letter]), 8*letter) 202 | m7219.gfx_render() 203 | time.sleep(1) 204 | 205 | # Using gfx_ methods allows easy subsequent manipulation eg inverting text 206 | for matrix in range(3,8): 207 | for col in range(8): 208 | m7219.gfx_set_col(8*matrix+col, GFX_INVERT) 209 | m7219.gfx_render() 210 | time.sleep(1) 211 | 212 | # Draw some line patterns and demonstrate graphics scrolling 213 | for fill in (GFX_OFF, GFX_ON): 214 | m7219.gfx_set_all(GFX_OFF) 215 | m7219.gfx_line(0, 3, 63, 3, GFX_ON) 216 | m7219.gfx_line(0, 4, 63, 4, GFX_ON) 217 | for matrix in range(8): 218 | m7219.gfx_line(8*matrix+3 ,0 ,8*matrix+3 ,7 , GFX_ON) 219 | m7219.gfx_line(8*matrix+4 ,0 ,8*matrix+4 ,7 , GFX_ON) 220 | m7219.gfx_render() 221 | time.sleep(1) 222 | for index, scroll in enumerate([DIR_LD, DIR_L, DIR_LU, DIR_U, DIR_RU, DIR_R, DIR_RD, DIR_D]): 223 | for repeat in range(8): 224 | m7219.gfx_scroll(scroll, 8*index, 8, 0, 8, fill) 225 | m7219.gfx_render() 226 | time.sleep(0.05) 227 | m7219.gfx_set_all(GFX_OFF) 228 | m7219.gfx_render() 229 | 230 | # Draw random lines in both 'on' & 'off' modes 231 | x_new = 32 232 | y_new = 0 233 | for ink in [GFX_ON, GFX_OFF]: 234 | for line in range(128): 235 | x_old, y_old = x_new, y_new 236 | x_new, y_new = randrange(64), 7 - y_old 237 | m7219.gfx_line(x_old, y_old, x_new, y_new, ink) 238 | m7219.gfx_render() 239 | time.sleep(0.1) 240 | time.sleep(1) 241 | m7219.gfx_set_all(GFX_OFF) 242 | m7219.gfx_render() 243 | 244 | # Printing text in 'invert' mode allows easy subsequent erasure (eg to scroll it over a background) 245 | for x_s in range(16, 41): 246 | m7219.gfx_line(x_s, 7, x_s + 7, 0) 247 | text = " Raspberry Pi " 248 | rasp = [0x03, 0x05, 0x39, 0x46, 0xAA, 0x94, 0xAA, 0x46, 0x39, 0x05, 0x03] 249 | length = len(text) 250 | ext = len(rasp) 251 | for position in range(64, -8*length-2*ext-1, -1): 252 | m7219.gfx_sprite(rasp, position, GFX_INVERT) 253 | for letter in range(length): 254 | m7219.gfx_letter(ord(text[letter]), ext+position+8*letter, GFX_INVERT) 255 | m7219.gfx_sprite(rasp, ext+position+8*length, GFX_INVERT) 256 | m7219.gfx_render() 257 | time.sleep(0.1) 258 | m7219.gfx_sprite(rasp, position, GFX_INVERT) 259 | for letter in range(length): 260 | m7219.gfx_letter(ord(text[letter]), ext+position+8*letter, GFX_INVERT) 261 | m7219.gfx_sprite(rasp, ext+position+8*length, GFX_INVERT) 262 | 263 | # Similarly graphics drawn eg with gfx_sprite can be erased and scrolled by using 'invert' mode 264 | m7219.gfx_set_all(GFX_OFF) 265 | m7219.gfx_render() 266 | sinewave = [0x0C, 0x02, 0x01, 0x01, 0x02, 0x0C, 0x30, 0x40, 0x80, 0x80, 0x40, 0x30] 267 | sine_len=len(sinewave) 268 | text = "Max 7219" 269 | for letter in range(len(text)): 270 | m7219.gfx_letter(ord(text[letter]), 8*letter, GFX_ON) 271 | m7219.gfx_render() 272 | for loop in range(16): 273 | for position in range(sine_len): 274 | for repeat in range(64//sine_len+2): 275 | m7219.gfx_sprite(sinewave, repeat*sine_len - position, GFX_INVERT) 276 | m7219.gfx_render() 277 | time.sleep(0.02) 278 | for repeat in range(64//sine_len+2): 279 | m7219.gfx_sprite(sinewave, repeat*sine_len - position, GFX_INVERT) 280 | m7219.gfx_render() 281 | 282 | # Define & draw a large sprite, and then move it around on the array 283 | Pi = [0x7E, 0x12, 0x12, 0x6C, 0x00, 0x54, 0x54, 0x78, # Ra 284 | 0x00, 0x48, 0x54, 0x24, 0x00, 0xFC, 0x24, 0x18, # sp 285 | 0x00, 0x7E, 0x48, 0x30, 0x00, 0x38, 0x54, 0x58, # be 286 | 0x00, 0x78, 0x04, 0x04, 0x00, 0x78, 0x04, 0x04, # rr 287 | 0x9C, 0xA0, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, # y_ 288 | 0x00, 0x7E, 0x12, 0x12, 0x0C, 0x00, 0x74, 0x00, # Pi 289 | 0x00, 0x00, 0x00, 0x03, 0x05, 0x39, 0x46, 0xAA, # } logo 290 | 0x94, 0xAA, 0x46, 0x39, 0x05, 0x03] # } 291 | m7219.gfx_set_all(GFX_OFF) 292 | m7219.gfx_sprite(Pi,1) 293 | m7219.gfx_render() 294 | time.sleep(1) 295 | for repeat in range(2): 296 | for scroll in (DIR_L, DIR_LU, DIR_U, DIR_RU, DIR_R, DIR_RD, DIR_D, DIR_LD): 297 | moves = 2*repeat+1 298 | if scroll in [DIR_R, DIR_RD, DIR_D, DIR_LD]: 299 | moves += 1 300 | for loop in range(moves): 301 | m7219.gfx_scroll(scroll) 302 | m7219.gfx_render() 303 | time.sleep(0.1) 304 | 305 | # Continuous marquee display 306 | diamonds = chr(4) * 5 307 | m7219.scroll_message_horiz(" This is the end of the demo " + diamonds + " Press to end " + diamonds, 0, 5) 308 | 309 | except KeyboardInterrupt: 310 | # reset array 311 | m7219.scroll_message_horiz("Goodbye!", 1, 8) 312 | m7219.clear_all() 313 | -------------------------------------------------------------------------------- /MAX7219array_ReadMe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # ----------------------------------------------------------- 3 | # This filename: MAX78219array_ReadMe.py 4 | # ----------------------------------------------------------- 5 | # Documentation read-me file for MAX7219array.py library 6 | # and the suppporting files 7 | # Largely duplicates comments in the scripts 8 | # ----------------------------------------------------------- 9 | # ----------------------------------------------------------- 10 | # 11 | # 12 | # 13 | # 14 | # ----------------------------------------------------------- 15 | # ----------------------------------------------------------- 16 | # Library filename: MAX7219array.py 17 | # ----------------------------------------------------------- 18 | # MAX7219array library - functions for driving an array of 19 | # daisy-chained MAX7219 8x8 LED matrix boards 20 | # 21 | # v1.0 22 | # JLC Archibald 2014 23 | # ----------------------------------------------------------- 24 | # Controls a linear array of MAX7219 LED Display Drivers, 25 | # each of which is driving an 8x8 LED matrix. 26 | # 27 | # Terminology used in this script: 28 | # - matrix: one of the MAX7219 boards incl 8x8 LED display 29 | # - array: a 'daisy-chained' line of such matrices 30 | # 31 | # Wiring up the array of MAX7219 controller boards: 32 | # - Each board's Vcc & GND pins connected to power (not from 33 | # the Raspberry Pi as the current requirement would be too 34 | # high). Note that the common GND also needs to be connected 35 | # to the Pi's GND pin 36 | # - Each board's CS & CLK pins to be connected to the corresponding 37 | # SPI GPIO pins (CE0=Pin24 & SCLK=Pin23) on the RPi 38 | # - The right-most board's DIN pins to be connected to the 39 | # MOSI (=Pin19) SPI GPIO pin on the RPi 40 | # - Each subsequent board's DIN pin to be connected to the DOUT 41 | # pin on the board to its right as shown below: 42 | # 43 | # ...-+ +----+ +----+ +----+ 44 | # | | | | | | | 45 | # DOUT- | DOUT- | DOUT- | DOUT- 46 | # | | | | | | | | | | | 47 | # -DIN- | -DIN- | -DIN- | -DIN- 48 | # | | | | | | | 49 | # +----+ +----+ +----+ +---> RPi SPI.MOSI 50 | # 51 | # Numbering used by this library: 52 | # - The total number of matrices daisy-chained to be specified 53 | # in the NUM_MATRICES variable below 54 | # - Matrices are numbered from 0 (left) to NUM_MATRICES-1 (right) 55 | # - gfx_ (graphics-based) functions use an x,y coordinate system 56 | # to address individual LEDs: 57 | # x=0 (left-hand column) to x=8*NUM_MATRICES-1 (right-hand column) 58 | # y=0 (top row) to y=7 (bottom row) 59 | # ----------------------------------------------------------- 60 | # The main use for this script is as an imported library: 61 | # 1. In the main script, import the library using eg: 62 | # import MAX7219array.py as m7219 63 | # 2. Also import the fonts with: 64 | # from MAX7219fonts import CP437_FONT, SINCLAIRS_FONT, LCD_FONT, TINY_FONT 65 | # 3. To facilitate calling the library functions, 66 | # import the following pre-defined parameters: 67 | # from MAX7219array import DIR_L, DIR_R, DIR_U, DIR_D 68 | # from MAX7219array import DIR_LU, DIR_RU, DIR_LD, DIR_RD 69 | # from MAX7219array import DISSOLVE, GFX_ON, GFX_OFF, GFX_INVERT 70 | # 4. The main script can then use the library functions using eg: 71 | # m7219.scroll_message_horiz("Marquee text goes here") 72 | # 73 | # This script can also be executed directly as a shorthand way of running 74 | # a 'marquee' display. Enter the following at the command line to use 75 | # this functionality: 76 | # python MAX7219array.py message [repeats [speed [direction [font]]]]" 77 | # Or for more information on this usage, see the help text at the end of this 78 | # script, or alternatively, enter the following at the command line: 79 | # python MAX7219array.py 80 | # ----------------------------------------------------------- 81 | # Based on and extended from the max7219 module by RM Hull 82 | # (see https://github.com/rm-hull/max7219) 83 | # but uses the spidev module to provide the SPI interface 84 | # instead of the SPI-Py C extension used by max7219 85 | # ----------------------------------------------------------- 86 | # Requires: 87 | # - python-dev & py-spidev modules, see install instructions 88 | # at www.100randomtasks.com/simple-spi-on-raspberry-pi 89 | # - MAX7219fonts.py file containing font bitmaps 90 | # - User should also set NUM_MATRICES variable below to the 91 | # appropriate value for the setup in use. Failure to do 92 | # this will prevent the library functions working properly 93 | # ----------------------------------------------------------- 94 | # The functions from spidev used in this library are: 95 | # xfer() : send bytes deasserting CS/CE after every byte 96 | # xfer2() : send bytes only de-asserting CS/CE at end 97 | # ----------------------------------------------------------- 98 | # The variable NUM_MATRICES, defined in the MAX7219array.py 99 | # library script, should always be set to be consistent 100 | # with the actual hardware setup in use. If it is not 101 | # set correctly, then the functions will not work as 102 | # intended: 103 | # a)NUM_MATRICES set > actual number or matrices: 104 | # The functions will assume the presence of the 105 | # non-existent extra matrices off to the left-hand 106 | # side of the real array, and so some data sent will 107 | # not be displayed 108 | # b)NUM_MATRICES set < actual number of matrices: 109 | # The functions should work correctly in the right- 110 | # most matrices declared to the library. Some of 111 | # the displayed data will however be duplicated on 112 | # the addition non-declared matrices 113 | # The main script calling the library functions should 114 | # send arguments appropriate for the value of 115 | # NUM_MATRICES set in the library. Error-trapping in 116 | # the library attempts to capture any inappropriate 117 | # arguments (and either set them to appropriate values 118 | # instead or simply ignore the command) but may not 119 | # correct or eliminate them all. If required, the 120 | # NUM_MATRICES variable could be imported into the 121 | # main script to allow the script to adjust to the 122 | # size of array in use 123 | # ----------------------------------------------------------- 124 | # See further documentation of each library function below 125 | # Also see MAX7219array_demo.py script for examples of use 126 | # MAX7219 datasheet gives full details of operation of the 127 | # LED driver chip 128 | # ----------------------------------------------------------- 129 | # 130 | # List of library functions: 131 | # -------------------------- 132 | # 133 | # Note that the functions below have both compulsory and 134 | # optional arguments. Optional arguments can be seen in the 135 | # syntax for each function as they have default definitions 136 | # which will be used of the argument is not provided when the 137 | # function is called. Where an argument in the function 138 | # syntax do not have these default definitions, they are 139 | # compulsory and must be provided when the function is called 140 | # eg in the function: 141 | # send_matrix_letter(matrix, char_code, font=EFAULT_FONT): 142 | # the arguments 'matrix' & 'char_code' are compulsory and 143 | # must be provided whenever the function is called 144 | # However, 'font=DEFAULT_FONT' means that the argument 145 | # 'font' COULD be provided when the function is called, 146 | # but if it is omitted, then the value of DEFAULT_FONT 147 | # will be used instead 148 | # 149 | # Low-level basic functions: 150 | # .......................... 151 | # 152 | # send_reg_byte(register, data): 153 | # Send one byte of data to one register via SPI port, 154 | # then raise CS to latch. Note that subsequent sends 155 | # will cycle this tuple through to successive MAX7219 chips 156 | # 157 | # send_bytes(datalist): 158 | # Send sequence of bytes (should be [register,data] tuples) 159 | # via SPI port, then raise CS. Included for ease of 160 | # remembering the syntax rather than the native spidev 161 | # command, but also to avoid reassigning to 'datalist' 162 | # argument 163 | # 164 | # send_matrix_reg_byte(matrix, register, data): 165 | # Send one byte of data to one register in just one MAX7219 166 | # without affecting others 167 | # 168 | # send_all_reg_byte(register, data): 169 | # Send the same byte of data to the same register in all 170 | # of the MAX7219 chips 171 | # 172 | # Housekeeping functions: 173 | # ....................... 174 | # 175 | # clear(matrix_list): 176 | # Clear one or more specified MAX7219 matrices (argument(s) 177 | # to be specified as a [list] even if just one) 178 | # 179 | # clear_all(): 180 | # Clear all of the connected MAX7219 matrices 181 | # 182 | # brightness(intensity): 183 | # Set a specified brightness level on all of the connected 184 | # MAX7219 matrices 185 | # Intensity: 0-15 with 0=dimmest, 15=brightest; in practice 186 | # the full range does not represent a large difference 187 | # 188 | # init(): 189 | # Initialise all of the MAX7219 chips (see datasheet for 190 | # details of registers) to the following settings: 191 | # show all 8 digits / using a LED matrix (not digits) / 192 | # no display test / not in shutdown mode 193 | # Also ensure the whole array is blank, set brightness & 194 | # clear the graphics buffer 195 | # 196 | # Text-based functions: 197 | # ..................... 198 | # 199 | # send_matrix_letter(matrix, char_code, font=DEFAULT_FONT): 200 | # Send one character from the specified font to a 201 | # specified MAX7219 matrix 202 | # 203 | # send_matrix_shifted_letter(matrix, curr_code, next_code, progress, direction=DIR_L, font=DEFAULT_FONT): 204 | # Send to one MAX7219 matrix a combination of two 205 | # specified characters, representing a partially- 206 | # scrolled position 207 | # progress: 0-7: how many pixels the characters are shifted: 208 | # 0=curr_code fully displayed; 209 | # 7=one pixel less than fully shifted to next_code 210 | # With multiple matrices, this function sends many NO_OP 211 | # tuples, limiting the scrolling speed achievable for a 212 | # whole line. scroll_message_horiz() and 213 | # scroll_message_vert() are more efficient and can scroll 214 | # a whole line of text faster 215 | # 216 | # static_message(message, font=DEFAULT_FONT): 217 | # Send a stationary text message to the array of MAX7219 218 | # matrices. Message will be truncated from the right to 219 | # fit the array 220 | # 221 | # scroll_message_horiz(message, repeats=0, speed=3, direction=DIR_L, font=DEFAULT_FONT, finish=True): 222 | # Scroll a text message across the array, for a specified 223 | # number of times 224 | # repeats=0 gives indefinite scrolling until script is 225 | # interrupted 226 | # speed: 0-9 for practical purposes; speed does not have 227 | # to be integral 228 | # direction: DIR_L or DIR_R only; DIR_U & DIR_D will 229 | # do nothing 230 | # finish: True/False - True ensures array is clear at end, 231 | # False ends with the last column of the last character 232 | # of message still displayed on the array - this is 233 | # included for completeness but rarely likely to be 234 | # required in practice 235 | # Scrolling starts with message off the RHS(DIR_L) 236 | # /LHS(DIR_R) of array, and ends with message off the 237 | # LHS/RHS 238 | # If repeats>1, add space(s) at end of 'message' to 239 | # separate the end of message & start of its repeat 240 | # 241 | # scroll_message_vert(old_message, new_message, speed=3, direction=DIR_U, font=DEFAULT_FONT, finish=True): 242 | # Transitions vertically between two different 243 | # (truncated if necessary) text messages 244 | # speed: 0-9 for practical purposes; speed does not 245 | # have to integral 246 | # direction: DIR_U or DIR_D only; DIR_L & DIR_R 247 | # will do nothing 248 | # finish: True/False : True completely displays 249 | # new_message at end, False leaves the transition 250 | # one pixel short. False should be used to ensure 251 | # smooth scrolling if another vertical scroll is 252 | # to follow immediately 253 | # 254 | # wipe_message(old_message, new_message, speed=3, transition=DISSOLVE, font=DEFAULT_FONT): 255 | # Transition from one message (truncated if necessary) 256 | # to another by a 'wipe' or 'dissolve' 257 | # speed: 0-9 for practical purposes; speed does not 258 | # have to integral 259 | # transition: WIPE_U, WIPE_D, WIPE_L, WIPE_R, WIPE RU, 260 | # WIPE_RD, WIPE_LU, WIPE_LD to wipe each letter 261 | # simultaneously in the respective direction 262 | # The diagonal directions do not give a true corner 263 | # -to-corner 'wipe' effect 264 | # OR transition: DISSOLVE for a pseudo-random dissolve 265 | # from old_message to new_message 266 | # 267 | # Graphics-based functions: 268 | # ......................... 269 | # 270 | # gfx_set_px(g_x, g_y, state=GFX_INVERT): 271 | # Set an individual pixel in the graphics buffer to on, 272 | # off, or the inverse of its previous state 273 | # 274 | # gfx_set_col(g_col, state=GFX_INVERT): 275 | # Set an entire column in the graphics buffer to on, 276 | # off, or the inverse of its previous state 277 | # 278 | # gfx_set_all(state=GFX_INVERT): 279 | # Set the entire graphics buffer to on, off, or the 280 | # inverse of its previous state 281 | # 282 | # gfx_line(start_x, start_y, end_x, end_y, state=GFX_INVERT, incl_endpoint=GFX_ON): 283 | # Draw a staright line in the graphics buffer between 284 | # the specified start- & end-points. The line can be 285 | # drawn by setting each affected pixel to either on, 286 | # off, or the inverse of its previous state 287 | # The final point of the line (end_x, end_y) can 288 | # either be included (default) or omitted. It can be 289 | # usefully omitted if drawing another line starting 290 | # from this previous endpoint using GFX_INVERT 291 | # 292 | # gfx_letter(char_code, start_x=0, state=GFX_INVERT, font=DEFAULT_FONT): 293 | # Overlay one character from the specified font into 294 | # the graphics buffer, at a specified horizontal position 295 | # The character is drawn by setting each affected pixel 296 | # to either on, off, or the inverse of its previous state 297 | # 298 | # gfx_sprite(sprite, start_x=0, state=GFX_INVERT): 299 | # Overlay a specified sprite into the graphics buffer, 300 | # at a specified horizontal position. The sprite is 301 | # drawn by setting each affected pixel to either on, 302 | # off, or the inverse of its previous state 303 | # Sprite is an 8-pixel (high) x n-pixel wide pattern, 304 | # expressed as a list of n bytes 305 | # eg [0x99, 0x66, 0x5A, 0x66, 0x99] 306 | # 307 | # gfx_scroll(direction=DIR_L, start_x=0, extent_x=8*NUM_MATRICES, start_y=0, extent_y=8, new_pixels=GFX_OFF): 308 | # Scroll the specified area of the graphics buffer 309 | # by one pixel in the given direction 310 | # direction: any of DIR_U, DIR_D, DIR_L, DIR_R, DIR_LU, 311 | # DIR_RU, DIR_RD, DIR_LD 312 | # Pixels outside the rectangle are unaffected; pixels 313 | # scrolled outside the rectangle are discarded 314 | # The 'new' pixels in the gap created are either set 315 | # to on or off depending upon the new_pixels argument 316 | # 317 | # gfx_read_buffer(g_x, g_y): 318 | # Return the current state (on=True, off=False) of an 319 | # individual pixel in the graphics buffer 320 | # Note that this buffer only reflects the operations 321 | # of these gfx_ functions, since the buffer was last 322 | # cleared. The buffer does not reflect the effects 323 | # of other library functions such as 324 | # send_matrix_letter() or (static_message() 325 | # 326 | # gfx_render(): 327 | # All of the above gfx_ functions only write to (or 328 | # read from) a graphics buffer maintained in memory 329 | # This command sends the entire buffer to the matrix 330 | # array - use it to display the effect of one or more 331 | # previous gfx_ functions 332 | # 333 | # Internal functions: 334 | # ................... 335 | # (used by other library functions; not intended for use 336 | # directly by user-scripts) 337 | # 338 | # scroll_text_once(text, delay, direction, font): 339 | # Subroutine used by scroll_message_horiz(), scrolls 340 | # text once across the array, starting & ending with 341 | # 'text' on the array 342 | # NOTE: Not intended to be used as a user routine; 343 | # if used, note different syntax: compulsory arguments 344 | # & requires delay rather than speed 345 | # 346 | # trim(text): 347 | # Trim or pad specified text to the length of the 348 | # MAX7219 array 349 | # 350 | # ----------------------------------------------------- 351 | # 352 | # Execution from the command line 353 | # 354 | # As well as being used as a library of functions, the 355 | # library script can itself be run directly from the 356 | # command line. In this case, it scrolls a message 357 | # across the array of MAX7219 8x8 LED boards, with 358 | # optional arguments controlling the display 359 | # 360 | # Run syntax: 361 | # python MAX7219array.py message [repeats [speed [direction [font]]]] 362 | # or, if the file has been made executable with 363 | # chmod +x MAX7219array.py : 364 | # ./MAX7219array.py message [repeats [speed [direction]]] 365 | # 366 | # Parameters: 367 | # (none) : displays this help information 368 | # message : any text to be displayed on the array 369 | # if message is more than one word, 370 | # it must be enclosed in 'quotation marks' 371 | # Note: include blank space(s) at the end 372 | # of 'message' if it is to be displayed 373 | # multiple times 374 | # repeats (optional) : number of times the message is scrolled 375 | # repeats = 0 scrolls indefinitely until 376 | # is pressed 377 | # if omitted, 'repeats' defaults to 378 | # 0 (indefinitely) 379 | # speed (optional) : how fast the text is scrolled across 380 | # the array 381 | # 1 (v.slow) to 9 (v.fast) inclusive 382 | # (not necessarily integral) 383 | # if omitted, 'speed' defaults to 3 384 | # direction (optional) : direction the text is scrolled 385 | # L or R - if omitted, 'direction' 386 | # defaults to L 387 | # font (optional) : font to use for the displayed text 388 | # CP437, SINCLAIRS, LCD or TINY only 389 | # default 'font' if not recognized 390 | # is CP437 391 | # ----------------------------------------------------------- 392 | # ----------------------------------------------------------- 393 | # 394 | # 395 | # 396 | # 397 | # ----------------------------------------------------------- 398 | # ----------------------------------------------------------- 399 | # Fonts filename: MAX7219fonts.py 400 | # ----------------------------------------------------------- 401 | # Fonts data for use by the MAX7219array.py library 402 | # 403 | # v1.0 404 | # JLC Archibald 405 | # ----------------------------------------------------------- 406 | # Structure: 407 | # - each font is a list of 256 characters 408 | # - each character represented as an 8x8 binary bitmap: 409 | # - each character's data comprises an 8-byte list 410 | # - each byte represents one column of the character 411 | # - the bytes are in column order left-to-right 412 | # - the bits in each byte are in row order: MSB (bottom row) 413 | # to LSB (top row) 414 | # - some fonts only have non-zero (ie non-blank) data for 415 | # characters in the range 0x20 to 0x7F 416 | # ----------------------------------------------------------- 417 | # Each font's source is listed, although some have had 418 | # to be transposed to the above structure 419 | # ----------------------------------------------------------- 420 | # Additional 8x8 fonts can be added as follows: 421 | # - add additional list data at the bottom of the fonts file 422 | # - ensure that the file structure is maintained, and 423 | # that the new font data is in the same form 424 | # - include zero data for any non-repesented characters, so 425 | # that every font variable is a 256x8 nested list 426 | # - import the variable names representing the additional 427 | # fonts into the MAX7219array.py library, and into the 428 | # main script where they will be used as arguments to 429 | # the library functions 430 | # ----------------------------------------------------------- 431 | # ----------------------------------------------------------- 432 | # 433 | # 434 | # 435 | # 436 | # ----------------------------------------------------------- 437 | # ----------------------------------------------------------- 438 | # Demo script filename: MAX7219array_demo.py 439 | # ----------------------------------------------------------- 440 | # Demonstration of the features in the MAX7219array library 441 | # 442 | # v1.0 443 | # JLC Archibald 2014 444 | # ----------------------------------------------------------- 445 | # Inspired by and based on the max7219 module by RM Hull 446 | # (see https://github.com/rm-hull/max7219) 447 | # ----------------------------------------------------------- 448 | # See MAX7219array.py library file for more details 449 | # ----------------------------------------------------------- 450 | # This demo script is intended to run on an array of 8 451 | # MAX7219 boards, connected as described in the library 452 | # script. It should run without errors on other-sized 453 | # arrays, but would not then fully or correctly display 454 | # the operation of the library functions 455 | # The variable NUM_MATRICES, defined in the MAX7219array.py 456 | # library script, should always be set to be consistent 457 | # with the actual hardware setup in use. If it is not 458 | # set correctly, then the functions will not work as 459 | # intended: 460 | # a)NUM_MATRICES set > actual number or matrices: 461 | # The functions will assume the presence of the 462 | # non-existent extra matrices off to the left-hand 463 | # side of the real array, and so some data sent will 464 | # not be displayed 465 | # b)NUM_MATRICES set < actual number of matrices: 466 | # The functions should work correctly in the right- 467 | # most matrices declared to the library. Some of 468 | # the displayed data will however be duplicated on 469 | # the addition non-declared matrices 470 | # The main script calling the library functions should 471 | # send arguments appropriate for the value of 472 | # NUM_MATRICES set in the library. Error-trapping in 473 | # the library attempts to capture any inappropriate 474 | # arguments (and either set them to appropriate values 475 | # instead or simply ignore the command) but may not 476 | # correct or eliminate them all. If required, the 477 | # NUM_MATRICES variable could be imported into the 478 | # main script to allow the script to adjust to the 479 | # size of array in use 480 | # ----------------------------------------------------------- 481 | # ----------------------------------------------------------- 482 | -------------------------------------------------------------------------------- /MAX7219array.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # --------------------------------------------------------- 3 | # Filename: MAX7219array.py 4 | # --------------------------------------------------------- 5 | # MAX7219array library - functions for driving an array of 6 | # daisy-chained MAX7219 8x8 LED matrix boards 7 | # 8 | # v1.0 9 | # JLC Archibald 2014 10 | # --------------------------------------------------------- 11 | # Controls a linear array of MAX7219 LED Display Drivers, 12 | # each of which is driving an 8x8 LED matrix. 13 | # 14 | # Terminology used in this script: 15 | # - matrix: one of the MAX7219 boards incl 8x8 LED display 16 | # - array: a 'daisy-chained' line of such matrices 17 | # 18 | # Wiring up the array of MAX7219 controller boards: 19 | # - Each board's Vcc & GND pins connected to power (not from 20 | # the Raspberry Pi as the current requirement would be too 21 | # high). Note that the common GND also needs to be connected 22 | # to the Pi's GND pin 23 | # - Each board's CS & CLK pins to be connected to the corresponding 24 | # SPI GPIO pins (CE0=Pin24 & SCLK=Pin23) on the RPi 25 | # - The right-most board's DIN pins to be connected to the 26 | # MOSI (=Pin19) SPI GPIO pin on the RPi 27 | # - Each subsequent board's DIN pin to be connected to the DOUT 28 | # pin on the board to its right as shown below: 29 | # 30 | # ...-+ +----+ +----+ +----+ 31 | # | | | | | | | 32 | # DOUT- | DOUT- | DOUT- | DOUT- 33 | # | | | | | | | | | | | 34 | # -DIN- | -DIN- | -DIN- | -DIN- 35 | # | | | | | | | 36 | # +----+ +----+ +----+ +---> RPi SPI.MOSI 37 | # 38 | # Numbering used by this library: 39 | # - The total number of matrices daisy-chained to be specified 40 | # in the NUM_MATRICES variable below 41 | # - Matrices are numbered from 0 (left) to NUM_MATRICES-1 (right) 42 | # - gfx_ (graphics-based) functions use an x,y coordinate system 43 | # to address individual LEDs: 44 | # x=0 (left-hand column) to x=8*NUM_MATRICES-1 (right-hand column) 45 | # y=0 (top row) to y=7 (bottom row) 46 | # --------------------------------------------------------- 47 | # The main use for this script is as an imported library: 48 | # 1. In the main script, import the library using eg: 49 | # import MAX7219array.py as m7219 50 | # 2. Also import the fonts with: 51 | # from MAX7219fonts import CP437_FONT, SINCLAIRS_FONT, LCD_FONT, TINY_FONT 52 | # 3. To facilitate calling the library functions, 53 | # import the following pre-defined parameters: 54 | # from MAX7219array import DIR_L, DIR_R, DIR_U, DIR_D 55 | # from MAX7219array import DIR_LU, DIR_RU, DIR_LD, DIR_RD 56 | # from MAX7219array import DISSOLVE, GFX_ON, GFX_OFF, GFX_INVERT 57 | # 4. The main script can then use the library functions using eg: 58 | # m7219.scroll_message_horiz("Marquee text goes here") 59 | # 60 | # This script can also be executed directly as a shorthand way of running 61 | # a 'marquee' display. Enter the following at the command line to use 62 | # this functionality: 63 | # python MAX7219array.py message [repeats [speed [direction [font]]]]" 64 | # Or for more information on this usage, see the help text at the end of this 65 | # script, or alternatively, enter the following at the command line: 66 | # python MAX7219array.py 67 | # --------------------------------------------------------- 68 | # Based on and extended from the max7219 module by RM Hull 69 | # (see https://github.com/rm-hull/max7219) 70 | # but uses the spidev module to provide the SPI interface 71 | # instead of the SPI-Py C extension used by max7219 72 | # --------------------------------------------------------- 73 | # Requires: 74 | # - python-dev & py-spidev modules, see install instructions 75 | # at www.100randomtasks.com/simple-spi-on-raspberry-pi 76 | # - MAX7219fonts.py file containing font bitmaps 77 | # - User should also set NUM_MATRICES variable below to the 78 | # appropriate value for the setup in use. Failure to do 79 | # this will prevent the library functions working properly 80 | # --------------------------------------------------------- 81 | # The functions from spidev used in this library are: 82 | # xfer() : send bytes deasserting CS/CE after every byte 83 | # xfer2() : send bytes only de-asserting CS/CE at end 84 | # --------------------------------------------------------- 85 | # The variable NUM_MATRICES, defined in the MAX7219array.py 86 | # library script, should always be set to be consistent 87 | # with the actual hardware setup in use. If it is not 88 | # set correctly, then the functions will not work as 89 | # intended: 90 | # a)NUM_MATRICES set > actual number or matrices: 91 | # The functions will assume the presence of the 92 | # non-existent extra matrices off to the left-hand 93 | # side of the real array, and so some data sent will 94 | # not be displayed 95 | # b)NUM_MATRICES set < actual number of matrices: 96 | # The functions should work correctly in the right- 97 | # most matrices declared to the library. Some of 98 | # the displayed data will however be duplicated on 99 | # the addition non-declared matrices 100 | # The main script calling the library functions should 101 | # send arguments appropriate for the value of 102 | # NUM_MATRICES set in the library. Error-trapping in 103 | # the library attempts to capture any inappropriate 104 | # arguments (and either set them to appropriate values 105 | # instead or simply ignore the command) but may not 106 | # correct or eliminate them all. If required, the 107 | # NUM_MATRICES variable could be imported into the 108 | # main script to allow the script to adjust to the 109 | # size of array in use 110 | # --------------------------------------------------------- 111 | # See further documentation of each library function below 112 | # Also see MAX7219array_demo.py script for examples of use 113 | # MAX7219 datasheet gives full details of operation of the 114 | # LED driver chip 115 | # --------------------------------------------------------- 116 | 117 | import spidev 118 | import time 119 | from random import randrange 120 | 121 | # Note: If any additional fonts are added in MAX7219fonts.py, add them to the import list here: 122 | # Also add them to the section at the end of this script that parses command line arguments 123 | from MAX7219fonts import CP437_FONT, SINCLAIRS_FONT, LCD_FONT, TINY_FONT 124 | 125 | # IMPORTANT: User must specify the number of MAX7219 matrices here: 126 | NUM_MATRICES = 8 # Number of separate MAX7219 matrices 127 | 128 | # Optional: It is also possible to change the default font for all the library functions: 129 | DEFAULT_FONT = CP437_FONT # Note: some fonts only contain characters in chr(32)-chr(126) range 130 | 131 | # --------------------------------------------------------- 132 | # Should not need to change anything below here 133 | # --------------------------------------------------------- 134 | 135 | PAD_STRING = " " * NUM_MATRICES # String for trimming text to fit 136 | NO_OP = [0,0] # 'No operation' tuple: 0x00 sent to register MAX_7219_NOOP 137 | MATRICES = range(NUM_MATRICES) # List of available matrices for validation 138 | 139 | # Graphics setup 140 | gfx_buffer = [] 141 | gfx_rows = range(8) 142 | gfx_columns = range(NUM_MATRICES * 8) 143 | for gfx_col in gfx_columns: 144 | gfx_buffer += [0] 145 | 146 | # Registers in the MAX7219 matrix controller (see datasheet) 147 | MAX7219_REG_NOOP = 0x0 148 | MAX7219_REG_DIGIT0 = 0x1 149 | MAX7219_REG_DIGIT1 = 0x2 150 | MAX7219_REG_DIGIT2 = 0x3 151 | MAX7219_REG_DIGIT3 = 0x4 152 | MAX7219_REG_DIGIT4 = 0x5 153 | MAX7219_REG_DIGIT5 = 0x6 154 | MAX7219_REG_DIGIT6 = 0x7 155 | MAX7219_REG_DIGIT7 = 0x8 156 | MAX7219_REG_DECODEMODE = 0x9 157 | MAX7219_REG_INTENSITY = 0xA 158 | MAX7219_REG_SCANLIMIT = 0xB 159 | MAX7219_REG_SHUTDOWN = 0xC 160 | MAX7219_REG_DISPLAYTEST = 0xF 161 | 162 | # Scroll & wipe directions, for use as arguments to various library functions 163 | # For ease of use, import the following constants into the main script 164 | DIR_U = 1 # Up 165 | DIR_R = 2 # Right 166 | DIR_D = 4 # Down 167 | DIR_L = 8 # Left 168 | DIR_RU = 3 # Right & up diagonal scrolling for gfx_scroll() function only 169 | DIR_RD = 6 # Right & down diagonal scrolling for gfx_scroll() function only 170 | DIR_LU = 9 # Left & up diagonal scrolling for gfx_scroll() function only 171 | DIR_LD = 12 # Left & down diagonal scrolling for gfx_scroll() function only 172 | DISSOLVE = 16 # Pseudo-random fade transition for wipe_message() function only 173 | GFX_OFF = 0 # Turn the relevant LEDs off, or omit (don't draw) the endpoint of a line 174 | GFX_ON = 1 # Turn the relevant LEDs on, or include (draw) the endpoint of a line 175 | GFX_INVERT = 2 # Invert the state of the relevant LEDs 176 | 177 | # Open SPI bus#0 using CS0 (CE0) 178 | spi = spidev.SpiDev() 179 | spi.open(0,0) 180 | 181 | # --------------------------------------- 182 | # Library function definitions begin here 183 | # --------------------------------------- 184 | 185 | def send_reg_byte(register, data): 186 | # Send one byte of data to one register via SPI port, then raise CS to latch 187 | # Note that subsequent sends will cycle this tuple through to successive MAX7219 chips 188 | spi.xfer([register, data]) 189 | 190 | def send_bytes(datalist): 191 | # Send sequence of bytes (should be [register,data] tuples) via SPI port, then raise CS 192 | # Included for ease of remembering the syntax rather than the native spidev command, but also to avoid reassigning to 'datalist' argument 193 | spi.xfer2(datalist[:]) 194 | 195 | def send_matrix_reg_byte(matrix, register, data): 196 | # Send one byte of data to one register in just one MAX7219 without affecting others 197 | if matrix in MATRICES: 198 | padded_data = NO_OP * (NUM_MATRICES - 1 - matrix) + [register, data] + NO_OP * matrix 199 | send_bytes(padded_data) 200 | 201 | def send_all_reg_byte(register, data): 202 | # Send the same byte of data to the same register in all of the MAX7219 chips 203 | send_bytes([register, data] * NUM_MATRICES) 204 | 205 | def clear(matrix_list): 206 | # Clear one or more specified MAX7219 matrices (argument(s) to be specified as a list even if just one) 207 | for matrix in matrix_list: 208 | if matrix in MATRICES: 209 | for col in range(8): 210 | send_matrix_reg_byte(matrix, col+1, 0) 211 | 212 | def clear_all(): 213 | # Clear all of the connected MAX7219 matrices 214 | for col in range(8): 215 | send_all_reg_byte(col+1, 0) 216 | 217 | def brightness(intensity): 218 | # Set a specified brightness level on all of the connected MAX7219 matrices 219 | # Intensity: 0-15 with 0=dimmest, 15=brightest; in practice the full range does not represent a large difference 220 | intensity = int(max(0, min(15, intensity))) 221 | send_bytes([MAX7219_REG_INTENSITY, intensity] * NUM_MATRICES) 222 | 223 | def send_matrix_letter(matrix, char_code, font=DEFAULT_FONT): 224 | # Send one character from the specified font to a specified MAX7219 matrix 225 | if matrix in MATRICES: 226 | for col in range(8): 227 | send_matrix_reg_byte(matrix, col+1, font[char_code % 0x100][col]) 228 | 229 | def send_matrix_shifted_letter(matrix, curr_code, next_code, progress, direction=DIR_L, font=DEFAULT_FONT): 230 | # Send to one MAX7219 matrix a combination of two specified characters, representing a partially-scrolled position 231 | # progress: 0-7: how many pixels the characters are shifted: 0=curr_code fully displayed; 7=one pixel less than fully shifted to next_code 232 | # With multiple matrices, this function sends many NO_OP tuples, limiting the scrolling speed achievable for a whole line 233 | # scroll_message_horiz() and scroll_message_vert() are more efficient and can scroll a whole line of text faster 234 | curr_char = font[curr_code % 0x100] 235 | next_char = font[next_code % 0x100] 236 | show_char = [0,0,0,0,0,0,0,0] 237 | progress = progress % 8 238 | if matrix in MATRICES: 239 | if direction == DIR_L: 240 | for col in range(8): 241 | if col+progress < 8: 242 | show_char[col] = curr_char[col+progress] 243 | else: 244 | show_char[col] = next_char[col+progress-8] 245 | send_matrix_reg_byte(matrix, col+1, show_char[col]) 246 | elif direction == DIR_R: 247 | for col in range(8): 248 | if col >= progress: 249 | show_char[col] = curr_char[col-progress] 250 | else: 251 | show_char[col] = next_char[col-progress+8] 252 | send_matrix_reg_byte(matrix, col+1, show_char[col]) 253 | elif direction == DIR_U: 254 | for col in range(8): 255 | show_char[col] = (curr_char[col] >> progress) + (next_char[col] << (8-progress)) 256 | send_matrix_reg_byte(matrix, col+1, show_char[col]) 257 | elif direction == DIR_D: 258 | for col in range(8): 259 | show_char[col] = (curr_char[col] << progress) + (next_char[col] >> (8-progress)) 260 | send_matrix_reg_byte(matrix, col+1, show_char[col]) 261 | 262 | def static_message(message, font=DEFAULT_FONT): 263 | # Send a stationary text message to the array of MAX7219 matrices 264 | # Message will be truncated from the right to fit the array 265 | message = trim(message) 266 | for matrix in range(NUM_MATRICES-1, -1, -1): 267 | send_matrix_letter(matrix, ord(message[NUM_MATRICES - matrix - 1]), font) 268 | 269 | def scroll_message_horiz(message, repeats=0, speed=3, direction=DIR_L, font=DEFAULT_FONT, finish=True): 270 | # Scroll a text message across the array, for a specified (repeats) number of times 271 | # repeats=0 gives indefinite scrolling until script is interrupted 272 | # speed: 0-9 for practical purposes; speed does not have to integral 273 | # direction: DIR_L or DIR_R only; DIR_U & DIR_D will do nothing 274 | # finish: True/False - True ensures array is clear at end, False ends with the last column of the last character of message 275 | # still displayed on the array - this is included for completeness but rarely likely to be required in practice 276 | # Scrolling starts with message off the RHS(DIR_L)/LHS(DIR_R) of array, and ends with message off the LHS/RHS 277 | # If repeats>1, add space(s) at end of 'message' to separate the end of message & start of its repeat 278 | delay = 0.5 ** speed 279 | if repeats <= 0: 280 | indef = True 281 | else: 282 | indef = False 283 | repeats = int(repeats) 284 | if len(message) < NUM_MATRICES: 285 | message = trim(message) 286 | # Repeatedly scroll the whole message (initially 'front-padded' with blanks) until the last char appears 287 | scroll_text = "" 288 | if direction == DIR_L: 289 | scroll_text = PAD_STRING + message 290 | elif direction == DIR_R: 291 | scroll_text = message + PAD_STRING 292 | counter = repeats 293 | while (counter > 0) or indef: 294 | scroll_text_once(scroll_text, delay, direction, font) 295 | # After the first scroll, replace the blank 'front-padding' with the start of the same message 296 | if counter == repeats: 297 | if direction == DIR_L: 298 | scroll_text = message[-NUM_MATRICES:] + message 299 | elif direction == DIR_R: 300 | scroll_text = message + message[:NUM_MATRICES] 301 | counter -= 1 302 | # To finish, 'end-pad' the message with blanks and scroll the end of the message off the array 303 | if direction == DIR_L: 304 | scroll_text = message[-NUM_MATRICES:] + PAD_STRING 305 | elif direction == DIR_R: 306 | scroll_text = PAD_STRING + message[:NUM_MATRICES] 307 | scroll_text_once(scroll_text, delay, direction, font) 308 | # Above algorithm leaves the last column of the last character displayed on the array, so optionally erase it 309 | if finish: 310 | clear_all() 311 | 312 | def scroll_text_once(text, delay, direction, font): 313 | # Subroutine used by scroll_message_horiz(), scrolls text once across the array, starting & ending with test on the array 314 | # Not intended to be used as a user routine; if used, note different syntax: compulsory arguments & requires delay rather than speed 315 | length = len(text) - NUM_MATRICES 316 | start_range = [] 317 | if direction == DIR_L: 318 | start_range = range(length) 319 | elif direction == DIR_R: 320 | start_range = range(length-1, -1, -1) 321 | for start_char in start_range: 322 | for stage in range(8): 323 | for col in range(8): 324 | column_data = [] 325 | for matrix in range(NUM_MATRICES-1, -1, -1): 326 | if direction == DIR_L: 327 | this_char = font[ord(text[start_char + NUM_MATRICES - matrix - 1])] 328 | next_char = font[ord(text[start_char + NUM_MATRICES - matrix])] 329 | if col+stage < 8: 330 | column_data += [col+1, this_char[col+stage]] 331 | else: 332 | column_data += [col+1, next_char[col+stage-8]] 333 | elif direction == DIR_R: 334 | this_char = font[ord(text[start_char + NUM_MATRICES - matrix])] 335 | next_char = font[ord(text[start_char + NUM_MATRICES - matrix - 1])] 336 | if col >= stage: 337 | column_data += [col+1, this_char[col-stage]] 338 | else: 339 | column_data += [col+1, next_char[col-stage+8]] 340 | send_bytes(column_data) 341 | time.sleep(delay) 342 | 343 | def scroll_message_vert(old_message, new_message, speed=3, direction=DIR_U, font=DEFAULT_FONT, finish=True): 344 | # Transitions vertically between two different (truncated if necessary) text messages 345 | # speed: 0-9 for practical purposes; speed does not have to integral 346 | # direction: DIR_U or DIR_D only; DIR_L & DIR_R will do nothing 347 | # finish: True/False : True completely displays new_message at end, False leaves the transition one pixel short 348 | # False should be used to ensure smooth scrolling if another vertical scroll is to follow immediately 349 | delay = 0.5 ** speed 350 | old_message = trim(old_message) 351 | new_message = trim(new_message) 352 | for stage in range(8): 353 | for col in range(8): 354 | column_data=[] 355 | for matrix in range(NUM_MATRICES-1, -1, -1): 356 | this_char = font[ord(old_message[NUM_MATRICES - matrix - 1])] 357 | next_char = font[ord(new_message[NUM_MATRICES - matrix - 1])] 358 | scrolled_char = [0,0,0,0,0,0,0,0] 359 | if direction == DIR_U: 360 | scrolled_char[col] = (this_char[col] >> stage) + (next_char[col] << (8-stage)) 361 | elif direction == DIR_D: 362 | scrolled_char[col] = (this_char[col] << stage) + (next_char[col] >> (8-stage)) 363 | column_data += [col+1, scrolled_char[col]] 364 | send_bytes(column_data) 365 | time.sleep(delay) 366 | # above algorithm finishes one shift before fully displaying new_message, so optionally complete the display 367 | if finish: 368 | static_message(new_message) 369 | 370 | def wipe_message(old_message, new_message, speed=3, transition=DISSOLVE, font=DEFAULT_FONT): 371 | # Transition from one message (truncated if necessary) to another by a 'wipe' or 'dissolve' 372 | # speed: 0-9 for practical purposes; speed does not have to integral 373 | # transition: WIPE_U, WIPE_D, WIPE_L, WIPE_R, WIPE RU, WIPE_RD, WIPE_LU, WIPE_LD to wipe each letter simultaneously 374 | # in the respective direction (the diagonal directions do not give a true corner-to-corner 'wipe' effect) 375 | # or transition: DISSOLVE for a pseudo-random dissolve from old_message to new_message 376 | delay = 0.5 ** speed 377 | old_message = trim(old_message) 378 | new_message = trim(new_message) 379 | old_data = [ [], [], [], [], [], [], [], [] ] 380 | new_data = [ [], [], [], [], [], [], [], [] ] 381 | pixel = [ [], [], [], [], [], [], [], [] ] 382 | stage_range = range(8) 383 | col_range = range(8) 384 | for col in range(8): 385 | for letter in range(NUM_MATRICES): 386 | old_data[col] += [col+1] + [font[ord(old_message[letter])][col]] 387 | new_data[col] += [col+1] + [font[ord(new_message[letter])][col]] 388 | if transition == DISSOLVE: 389 | pixel[col] += [randrange(8)] 390 | elif transition == DIR_D: 391 | pixel[col] += [0] 392 | elif transition == DIR_U: 393 | pixel[col] += [7] 394 | elif transition == DIR_RU or transition == DIR_LD: 395 | pixel[col] += [col] 396 | elif transition == DIR_RD or transition == DIR_LU: 397 | pixel[col] += [7-col] 398 | elif transition == DIR_L: 399 | col_range = range(7, -1, -1) 400 | stage_range = [0] 401 | elif transition == DIR_R: 402 | stage_range = [0] 403 | for stage in stage_range: 404 | for col in col_range: 405 | if transition == DIR_L or transition == DIR_R: 406 | old_data[col]=new_data[col][:] 407 | else: 408 | for letter in range(NUM_MATRICES): 409 | mask = (0x01 << pixel[col][letter]) 410 | old_data[col][2*letter+1] = old_data[col][2*letter+1] & ~mask | new_data[col][2*letter+1] & mask 411 | if transition == DISSOLVE: 412 | pixel_jump = 3 413 | elif transition & DIR_D: 414 | pixel_jump = 1 415 | elif transition & DIR_U: 416 | pixel_jump = 7 417 | pixel[col][letter] = (pixel[col][letter] + pixel_jump)%8 418 | send_bytes(old_data[col]) 419 | if transition == DIR_L or transition == DIR_R: 420 | time.sleep(delay) 421 | time.sleep(delay) 422 | 423 | def trim(text): 424 | # Trim or pad specified text to the length of the MAX7219 array 425 | text += PAD_STRING 426 | text = text[:NUM_MATRICES] 427 | return text 428 | 429 | def gfx_set_px(g_x, g_y, state=GFX_INVERT): 430 | # Set an individual pixel in the graphics buffer to on, off, or the inverse of its previous state 431 | if (g_x in gfx_columns) and (g_y in gfx_rows): 432 | if state == GFX_ON: 433 | gfx_buffer[g_x] = gfx_buffer[g_x] | (0x01 << g_y) 434 | elif state == GFX_OFF: 435 | gfx_buffer[g_x] = (gfx_buffer[g_x] & ~(0x01 << g_y)) & 0xFF 436 | elif state == GFX_INVERT: 437 | gfx_buffer[g_x] = (gfx_buffer[g_x] ^ (0x01 << g_y)) & 0xFF 438 | 439 | def gfx_set_col(g_col, state=GFX_INVERT): 440 | # Set an entire column in the graphics buffer to on, off, or the inverse of its previous state 441 | if (g_col in gfx_columns): 442 | if state == GFX_ON: 443 | gfx_buffer[g_col] = 0xFF 444 | elif state == GFX_OFF: 445 | gfx_buffer[g_col] = 0x00 446 | elif state == GFX_INVERT: 447 | gfx_buffer[g_col] = (~gfx_buffer[g_col]) & 0xFF 448 | 449 | def gfx_set_all(state=GFX_INVERT): 450 | # Set the entire graphics buffer to on, off, or the inverse of its previous state 451 | for g_col in gfx_columns: 452 | if state == GFX_ON: 453 | gfx_buffer[g_col] = 0xFF 454 | elif state == GFX_OFF: 455 | gfx_buffer[g_col] = 0x00 456 | elif state == GFX_INVERT: 457 | gfx_buffer[g_col] = (~gfx_buffer[g_col]) & 0xFF 458 | 459 | def gfx_line(start_x, start_y, end_x, end_y, state=GFX_INVERT, incl_endpoint=GFX_ON): 460 | # Draw a staright line in the graphics buffer between the specified start- & end-points 461 | # The line can be drawn by setting each affected pixel to either on, off, or the inverse of its previous state 462 | # The final point of the line (end_x, end_y) can either be included (default) or omitted 463 | # It can be usefully omitted if drawing another line starting from this previous endpoint using GFX_INVERT 464 | start_x, end_x = int(start_x), int(end_x) 465 | start_y, end_y = int(start_y), int(end_y) 466 | len_x = end_x - start_x 467 | len_y = end_y - start_y 468 | if abs(len_x) + abs(len_y) == 0: 469 | if incl_endpoint == GFX_ON: 470 | gfx_set_px(start_x, start_y, state) 471 | elif abs(len_x) > abs(len_y): 472 | step_x = abs(len_x) / len_x 473 | for g_x in range(start_x, end_x + incl_endpoint*step_x, step_x): 474 | g_y = int(start_y + float(len_y) * (float(g_x - start_x)) / float(len_x) + 0.5) 475 | if (g_x in gfx_columns) and (g_y in gfx_rows): 476 | #if (0 <= g_x < 8*NUM_MATRICES) and (0<= g_y <8): 477 | gfx_set_px(g_x, g_y, state) 478 | else: 479 | step_y = abs(len_y) / len_y 480 | for g_y in range(start_y, end_y + incl_endpoint*step_y, step_y): 481 | g_x = int(start_x + float(len_x) * (float(g_y - start_y)) / float(len_y) + 0.5) 482 | if (g_x in gfx_columns) and (g_y in gfx_rows): 483 | #if (0 <= g_x < 8*NUM_MATRICES) and (0<= g_y <8): 484 | gfx_set_px(g_x, g_y, state) 485 | 486 | def gfx_letter(char_code, start_x=0, state=GFX_INVERT, font=DEFAULT_FONT): 487 | # Overlay one character from the specified font into the graphics buffer, at a specified horizontal position 488 | # The character is drawn by setting each affected pixel to either on, off, or the inverse of its previous state 489 | start_x = int(start_x) 490 | for l_col in range(0,8): 491 | if (l_col + start_x) in gfx_columns: 492 | #if ((l_col + start_x) >= 0) and (l_col + start_x < NUM_MATRICES*8): 493 | if state == GFX_ON: 494 | gfx_buffer[l_col + start_x] = font[char_code][l_col] 495 | elif state == GFX_OFF: 496 | gfx_buffer[l_col + start_x] = (~font[char_code][l_col]) & 0xFF 497 | elif state == GFX_INVERT: 498 | gfx_buffer[l_col + start_x] = (gfx_buffer[l_col + start_x] ^ font[char_code][l_col]) & 0xFF 499 | 500 | def gfx_sprite(sprite, start_x=0, state=GFX_INVERT): 501 | # Overlay a specified sprite into the graphics buffer, at a specified horizontal position 502 | # The sprite is drawn by setting each affected pixel to either on, off, or the inverse of its previous state 503 | # Sprite is an 8-pixel (high) x n-pixel wide pattern, expressed as a list of n bytes eg [0x99, 0x66, 0x5A, 0x66, 0x99] 504 | for l_col in range(0,len(sprite)): 505 | if ((l_col + start_x) >= 0) and (l_col + start_x < NUM_MATRICES*8): 506 | if state == GFX_ON: 507 | gfx_buffer[l_col + start_x] = sprite[l_col] 508 | elif state == GFX_OFF: 509 | gfx_buffer[l_col + start_x] = (~sprite[l_col]) & 0xFF 510 | elif state == GFX_INVERT: 511 | gfx_buffer[l_col + start_x] = (gfx_buffer[l_col + start_x] ^ sprite[l_col]) & 0xFF 512 | 513 | def gfx_scroll(direction=DIR_L, start_x=0, extent_x=8*NUM_MATRICES, start_y=0, extent_y=8, new_pixels=GFX_OFF): 514 | # Scroll the specified area of the graphics buffer by one pixel in the given direction 515 | # direction: any of DIR_U, DIR_D, DIR_L, DIR_R, DIR_LU, DIR_RU, DIR_RD, DIR_LD 516 | # Pixels outside the rectangle are unaffected; pixels scrolled outside the rectangle are discarded 517 | # The 'new' pixels in the gap created are either set to on or off depending upon the new_pixels argument 518 | start_x = max(0, min(8*NUM_MATRICES - 1 , int(start_x))) 519 | extent_x = max(0, min(8*NUM_MATRICES - start_x, int(extent_x))) 520 | start_y = max(0, min(7, int(start_y))) 521 | extent_y = max(0, min(8 - start_y, int(extent_y))) 522 | mask = 0x00 523 | for g_y in range(start_y, start_y + extent_y): 524 | mask = mask | (0x01 << g_y) 525 | if direction & DIR_L: 526 | for g_x in range(start_x, start_x + extent_x - 1): 527 | gfx_buffer[g_x] = (gfx_buffer[g_x] & ~mask) | (gfx_buffer[g_x + 1] & mask) 528 | gfx_buffer[start_x + extent_x - 1] = gfx_buffer[start_x + extent_x - 1] & ~mask 529 | if new_pixels == GFX_ON: 530 | gfx_buffer[start_x + extent_x - 1] = gfx_buffer[start_x + extent_x - 1] | mask 531 | elif direction & DIR_R: 532 | for g_x in range(start_x + extent_x - 1, start_x, -1): 533 | gfx_buffer[g_x] = (gfx_buffer[g_x] & ~mask) | (gfx_buffer[g_x - 1] & mask) 534 | gfx_buffer[start_x] = gfx_buffer[start_x] & ~mask 535 | if new_pixels == GFX_ON: 536 | gfx_buffer[start_x] = gfx_buffer[start_x] | mask 537 | if direction & DIR_U: 538 | for g_x in range(start_x, start_x + extent_x): 539 | gfx_buffer[g_x] = (gfx_buffer[g_x] & ~mask) | (((gfx_buffer[g_x] & mask) >> 1) & mask) 540 | if new_pixels == GFX_ON: 541 | gfx_buffer[g_x] = gfx_buffer[g_x] | (0x01 << (start_y + extent_y - 1)) 542 | elif direction & DIR_D: 543 | for g_x in range(start_x, start_x + extent_x): 544 | gfx_buffer[g_x] = (gfx_buffer[g_x] & ~mask) | (((gfx_buffer[g_x] & mask) << 1) & mask) 545 | if new_pixels == GFX_ON: 546 | gfx_buffer[g_x] = gfx_buffer[g_x] | (0x01 << start_y) 547 | 548 | def gfx_read_buffer(g_x, g_y): 549 | # Return the current state (on=True, off=False) of an individual pixel in the graphics buffer 550 | # Note that this buffer only reflects the operations of these gfx_ functions, since the buffer was last cleared 551 | # The buffer does not reflect the effects of other library functions such as send_matrix_letter() or (static_message() 552 | if (g_x in gfx_columns) and (g_y in gfx_rows): 553 | return (gfx_buffer[g_x] & (0x01 << g_y) != 0) 554 | 555 | def gfx_render(): 556 | # All of the above gfx_ functions only write to (or read from) a graphics buffer maintained in memory 557 | # This command sends the entire buffer to the matrix array - use it to display the effect of one or more previous gfx_ functions 558 | for g_col in range(8): 559 | column_data = [] 560 | for matrix in range(NUM_MATRICES): 561 | column_data += [g_col+1, gfx_buffer[8*matrix + g_col]] 562 | send_bytes(column_data) 563 | 564 | def init(): 565 | # Initialise all of the MAX7219 chips (see datasheet for details of registers) 566 | send_all_reg_byte(MAX7219_REG_SCANLIMIT, 7) # show all 8 digits 567 | send_all_reg_byte(MAX7219_REG_DECODEMODE, 0) # using a LED matrix (not digits) 568 | send_all_reg_byte(MAX7219_REG_DISPLAYTEST, 0) # no display test 569 | clear_all() # ensure the whole array is blank 570 | brightness(3) # set character intensity: range: 0..15 571 | send_all_reg_byte(MAX7219_REG_SHUTDOWN, 1) # not in shutdown mode (i.e start it up) 572 | gfx_set_all(GFX_OFF) # clear the graphics buffer 573 | 574 | # ----------------------------------------------------- 575 | # Library function definitions end here 576 | # The following script executes if run from command line 577 | # ------------------------------------------------------ 578 | 579 | if __name__ == "__main__": 580 | import sys 581 | # Parse arguments and attempt to correct obvious errors 582 | try: 583 | # message text 584 | message = sys.argv[1] 585 | # number of marequu repeats 586 | try: 587 | repeats = abs(int(sys.argv[2])) 588 | except (IndexError, ValueError): 589 | repeats = 0 590 | # speed of marquee scrolling 591 | try: 592 | speed = float(sys.argv[3]) 593 | except (IndexError, ValueError): 594 | speed = 3 595 | if speed < 1: 596 | speed = 3 597 | elif speed > 9: 598 | speed = 9 599 | # direction of marquee scrolling 600 | try: 601 | direction = sys.argv[4].lower() 602 | if direction in ["dir_r", "dirr", "r", "right", ">", 2]: 603 | direction = 2 # Right 604 | else: 605 | direction = 8 # Left 606 | except (IndexError, ValueError): 607 | direction = 8 # Left 608 | # font 609 | try: 610 | font = sys.argv[5].lower() 611 | if font in ["cp437", "cp437_font", "cp437font", "cp_437", "cp_437font", "cp_437_font"]: 612 | font = CP437_FONT 613 | elif font in ["sinclairs_font", "sinclairs", "sinclair_s", "sinclair_s_font", "sinclairsfont"]: 614 | font = SINCLAIRS_FONT 615 | elif font in ["lcd_font", "lcd", "lcdfont"]: 616 | font = LCD_FONT 617 | elif font in ["tiny_font", "tiny", "tinyfont"]: 618 | font = TINY_FONT 619 | # Note: if further fonts are added to MAX7219fonts.py, add suitable references to parse command line arguments here 620 | else: 621 | font = CP437_FONT 622 | except (IndexError, ValueError): 623 | font = CP437_FONT 624 | # Call the marquee function with the parsed arguments 625 | try: 626 | scroll_message_horiz(message, repeats, speed, direction, font) 627 | except KeyboardInterrupt: 628 | clear_all() 629 | except IndexError: 630 | # If no arguments given, show help text 631 | print "MAX7219array.py" 632 | print "Scrolls a message across an array of MAX7219 8x8 LED boards" 633 | print "Run syntax:" 634 | print " python MAX7219array.py message [repeats [speed [direction [font]]]]" 635 | print " or, if the file has been made executable with chmod +x MAX7219array.py :" 636 | print " ./MAX7219array.py message [repeats [speed [direction [font]]]]" 637 | print "Parameters:" 638 | print " (none) : displays this help information" 639 | print " message : any text to be displayed on the array" 640 | print " if message is more than one word, it must be enclosed in 'quotation marks'" 641 | print " Note: include blank space(s) at the end of 'message' if it is to be displayed multiple times" 642 | print " repeats (optional) : number of times the message is scrolled" 643 | print " repeats = 0 scrolls indefinitely until is pressed" 644 | print " if omitted, 'repeats' defaults to 0 (indefinitely)" 645 | print " speed (optional) : how fast the text is scrolled across the array" 646 | print " 1 (v.slow) to 9 (v.fast) inclusive (not necessarily integral)" 647 | print " if omitted, 'speed' defaults to 3" 648 | print " direction (optional) : direction the text is scrolled" 649 | print " L or R - if omitted, 'direction' defaults to L" 650 | print " font (optional) : font to use for the displayed text" 651 | print " CP437, SINCLAIRS, LCD or TINY only - default 'font' if not recognized is CP437" 652 | print "MAX7219array.py can also be imported as a module to provide a wider range of functions for driving the array" 653 | print " See documentation within the script for details of these functions, and how to setup the library and the array" 654 | 655 | 656 | -------------------------------------------------------------------------------- /MAX7219fonts.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # ----------------------------------------------------------- 4 | # Filename: MAX7219fonts.py 5 | # ----------------------------------------------------------- 6 | # Fonts data for use by the MAX7219array.py library 7 | # 8 | # v1.0 9 | # JLC Archibald 10 | # ----------------------------------------------------------- 11 | # Structure: 12 | # - each font is a list of 256 characters 13 | # - each character represented as an 8x8 binary bitmap: 14 | # - each character's data comprises an 8-byte list 15 | # - each byte represents one column of the character 16 | # - the bytes are in column order left-to-right 17 | # - the bits in each byte are in row order: MSB (bottom row) 18 | # to LSB (top row) 19 | # - some fonts only have non-zero (ie non-blank) data for 20 | # characters in the range 0x20 to 0x7F 21 | # ----------------------------------------------------------- 22 | # Each font's source is listed below, although some have had 23 | # to be transposed to the above structure 24 | # ----------------------------------------------------------- 25 | # Additional 8x8 fonts can be added as follows: 26 | # - add additional list data at the bottom of this file 27 | # - ensure that the file structure is maintained, and 28 | # that the new font data is in the same form 29 | # - include zero data for any non-repesented characters, so 30 | # that every font variable is a 256x8 nested list 31 | # - import the variable names representing the additional 32 | # fonts into the MAX7219array.py library, and into the 33 | # main script where they will be used as arguments to 34 | # the library functions 35 | # ----------------------------------------------------------- 36 | # 37 | # Fonts data begins here: 38 | # ----------------------------------------------------------- 39 | # Bit patterns for the CP437 font 40 | # See https://en.wikipedia.org/wiki/Code_page_437 41 | # Source: max7219 module by RM Hull 42 | # (see https://github.com/rm-hull/max7219) 43 | 44 | CP437_FONT = [ 45 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x00 46 | [ 0x7E, 0x81, 0x95, 0xB1, 0xB1, 0x95, 0x81, 0x7E ], # 0x01 47 | [ 0x7E, 0xFF, 0xEB, 0xCF, 0xCF, 0xEB, 0xFF, 0x7E ], # 0x02 48 | [ 0x0E, 0x1F, 0x3F, 0x7E, 0x3F, 0x1F, 0x0E, 0x00 ], # 0x03 49 | [ 0x08, 0x1C, 0x3E, 0x7F, 0x3E, 0x1C, 0x08, 0x00 ], # 0x04 50 | [ 0x18, 0xBA, 0xFF, 0xFF, 0xFF, 0xBA, 0x18, 0x00 ], # 0x05 51 | [ 0x10, 0xB8, 0xFC, 0xFF, 0xFC, 0xB8, 0x10, 0x00 ], # 0x06 52 | [ 0x00, 0x00, 0x18, 0x3C, 0x3C, 0x18, 0x00, 0x00 ], # 0x07 53 | [ 0xFF, 0xFF, 0xE7, 0xC3, 0xC3, 0xE7, 0xFF, 0xFF ], # 0x08 54 | [ 0x00, 0x3C, 0x66, 0x42, 0x42, 0x66, 0x3C, 0x00 ], # 0x09 55 | [ 0xFF, 0xC3, 0x99, 0xBD, 0xBD, 0x99, 0xC3, 0xFF ], # 0x0A 56 | [ 0x70, 0xF8, 0x88, 0x88, 0xFD, 0x7F, 0x07, 0x0F ], # 0x0B 57 | [ 0x00, 0x4E, 0x5F, 0xF1, 0xF1, 0x5F, 0x4E, 0x00 ], # 0x0C 58 | [ 0xC0, 0xE0, 0xFF, 0x7F, 0x05, 0x05, 0x07, 0x07 ], # 0x0D 59 | [ 0xC0, 0xFF, 0x7F, 0x05, 0x05, 0x65, 0x7F, 0x3F ], # 0x0E 60 | [ 0x99, 0x5A, 0x3C, 0xE7, 0xE7, 0x3C, 0x5A, 0x99 ], # 0x0F 61 | [ 0x7F, 0x3E, 0x3E, 0x1C, 0x1C, 0x08, 0x08, 0x00 ], # 0x10 62 | [ 0x08, 0x08, 0x1C, 0x1C, 0x3E, 0x3E, 0x7F, 0x00 ], # 0x11 63 | [ 0x00, 0x24, 0x66, 0xFF, 0xFF, 0x66, 0x24, 0x00 ], # 0x12 64 | [ 0x00, 0x5F, 0x5F, 0x00, 0x00, 0x5F, 0x5F, 0x00 ], # 0x13 65 | [ 0x06, 0x0F, 0x09, 0x7F, 0x7F, 0x01, 0x7F, 0x7F ], # 0x14 66 | [ 0x40, 0xDA, 0xBF, 0xA5, 0xFD, 0x59, 0x03, 0x02 ], # 0x15 67 | [ 0x00, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x00 ], # 0x16 68 | [ 0x80, 0x94, 0xB6, 0xFF, 0xFF, 0xB6, 0x94, 0x80 ], # 0x17 69 | [ 0x00, 0x04, 0x06, 0x7F, 0x7F, 0x06, 0x04, 0x00 ], # 0x18 70 | [ 0x00, 0x10, 0x30, 0x7F, 0x7F, 0x30, 0x10, 0x00 ], # 0x19 71 | [ 0x08, 0x08, 0x08, 0x2A, 0x3E, 0x1C, 0x08, 0x00 ], # 0x1A 72 | [ 0x08, 0x1C, 0x3E, 0x2A, 0x08, 0x08, 0x08, 0x00 ], # 0x1B 73 | [ 0x3C, 0x3C, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00 ], # 0x1C 74 | [ 0x08, 0x1C, 0x3E, 0x08, 0x08, 0x3E, 0x1C, 0x08 ], # 0x1D 75 | [ 0x30, 0x38, 0x3C, 0x3E, 0x3E, 0x3C, 0x38, 0x30 ], # 0x1E 76 | [ 0x06, 0x0E, 0x1E, 0x3E, 0x3E, 0x1E, 0x0E, 0x06 ], # 0x1F 77 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ' ' 78 | [ 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00, 0x00 ], # '!' 79 | [ 0x00, 0x07, 0x07, 0x00, 0x07, 0x07, 0x00, 0x00 ], # '"' 80 | [ 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 ], # '#' 81 | [ 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00, 0x00 ], # '$' 82 | [ 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 ], # '%' 83 | [ 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 ], # '&' 84 | [ 0x04, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ''' 85 | [ 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00, 0x00 ], # '(' 86 | [ 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00, 0x00 ], # ')' 87 | [ 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 ], # '*' 88 | [ 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00, 0x00 ], # '+' 89 | [ 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00, 0x00 ], # ',' 90 | [ 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 ], # '-' 91 | [ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 ], # '.' 92 | [ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 ], # '/' 93 | [ 0x3E, 0x7F, 0x71, 0x59, 0x4D, 0x7F, 0x3E, 0x00 ], # '0' 94 | [ 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00, 0x00 ], # '1' 95 | [ 0x62, 0x73, 0x59, 0x49, 0x6F, 0x66, 0x00, 0x00 ], # '2' 96 | [ 0x22, 0x63, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 ], # '3' 97 | [ 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 ], # '4' 98 | [ 0x27, 0x67, 0x45, 0x45, 0x7D, 0x39, 0x00, 0x00 ], # '5' 99 | [ 0x3C, 0x7E, 0x4B, 0x49, 0x79, 0x30, 0x00, 0x00 ], # '6' 100 | [ 0x03, 0x03, 0x71, 0x79, 0x0F, 0x07, 0x00, 0x00 ], # '7' 101 | [ 0x36, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00, 0x00 ], # '8' 102 | [ 0x06, 0x4F, 0x49, 0x69, 0x3F, 0x1E, 0x00, 0x00 ], # '9' 103 | [ 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00 ], # ':' 104 | [ 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00, 0x00 ], # ';' 105 | [ 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00, 0x00, 0x00 ], # '<' 106 | [ 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00 ], # '=' 107 | [ 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 ], # '>' 108 | [ 0x02, 0x03, 0x51, 0x59, 0x0F, 0x06, 0x00, 0x00 ], # '?' 109 | [ 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 ], # '@' 110 | [ 0x7C, 0x7E, 0x13, 0x13, 0x7E, 0x7C, 0x00, 0x00 ], # 'A' 111 | [ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 ], # 'B' 112 | [ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 ], # 'C' 113 | [ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 ], # 'D' 114 | [ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 ], # 'E' 115 | [ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 ], # 'F' 116 | [ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x73, 0x72, 0x00 ], # 'G' 117 | [ 0x7F, 0x7F, 0x08, 0x08, 0x7F, 0x7F, 0x00, 0x00 ], # 'H' 118 | [ 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00, 0x00 ], # 'I' 119 | [ 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 ], # 'J' 120 | [ 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 ], # 'K' 121 | [ 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 ], # 'L' 122 | [ 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 ], # 'M' 123 | [ 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 ], # 'N' 124 | [ 0x1C, 0x3E, 0x63, 0x41, 0x63, 0x3E, 0x1C, 0x00 ], # 'O' 125 | [ 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 ], # 'P' 126 | [ 0x1E, 0x3F, 0x21, 0x71, 0x7F, 0x5E, 0x00, 0x00 ], # 'Q' 127 | [ 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 ], # 'R' 128 | [ 0x26, 0x6F, 0x4D, 0x59, 0x73, 0x32, 0x00, 0x00 ], # 'S' 129 | [ 0x03, 0x41, 0x7F, 0x7F, 0x41, 0x03, 0x00, 0x00 ], # 'T' 130 | [ 0x7F, 0x7F, 0x40, 0x40, 0x7F, 0x7F, 0x00, 0x00 ], # 'U' 131 | [ 0x1F, 0x3F, 0x60, 0x60, 0x3F, 0x1F, 0x00, 0x00 ], # 'V' 132 | [ 0x7F, 0x7F, 0x30, 0x18, 0x30, 0x7F, 0x7F, 0x00 ], # 'W' 133 | [ 0x43, 0x67, 0x3C, 0x18, 0x3C, 0x67, 0x43, 0x00 ], # 'X' 134 | [ 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00, 0x00 ], # 'Y' 135 | [ 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 ], # 'Z' 136 | [ 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00, 0x00 ], # '[' 137 | [ 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 ], # backslash 138 | [ 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00, 0x00 ], # ']' 139 | [ 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 ], # '^' 140 | [ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 ], # '_' 141 | [ 0x00, 0x00, 0x03, 0x07, 0x04, 0x00, 0x00, 0x00 ], # '`' 142 | [ 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 ], # 'a' 143 | [ 0x41, 0x7F, 0x3F, 0x48, 0x48, 0x78, 0x30, 0x00 ], # 'b' 144 | [ 0x38, 0x7C, 0x44, 0x44, 0x6C, 0x28, 0x00, 0x00 ], # 'c' 145 | [ 0x30, 0x78, 0x48, 0x49, 0x3F, 0x7F, 0x40, 0x00 ], # 'd' 146 | [ 0x38, 0x7C, 0x54, 0x54, 0x5C, 0x18, 0x00, 0x00 ], # 'e' 147 | [ 0x48, 0x7E, 0x7F, 0x49, 0x03, 0x02, 0x00, 0x00 ], # 'f' 148 | [ 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 ], # 'g' 149 | [ 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 ], # 'h' 150 | [ 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00, 0x00 ], # 'i' 151 | [ 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00, 0x00 ], # 'j' 152 | [ 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 ], # 'k' 153 | [ 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00, 0x00 ], # 'l' 154 | [ 0x7C, 0x7C, 0x18, 0x38, 0x1C, 0x7C, 0x78, 0x00 ], # 'm' 155 | [ 0x7C, 0x7C, 0x04, 0x04, 0x7C, 0x78, 0x00, 0x00 ], # 'n' 156 | [ 0x38, 0x7C, 0x44, 0x44, 0x7C, 0x38, 0x00, 0x00 ], # 'o' 157 | [ 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 ], # 'p' 158 | [ 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 ], # 'q' 159 | [ 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x1C, 0x18, 0x00 ], # 'r' 160 | [ 0x48, 0x5C, 0x54, 0x54, 0x74, 0x24, 0x00, 0x00 ], # 's' 161 | [ 0x00, 0x04, 0x3E, 0x7F, 0x44, 0x24, 0x00, 0x00 ], # 't' 162 | [ 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 ], # 'u' 163 | [ 0x1C, 0x3C, 0x60, 0x60, 0x3C, 0x1C, 0x00, 0x00 ], # 'v' 164 | [ 0x3C, 0x7C, 0x70, 0x38, 0x70, 0x7C, 0x3C, 0x00 ], # 'w' 165 | [ 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 ], # 'x' 166 | [ 0x9C, 0xBC, 0xA0, 0xA0, 0xFC, 0x7C, 0x00, 0x00 ], # 'y' 167 | [ 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00, 0x00 ], # 'z' 168 | [ 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00, 0x00 ], # '{' 169 | [ 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00, 0x00 ], # '|' 170 | [ 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00, 0x00 ], # '}' 171 | [ 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 ], # '~' 172 | [ 0x70, 0x78, 0x4C, 0x46, 0x4C, 0x78, 0x70, 0x00 ], # 0x7F 173 | [ 0x0E, 0x9F, 0x91, 0xB1, 0xFB, 0x4A, 0x00, 0x00 ], # 0x80 174 | [ 0x3A, 0x7A, 0x40, 0x40, 0x7A, 0x7A, 0x40, 0x00 ], # 0x81 175 | [ 0x38, 0x7C, 0x54, 0x55, 0x5D, 0x19, 0x00, 0x00 ], # 0x82 176 | [ 0x02, 0x23, 0x75, 0x55, 0x55, 0x7D, 0x7B, 0x42 ], # 0x83 177 | [ 0x21, 0x75, 0x54, 0x54, 0x7D, 0x79, 0x40, 0x00 ], # 0x84 178 | [ 0x21, 0x75, 0x55, 0x54, 0x7C, 0x78, 0x40, 0x00 ], # 0x85 179 | [ 0x20, 0x74, 0x57, 0x57, 0x7C, 0x78, 0x40, 0x00 ], # 0x86 180 | [ 0x18, 0x3C, 0xA4, 0xA4, 0xE4, 0x40, 0x00, 0x00 ], # 0x87 181 | [ 0x02, 0x3B, 0x7D, 0x55, 0x55, 0x5D, 0x1B, 0x02 ], # 0x88 182 | [ 0x39, 0x7D, 0x54, 0x54, 0x5D, 0x19, 0x00, 0x00 ], # 0x89 183 | [ 0x39, 0x7D, 0x55, 0x54, 0x5C, 0x18, 0x00, 0x00 ], # 0x8A 184 | [ 0x01, 0x45, 0x7C, 0x7C, 0x41, 0x01, 0x00, 0x00 ], # 0x8B 185 | [ 0x02, 0x03, 0x45, 0x7D, 0x7D, 0x43, 0x02, 0x00 ], # 0x8C 186 | [ 0x01, 0x45, 0x7D, 0x7C, 0x40, 0x00, 0x00, 0x00 ], # 0x8D 187 | [ 0x79, 0x7D, 0x16, 0x12, 0x16, 0x7D, 0x79, 0x00 ], # 0x8E 188 | [ 0x70, 0x78, 0x2B, 0x2B, 0x78, 0x70, 0x00, 0x00 ], # 0x8F 189 | [ 0x44, 0x7C, 0x7C, 0x55, 0x55, 0x45, 0x00, 0x00 ], # 0x90 190 | [ 0x20, 0x74, 0x54, 0x54, 0x7C, 0x7C, 0x54, 0x54 ], # 0x91 191 | [ 0x7C, 0x7E, 0x0B, 0x09, 0x7F, 0x7F, 0x49, 0x00 ], # 0x92 192 | [ 0x32, 0x7B, 0x49, 0x49, 0x7B, 0x32, 0x00, 0x00 ], # 0x93 193 | [ 0x32, 0x7A, 0x48, 0x48, 0x7A, 0x32, 0x00, 0x00 ], # 0x94 194 | [ 0x32, 0x7A, 0x4A, 0x48, 0x78, 0x30, 0x00, 0x00 ], # 0x95 195 | [ 0x3A, 0x7B, 0x41, 0x41, 0x7B, 0x7A, 0x40, 0x00 ], # 0x96 196 | [ 0x3A, 0x7A, 0x42, 0x40, 0x78, 0x78, 0x40, 0x00 ], # 0x97 197 | [ 0x9A, 0xBA, 0xA0, 0xA0, 0xFA, 0x7A, 0x00, 0x00 ], # 0x98 198 | [ 0x01, 0x19, 0x3C, 0x66, 0x66, 0x3C, 0x19, 0x01 ], # 0x99 199 | [ 0x3D, 0x7D, 0x40, 0x40, 0x7D, 0x3D, 0x00, 0x00 ], # 0x9A 200 | [ 0x18, 0x3C, 0x24, 0xE7, 0xE7, 0x24, 0x24, 0x00 ], # 0x9B 201 | [ 0x68, 0x7E, 0x7F, 0x49, 0x43, 0x66, 0x20, 0x00 ], # 0x9C 202 | [ 0x2B, 0x2F, 0xFC, 0xFC, 0x2F, 0x2B, 0x00, 0x00 ], # 0x9D 203 | [ 0xFF, 0xFF, 0x09, 0x09, 0x2F, 0xF6, 0xF8, 0xA0 ], # 0x9E 204 | [ 0x40, 0xC0, 0x88, 0xFE, 0x7F, 0x09, 0x03, 0x02 ], # 0x9F 205 | [ 0x20, 0x74, 0x54, 0x55, 0x7D, 0x79, 0x40, 0x00 ], # 0xA0 206 | [ 0x00, 0x44, 0x7D, 0x7D, 0x41, 0x00, 0x00, 0x00 ], # 0xA1 207 | [ 0x30, 0x78, 0x48, 0x4A, 0x7A, 0x32, 0x00, 0x00 ], # 0xA2 208 | [ 0x38, 0x78, 0x40, 0x42, 0x7A, 0x7A, 0x40, 0x00 ], # 0xA3 209 | [ 0x7A, 0x7A, 0x0A, 0x0A, 0x7A, 0x70, 0x00, 0x00 ], # 0xA4 210 | [ 0x7D, 0x7D, 0x19, 0x31, 0x7D, 0x7D, 0x00, 0x00 ], # 0xA5 211 | [ 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x2F, 0x28, 0x00 ], # 0xA6 212 | [ 0x00, 0x26, 0x2F, 0x29, 0x2F, 0x26, 0x00, 0x00 ], # 0xA7 213 | [ 0x30, 0x78, 0x4D, 0x45, 0x60, 0x20, 0x00, 0x00 ], # 0xA8 214 | [ 0x38, 0x38, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00 ], # 0xA9 215 | [ 0x08, 0x08, 0x08, 0x08, 0x38, 0x38, 0x00, 0x00 ], # 0xAA 216 | [ 0x4F, 0x6F, 0x30, 0x18, 0xCC, 0xEE, 0xBB, 0x91 ], # 0xAB 217 | [ 0x4F, 0x6F, 0x30, 0x18, 0x6C, 0x76, 0xFB, 0xF9 ], # 0xAC 218 | [ 0x00, 0x00, 0x00, 0x7B, 0x7B, 0x00, 0x00, 0x00 ], # 0xAD 219 | [ 0x08, 0x1C, 0x36, 0x22, 0x08, 0x1C, 0x36, 0x22 ], # 0xAE 220 | [ 0x22, 0x36, 0x1C, 0x08, 0x22, 0x36, 0x1C, 0x08 ], # 0xAF 221 | [ 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00 ], # 0xB0 222 | [ 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 ], # 0xB1 223 | [ 0xDD, 0xFF, 0xAA, 0x77, 0xDD, 0xAA, 0xFF, 0x77 ], # 0xB2 224 | [ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00 ], # 0xB3 225 | [ 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x00, 0x00, 0x00 ], # 0xB4 226 | [ 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x00, 0x00, 0x00 ], # 0xB5 227 | [ 0x10, 0x10, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 ], # 0xB6 228 | [ 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x00 ], # 0xB7 229 | [ 0x14, 0x14, 0x14, 0xFC, 0xFC, 0x00, 0x00, 0x00 ], # 0xB8 230 | [ 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xFF, 0xFF, 0x00 ], # 0xB9 231 | [ 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x00 ], # 0xBA 232 | [ 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xFC, 0xFC, 0x00 ], # 0xBB 233 | [ 0x14, 0x14, 0x17, 0x17, 0x10, 0x1F, 0x1F, 0x00 ], # 0xBC 234 | [ 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x00 ], # 0xBD 235 | [ 0x14, 0x14, 0x14, 0x1F, 0x1F, 0x00, 0x00, 0x00 ], # 0xBE 236 | [ 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x00, 0x00, 0x00 ], # 0xBF 237 | [ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x10, 0x10 ], # 0xC0 238 | [ 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x10, 0x10 ], # 0xC1 239 | [ 0x10, 0x10, 0x10, 0xF0, 0xF0, 0x10, 0x10, 0x10 ], # 0xC2 240 | [ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x10, 0x10, 0x10 ], # 0xC3 241 | [ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 ], # 0xC4 242 | [ 0x10, 0x10, 0x10, 0xFF, 0xFF, 0x10, 0x10, 0x10 ], # 0xC5 243 | [ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x14, 0x14, 0x14 ], # 0xC6 244 | [ 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0x10 ], # 0xC7 245 | [ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x17, 0x17, 0x14 ], # 0xC8 246 | [ 0x00, 0x00, 0xFC, 0xFC, 0x04, 0xF4, 0xF4, 0x14 ], # 0xC9 247 | [ 0x14, 0x14, 0x17, 0x17, 0x10, 0x17, 0x17, 0x14 ], # 0xCA 248 | [ 0x14, 0x14, 0xF4, 0xF4, 0x04, 0xF4, 0xF4, 0x14 ], # 0xCB 249 | [ 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xF7, 0xF7, 0x14 ], # 0xCC 250 | [ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 ], # 0xCD 251 | [ 0x14, 0x14, 0xF7, 0xF7, 0x00, 0xF7, 0xF7, 0x14 ], # 0xCE 252 | [ 0x14, 0x14, 0x14, 0x17, 0x17, 0x14, 0x14, 0x14 ], # 0xCF 253 | [ 0x10, 0x10, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 ], # 0xD0 254 | [ 0x14, 0x14, 0x14, 0xF4, 0xF4, 0x14, 0x14, 0x14 ], # 0xD1 255 | [ 0x10, 0x10, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 ], # 0xD2 256 | [ 0x00, 0x00, 0x1F, 0x1F, 0x10, 0x1F, 0x1F, 0x10 ], # 0xD3 257 | [ 0x00, 0x00, 0x00, 0x1F, 0x1F, 0x14, 0x14, 0x14 ], # 0xD4 258 | [ 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x14, 0x14, 0x14 ], # 0xD5 259 | [ 0x00, 0x00, 0xF0, 0xF0, 0x10, 0xF0, 0xF0, 0x10 ], # 0xD6 260 | [ 0x10, 0x10, 0xFF, 0xFF, 0x10, 0xFF, 0xFF, 0x10 ], # 0xD7 261 | [ 0x14, 0x14, 0x14, 0xFF, 0xFF, 0x14, 0x14, 0x14 ], # 0xD8 262 | [ 0x10, 0x10, 0x10, 0x1F, 0x1F, 0x00, 0x00, 0x00 ], # 0xD9 263 | [ 0x00, 0x00, 0x00, 0xF0, 0xF0, 0x10, 0x10, 0x10 ], # 0xDA 264 | [ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ], # 0xDB 265 | [ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0 ], # 0xDC 266 | [ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ], # 0xDD 267 | [ 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ], # 0xDE 268 | [ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F ], # 0xDF 269 | [ 0x38, 0x7C, 0x44, 0x6C, 0x38, 0x6C, 0x44, 0x00 ], # 0xE0 270 | [ 0xFC, 0xFE, 0x2A, 0x2A, 0x3E, 0x14, 0x00, 0x00 ], # 0xE1 271 | [ 0x7E, 0x7E, 0x02, 0x02, 0x06, 0x06, 0x00, 0x00 ], # 0xE2 272 | [ 0x02, 0x7E, 0x7E, 0x02, 0x7E, 0x7E, 0x02, 0x00 ], # 0xE3 273 | [ 0x63, 0x77, 0x5D, 0x49, 0x63, 0x63, 0x00, 0x00 ], # 0xE4 274 | [ 0x38, 0x7C, 0x44, 0x7C, 0x3C, 0x04, 0x04, 0x00 ], # 0xE5 275 | [ 0x80, 0xFE, 0x7E, 0x20, 0x20, 0x3E, 0x1E, 0x00 ], # 0xE6 276 | [ 0x04, 0x06, 0x02, 0x7E, 0x7C, 0x06, 0x02, 0x00 ], # 0xE7 277 | [ 0x99, 0xBD, 0xE7, 0xE7, 0xBD, 0x99, 0x00, 0x00 ], # 0xE8 278 | [ 0x1C, 0x3E, 0x6B, 0x49, 0x6B, 0x3E, 0x1C, 0x00 ], # 0xE9 279 | [ 0x4C, 0x7E, 0x73, 0x01, 0x73, 0x7E, 0x4C, 0x00 ], # 0xEA 280 | [ 0x30, 0x78, 0x4A, 0x4F, 0x7D, 0x39, 0x00, 0x00 ], # 0xEB 281 | [ 0x18, 0x3C, 0x24, 0x3C, 0x3C, 0x24, 0x3C, 0x18 ], # 0xEC 282 | [ 0x98, 0xFC, 0x64, 0x3C, 0x3E, 0x27, 0x3D, 0x18 ], # 0xED 283 | [ 0x1C, 0x3E, 0x6B, 0x49, 0x49, 0x00, 0x00, 0x00 ], # 0xEE 284 | [ 0x7E, 0x7F, 0x01, 0x01, 0x7F, 0x7E, 0x00, 0x00 ], # 0xEF 285 | [ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x00, 0x00 ], # 0xF0 286 | [ 0x44, 0x44, 0x5F, 0x5F, 0x44, 0x44, 0x00, 0x00 ], # 0xF1 287 | [ 0x40, 0x51, 0x5B, 0x4E, 0x44, 0x40, 0x00, 0x00 ], # 0xF2 288 | [ 0x40, 0x44, 0x4E, 0x5B, 0x51, 0x40, 0x00, 0x00 ], # 0xF3 289 | [ 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x01, 0x07, 0x06 ], # 0xF4 290 | [ 0x60, 0xE0, 0x80, 0xFF, 0x7F, 0x00, 0x00, 0x00 ], # 0xF5 291 | [ 0x08, 0x08, 0x6B, 0x6B, 0x08, 0x08, 0x00, 0x00 ], # 0xF6 292 | [ 0x24, 0x36, 0x12, 0x36, 0x24, 0x36, 0x12, 0x00 ], # 0xF7 293 | [ 0x00, 0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00, 0x00 ], # 0xF8 294 | [ 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00 ], # 0xF9 295 | [ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00 ], # 0xFA 296 | [ 0x10, 0x30, 0x70, 0xC0, 0xFF, 0xFF, 0x01, 0x01 ], # 0xFB 297 | [ 0x00, 0x1F, 0x1F, 0x01, 0x1F, 0x1E, 0x00, 0x00 ], # 0xFC 298 | [ 0x00, 0x19, 0x1D, 0x17, 0x12, 0x00, 0x00, 0x00 ], # 0xFD 299 | [ 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00 ], # 0xFE 300 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFF 301 | ]; # end of CP437_FONT 302 | 303 | # ----------------------------------------------------------- 304 | # Bit patterns for SINCLAIRS_FONT 305 | # (based on the character set from the Sinclair ZX Spectrum) 306 | # Source: www.henningkarlsen.com/electronics/r_fonts.php 307 | # Transposed by JLCArchibald 308 | # Note: Only contains characters 0x20 - 0x7E inclusive 309 | # All others will appear as blanks 310 | 311 | SINCLAIRS_FONT = [ 312 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x00 313 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x01 314 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x02 315 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x03 316 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x04 317 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x05 318 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x06 319 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x07 320 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x08 321 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x09 322 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0A 323 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0B 324 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0C 325 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0D 326 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0E 327 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0F 328 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x10 329 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x11 330 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x12 331 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x13 332 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x14 333 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x15 334 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x16 335 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x17 336 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x18 337 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x19 338 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1A 339 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1B 340 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1C 341 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1D 342 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1E 343 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1F 344 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ' ' 345 | [ 0x00, 0x00, 0x00, 0x00, 0x5F, 0x00, 0x00, 0x00 ], # '!' 346 | [ 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00 ], # '"' 347 | [ 0x00, 0x24, 0x7E, 0x24, 0x24, 0x7E, 0x24, 0x00 ], # '#' 348 | [ 0x00, 0x2E, 0x2A, 0x7F, 0x2A, 0x3A, 0x00, 0x00 ], # '$' 349 | [ 0x00, 0x46, 0x26, 0x10, 0x08, 0x64, 0x62, 0x00 ], # '%' 350 | [ 0x00, 0x20, 0x54, 0x4A, 0x54, 0x20, 0x50, 0x00 ], # '&' 351 | [ 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00 ], # ''' 352 | [ 0x00, 0x00, 0x00, 0x3C, 0x42, 0x00, 0x00, 0x00 ], # '(' 353 | [ 0x00, 0x00, 0x00, 0x42, 0x3C, 0x00, 0x00, 0x00 ], # ')' 354 | [ 0x00, 0x10, 0x54, 0x38, 0x54, 0x10, 0x00, 0x00 ], # '*' 355 | [ 0x00, 0x10, 0x10, 0x7C, 0x10, 0x10, 0x00, 0x00 ], # '+' 356 | [ 0x00, 0x00, 0x00, 0x80, 0x60, 0x00, 0x00, 0x00 ], # ' 357 | [ 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00 ], # '-' 358 | [ 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00 ], # '.' 359 | [ 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00 ], # '/' 360 | [ 0x3C, 0x62, 0x52, 0x4A, 0x46, 0x3C, 0x00, 0x00 ], # '0' 361 | [ 0x44, 0x42, 0x7E, 0x40, 0x40, 0x00, 0x00, 0x00 ], # '1' 362 | [ 0x64, 0x52, 0x52, 0x52, 0x52, 0x4C, 0x00, 0x00 ], # '2' 363 | [ 0x24, 0x42, 0x42, 0x4A, 0x4A, 0x34, 0x00, 0x00 ], # '3' 364 | [ 0x30, 0x28, 0x24, 0x7E, 0x20, 0x20, 0x00, 0x00 ], # '4' 365 | [ 0x2E, 0x4A, 0x4A, 0x4A, 0x4A, 0x32, 0x00, 0x00 ], # '5' 366 | [ 0x3C, 0x4A, 0x4A, 0x4A, 0x4A, 0x30, 0x00, 0x00 ], # '6' 367 | [ 0x02, 0x02, 0x62, 0x12, 0x0A, 0x06, 0x00, 0x00 ], # '7' 368 | [ 0x34, 0x4A, 0x4A, 0x4A, 0x4A, 0x34, 0x00, 0x00 ], # '8' 369 | [ 0x0C, 0x52, 0x52, 0x52, 0x52, 0x3C, 0x00, 0x00 ], # '9' 370 | [ 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00 ], # ':' 371 | [ 0x00, 0x00, 0x80, 0x64, 0x00, 0x00, 0x00, 0x00 ], # ';' 372 | [ 0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00 ], # '<' 373 | [ 0x00, 0x28, 0x28, 0x28, 0x28, 0x28, 0x00, 0x00 ], # '=' 374 | [ 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00 ], # '>' 375 | [ 0x00, 0x04, 0x02, 0x02, 0x52, 0x0A, 0x04, 0x00 ], # '?' 376 | [ 0x00, 0x3C, 0x42, 0x5A, 0x56, 0x5A, 0x1C, 0x00 ], # '@' 377 | [ 0x7C, 0x12, 0x12, 0x12, 0x12, 0x7C, 0x00, 0x00 ], # 'A' 378 | [ 0x7E, 0x4A, 0x4A, 0x4A, 0x4A, 0x34, 0x00, 0x00 ], # 'B' 379 | [ 0x3C, 0x42, 0x42, 0x42, 0x42, 0x24, 0x00, 0x00 ], # 'C' 380 | [ 0x7E, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00 ], # 'D' 381 | [ 0x7E, 0x4A, 0x4A, 0x4A, 0x4A, 0x42, 0x00, 0x00 ], # 'E' 382 | [ 0x7E, 0x0A, 0x0A, 0x0A, 0x0A, 0x02, 0x00, 0x00 ], # 'F' 383 | [ 0x3C, 0x42, 0x42, 0x52, 0x52, 0x34, 0x00, 0x00 ], # 'G' 384 | [ 0x7E, 0x08, 0x08, 0x08, 0x08, 0x7E, 0x00, 0x00 ], # 'H' 385 | [ 0x00, 0x42, 0x42, 0x7E, 0x42, 0x42, 0x00, 0x00 ], # 'I' 386 | [ 0x30, 0x40, 0x40, 0x40, 0x40, 0x3E, 0x00, 0x00 ], # 'J' 387 | [ 0x7E, 0x08, 0x08, 0x14, 0x22, 0x40, 0x00, 0x00 ], # 'K' 388 | [ 0x7E, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00 ], # 'L' 389 | [ 0x7E, 0x04, 0x08, 0x08, 0x04, 0x7E, 0x00, 0x00 ], # 'M' 390 | [ 0x7E, 0x04, 0x08, 0x10, 0x20, 0x7E, 0x00, 0x00 ], # 'N' 391 | [ 0x3C, 0x42, 0x42, 0x42, 0x42, 0x3C, 0x00, 0x00 ], # 'O' 392 | [ 0x7E, 0x12, 0x12, 0x12, 0x12, 0x0C, 0x00, 0x00 ], # 'P' 393 | [ 0x3C, 0x42, 0x52, 0x62, 0x42, 0x3C, 0x00, 0x00 ], # 'Q' 394 | [ 0x7E, 0x12, 0x12, 0x12, 0x32, 0x4C, 0x00, 0x00 ], # 'R' 395 | [ 0x24, 0x4A, 0x4A, 0x4A, 0x4A, 0x30, 0x00, 0x00 ], # 'S' 396 | [ 0x02, 0x02, 0x02, 0x7E, 0x02, 0x02, 0x02, 0x00 ], # 'T' 397 | [ 0x3E, 0x40, 0x40, 0x40, 0x40, 0x3E, 0x00, 0x00 ], # 'U' 398 | [ 0x1E, 0x20, 0x40, 0x40, 0x20, 0x1E, 0x00, 0x00 ], # 'V' 399 | [ 0x3E, 0x40, 0x20, 0x20, 0x40, 0x3E, 0x00, 0x00 ], # 'W' 400 | [ 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00, 0x00 ], # 'X' 401 | [ 0x02, 0x04, 0x08, 0x70, 0x08, 0x04, 0x02, 0x00 ], # 'Y' 402 | [ 0x42, 0x62, 0x52, 0x4A, 0x46, 0x42, 0x00, 0x00 ], # 'Z' 403 | [ 0x00, 0x00, 0x7E, 0x42, 0x42, 0x00, 0x00, 0x00 ], # '[' 404 | [ 0x00, 0x04, 0x08, 0x10, 0x20, 0x40, 0x00, 0x00 ], # backslash 405 | [ 0x00, 0x00, 0x42, 0x42, 0x7E, 0x00, 0x00, 0x00 ], # ' 406 | [ 0x00, 0x08, 0x04, 0x7E, 0x04, 0x08, 0x00, 0x00 ], # '^' 407 | [ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00 ], # '_' 408 | [ 0x3C, 0x42, 0x99, 0xA5, 0xA5, 0x81, 0x42, 0x3C ], # '`' 409 | [ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x00 ], # 'a' 410 | [ 0x00, 0x7E, 0x48, 0x48, 0x48, 0x30, 0x00, 0x00 ], # 'b' 411 | [ 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x00, 0x00 ], # 'c' 412 | [ 0x00, 0x30, 0x48, 0x48, 0x48, 0x7E, 0x00, 0x00 ], # 'd' 413 | [ 0x00, 0x38, 0x54, 0x54, 0x54, 0x48, 0x00, 0x00 ], # 'e' 414 | [ 0x00, 0x00, 0x00, 0x7C, 0x0A, 0x02, 0x00, 0x00 ], # 'f' 415 | [ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0xA4, 0x7C, 0x00 ], # 'g' 416 | [ 0x00, 0x7E, 0x08, 0x08, 0x08, 0x70, 0x00, 0x00 ], # 'h' 417 | [ 0x00, 0x00, 0x00, 0x48, 0x7A, 0x40, 0x00, 0x00 ], # 'i' 418 | [ 0x00, 0x00, 0x40, 0x80, 0x80, 0x7A, 0x00, 0x00 ], # 'j' 419 | [ 0x00, 0x7E, 0x18, 0x24, 0x40, 0x00, 0x00, 0x00 ], # 'k' 420 | [ 0x00, 0x00, 0x00, 0x3E, 0x40, 0x40, 0x00, 0x00 ], # 'l' 421 | [ 0x00, 0x7C, 0x04, 0x78, 0x04, 0x78, 0x00, 0x00 ], # 'm' 422 | [ 0x00, 0x7C, 0x04, 0x04, 0x04, 0x78, 0x00, 0x00 ], # 'n' 423 | [ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00 ], # 'o' 424 | [ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, 0x00, 0x00 ], # 'p' 425 | [ 0x00, 0x18, 0x24, 0x24, 0x24, 0xFC, 0x80, 0x00 ], # 'q' 426 | [ 0x00, 0x00, 0x78, 0x04, 0x04, 0x04, 0x00, 0x00 ], # 'r' 427 | [ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, 0x00, 0x00 ], # 's' 428 | [ 0x00, 0x00, 0x04, 0x3E, 0x44, 0x40, 0x00, 0x00 ], # 't' 429 | [ 0x00, 0x3C, 0x40, 0x40, 0x40, 0x3C, 0x00, 0x00 ], # 'u' 430 | [ 0x00, 0x0C, 0x30, 0x40, 0x30, 0x0C, 0x00, 0x00 ], # 'v' 431 | [ 0x00, 0x3C, 0x40, 0x38, 0x40, 0x3C, 0x00, 0x00 ], # 'w' 432 | [ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00 ], # 'x' 433 | [ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, 0x00, 0x00 ], # 'y' 434 | [ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, 0x00, 0x00 ], # 'z' 435 | [ 0x00, 0x08, 0x08, 0x76, 0x42, 0x42, 0x00, 0x00 ], # '{' 436 | [ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00 ], # '|' 437 | [ 0x00, 0x42, 0x42, 0x76, 0x08, 0x08, 0x00, 0x00 ], # '}' 438 | [ 0x00, 0x00, 0x04, 0x02, 0x04, 0x02, 0x00, 0x00 ], # '~' 439 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x7F 440 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x80 441 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x81 442 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x82 443 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x83 444 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x84 445 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x85 446 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x86 447 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x87 448 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x88 449 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x89 450 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8A 451 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8B 452 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8C 453 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8D 454 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8E 455 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8F 456 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x90 457 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x91 458 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x92 459 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x93 460 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x94 461 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x95 462 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x96 463 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x97 464 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x98 465 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x99 466 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9A 467 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9B 468 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9C 469 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9D 470 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9E 471 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9F 472 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA0 473 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA1 474 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA2 475 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA3 476 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA4 477 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA5 478 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA6 479 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA7 480 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA8 481 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA9 482 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAA 483 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAB 484 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAC 485 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAD 486 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAE 487 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAF 488 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB0 489 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB1 490 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB2 491 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB3 492 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB4 493 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB5 494 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB6 495 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB7 496 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB8 497 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB9 498 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBA 499 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBB 500 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBC 501 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBD 502 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBE 503 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBF 504 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC0 505 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC1 506 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC2 507 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC3 508 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC4 509 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC5 510 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC6 511 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC7 512 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC8 513 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC9 514 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCA 515 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCB 516 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCC 517 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCD 518 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCE 519 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCF 520 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD0 521 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD1 522 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD2 523 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD3 524 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD4 525 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD5 526 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD6 527 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD7 528 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD8 529 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD9 530 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDA 531 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDB 532 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDC 533 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDD 534 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDE 535 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDF 536 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE0 537 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE1 538 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE2 539 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE3 540 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE4 541 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE5 542 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE6 543 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE7 544 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE8 545 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE9 546 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEA 547 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEB 548 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEC 549 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xED 550 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEE 551 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEF 552 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF0 553 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF1 554 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF2 555 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF3 556 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF4 557 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF5 558 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF6 559 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF7 560 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF8 561 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF9 562 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFA 563 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFB 564 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFC 565 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFD 566 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFE 567 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFF 568 | ]; # end of SINCLAIRS_FONT 569 | 570 | # ----------------------------------------------------------- 571 | # Bit patterns for LCD_FONT 572 | # Source: www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=69880 573 | # Transposed by JLCArchibald 574 | # Note: Only contains characters 0x20 - 0x7F inclusive 575 | # All others will appear as blanks 576 | 577 | LCD_FONT = [ 578 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x00 579 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x01 580 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x02 581 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x03 582 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x04 583 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x05 584 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x06 585 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x07 586 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x08 587 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x09 588 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0A 589 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0B 590 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0C 591 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0D 592 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0E 593 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0F 594 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x10 595 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x11 596 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x12 597 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x13 598 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x14 599 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x15 600 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x16 601 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x17 602 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x18 603 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x19 604 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1A 605 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1B 606 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1C 607 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1D 608 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1E 609 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1F 610 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ' ' 611 | [ 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00 ], # '!' 612 | [ 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00 ], # '"' 613 | [ 0x14, 0x7f, 0x14, 0x7f, 0x14, 0x00, 0x00, 0x00 ], # '#' 614 | [ 0x24, 0x2a, 0x7f, 0x2a, 0x12, 0x00, 0x00, 0x00 ], # '$' 615 | [ 0x23, 0x13, 0x08, 0x64, 0x62, 0x00, 0x00, 0x00 ], # '%' 616 | [ 0x36, 0x49, 0x55, 0x22, 0x50, 0x00, 0x00, 0x00 ], # '&' 617 | [ 0x00, 0x05, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ''' 618 | [ 0x00, 0x1c, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00 ], # '(' 619 | [ 0x00, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00 ], # ')' 620 | [ 0x14, 0x08, 0x3e, 0x08, 0x14, 0x00, 0x00, 0x00 ], # '*' 621 | [ 0x08, 0x08, 0x3e, 0x08, 0x08, 0x00, 0x00, 0x00 ], # '+' 622 | [ 0x00, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ' 623 | [ 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00 ], # '-' 624 | [ 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00 ], # '.' 625 | [ 0x20, 0x10, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00 ], # '/' 626 | [ 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00, 0x00, 0x00 ], # '0' 627 | [ 0x00, 0x42, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00 ], # '1' 628 | [ 0x42, 0x61, 0x51, 0x49, 0x46, 0x00, 0x00, 0x00 ], # '2' 629 | [ 0x21, 0x41, 0x45, 0x4b, 0x31, 0x00, 0x00, 0x00 ], # '3' 630 | [ 0x18, 0x14, 0x12, 0x7f, 0x10, 0x00, 0x00, 0x00 ], # '4' 631 | [ 0x27, 0x45, 0x45, 0x45, 0x39, 0x00, 0x00, 0x00 ], # '5' 632 | [ 0x3c, 0x4a, 0x49, 0x49, 0x30, 0x00, 0x00, 0x00 ], # '6' 633 | [ 0x01, 0x71, 0x09, 0x05, 0x03, 0x00, 0x00, 0x00 ], # '7' 634 | [ 0x36, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00 ], # '8' 635 | [ 0x06, 0x49, 0x49, 0x29, 0x1e, 0x00, 0x00, 0x00 ], # '9' 636 | [ 0x00, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ':' 637 | [ 0x00, 0x56, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ';' 638 | [ 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00 ], # '<' 639 | [ 0x14, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00, 0x00 ], # '=' 640 | [ 0x00, 0x41, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00 ], # '>' 641 | [ 0x02, 0x01, 0x51, 0x09, 0x06, 0x00, 0x00, 0x00 ], # '?' 642 | [ 0x32, 0x49, 0x79, 0x41, 0x3e, 0x00, 0x00, 0x00 ], # '@' 643 | [ 0x7e, 0x11, 0x11, 0x11, 0x7e, 0x00, 0x00, 0x00 ], # 'A' 644 | [ 0x7f, 0x49, 0x49, 0x49, 0x36, 0x00, 0x00, 0x00 ], # 'B' 645 | [ 0x3e, 0x41, 0x41, 0x41, 0x22, 0x00, 0x00, 0x00 ], # 'C' 646 | [ 0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00, 0x00, 0x00 ], # 'D' 647 | [ 0x7f, 0x49, 0x49, 0x49, 0x41, 0x00, 0x00, 0x00 ], # 'E' 648 | [ 0x7f, 0x09, 0x09, 0x09, 0x01, 0x00, 0x00, 0x00 ], # 'F' 649 | [ 0x3e, 0x41, 0x49, 0x49, 0x7a, 0x00, 0x00, 0x00 ], # 'G' 650 | [ 0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00, 0x00, 0x00 ], # 'H' 651 | [ 0x00, 0x41, 0x7f, 0x41, 0x00, 0x00, 0x00, 0x00 ], # 'I' 652 | [ 0x20, 0x40, 0x41, 0x3f, 0x01, 0x00, 0x00, 0x00 ], # 'J' 653 | [ 0x7f, 0x08, 0x14, 0x22, 0x41, 0x00, 0x00, 0x00 ], # 'K' 654 | [ 0x7f, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00 ], # 'L' 655 | [ 0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00, 0x00, 0x00 ], # 'M' 656 | [ 0x7f, 0x04, 0x08, 0x10, 0x7f, 0x00, 0x00, 0x00 ], # 'N' 657 | [ 0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00, 0x00, 0x00 ], # 'O' 658 | [ 0x7f, 0x09, 0x09, 0x09, 0x06, 0x00, 0x00, 0x00 ], # 'P' 659 | [ 0x3e, 0x41, 0x51, 0x21, 0x5e, 0x00, 0x00, 0x00 ], # 'Q' 660 | [ 0x7f, 0x09, 0x19, 0x29, 0x46, 0x00, 0x00, 0x00 ], # 'R' 661 | [ 0x46, 0x49, 0x49, 0x49, 0x31, 0x00, 0x00, 0x00 ], # 'S' 662 | [ 0x01, 0x01, 0x7f, 0x01, 0x01, 0x00, 0x00, 0x00 ], # 'T' 663 | [ 0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00, 0x00, 0x00 ], # 'U' 664 | [ 0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00, 0x00, 0x00 ], # 'V' 665 | [ 0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00, 0x00, 0x00 ], # 'W' 666 | [ 0x63, 0x14, 0x08, 0x14, 0x63, 0x00, 0x00, 0x00 ], # 'X' 667 | [ 0x07, 0x08, 0x70, 0x08, 0x07, 0x00, 0x00, 0x00 ], # 'Y' 668 | [ 0x61, 0x51, 0x49, 0x45, 0x43, 0x00, 0x00, 0x00 ], # 'Z' 669 | [ 0x00, 0x7f, 0x41, 0x41, 0x00, 0x00, 0x00, 0x00 ], # '[' 670 | [ 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00 ], # backslash 671 | [ 0x00, 0x41, 0x41, 0x7f, 0x00, 0x00, 0x00, 0x00 ], # ' 672 | [ 0x04, 0x02, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00 ], # '^' 673 | [ 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00 ], # '_' 674 | [ 0x00, 0x01, 0x02, 0x04, 0x00, 0x00, 0x00, 0x00 ], # '`' 675 | [ 0x20, 0x54, 0x54, 0x54, 0x78, 0x00, 0x00, 0x00 ], # 'a' 676 | [ 0x7f, 0x48, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00 ], # 'b' 677 | [ 0x38, 0x44, 0x44, 0x44, 0x20, 0x00, 0x00, 0x00 ], # 'c' 678 | [ 0x38, 0x44, 0x44, 0x48, 0x7f, 0x00, 0x00, 0x00 ], # 'd' 679 | [ 0x38, 0x54, 0x54, 0x54, 0x18, 0x00, 0x00, 0x00 ], # 'e' 680 | [ 0x08, 0x7e, 0x09, 0x01, 0x02, 0x00, 0x00, 0x00 ], # 'f' 681 | [ 0x0c, 0x52, 0x52, 0x52, 0x3e, 0x00, 0x00, 0x00 ], # 'g' 682 | [ 0x7f, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00 ], # 'h' 683 | [ 0x00, 0x44, 0x7d, 0x40, 0x00, 0x00, 0x00, 0x00 ], # 'i' 684 | [ 0x20, 0x40, 0x44, 0x3d, 0x00, 0x00, 0x00, 0x00 ], # 'j' 685 | [ 0x7f, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00 ], # 'k' 686 | [ 0x00, 0x41, 0x7f, 0x40, 0x00, 0x00, 0x00, 0x00 ], # 'l' 687 | [ 0x7c, 0x04, 0x18, 0x04, 0x78, 0x00, 0x00, 0x00 ], # 'm' 688 | [ 0x7c, 0x08, 0x04, 0x04, 0x78, 0x00, 0x00, 0x00 ], # 'n' 689 | [ 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00 ], # 'o' 690 | [ 0x7c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00 ], # 'p' 691 | [ 0x08, 0x14, 0x14, 0x18, 0x7c, 0x00, 0x00, 0x00 ], # 'q' 692 | [ 0x7c, 0x08, 0x04, 0x04, 0x08, 0x00, 0x00, 0x00 ], # 'r' 693 | [ 0x48, 0x54, 0x54, 0x54, 0x20, 0x00, 0x00, 0x00 ], # 's' 694 | [ 0x04, 0x3f, 0x44, 0x40, 0x20, 0x00, 0x00, 0x00 ], # 't' 695 | [ 0x3c, 0x40, 0x40, 0x20, 0x7c, 0x00, 0x00, 0x00 ], # 'u' 696 | [ 0x1c, 0x20, 0x40, 0x20, 0x1c, 0x00, 0x00, 0x00 ], # 'v' 697 | [ 0x3c, 0x40, 0x30, 0x40, 0x3c, 0x00, 0x00, 0x00 ], # 'w' 698 | [ 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00 ], # 'x' 699 | [ 0x0c, 0x50, 0x50, 0x50, 0x3c, 0x00, 0x00, 0x00 ], # 'y' 700 | [ 0x44, 0x64, 0x54, 0x4c, 0x44, 0x00, 0x00, 0x00 ], # 'z' 701 | [ 0x00, 0x08, 0x36, 0x41, 0x00, 0x00, 0x00, 0x00 ], # '{' 702 | [ 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00 ], # '|' 703 | [ 0x00, 0x41, 0x36, 0x08, 0x00, 0x00, 0x00, 0x00 ], # '}' 704 | [ 0x10, 0x08, 0x08, 0x10, 0x08, 0x00, 0x00, 0x00 ], # '~' 705 | [ 0x00, 0x00, 0x02, 0x05, 0x02, 0x00, 0x00, 0x00 ], # 0x7F 706 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x80 707 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x81 708 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x82 709 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x83 710 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x84 711 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x85 712 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x86 713 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x87 714 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x88 715 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x89 716 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8A 717 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8B 718 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8C 719 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8D 720 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8E 721 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8F 722 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x90 723 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x91 724 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x92 725 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x93 726 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x94 727 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x95 728 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x96 729 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x97 730 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x98 731 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x99 732 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9A 733 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9B 734 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9C 735 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9D 736 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9E 737 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9F 738 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA0 739 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA1 740 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA2 741 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA3 742 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA4 743 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA5 744 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA6 745 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA7 746 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA8 747 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA9 748 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAA 749 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAB 750 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAC 751 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAD 752 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAE 753 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAF 754 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB0 755 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB1 756 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB2 757 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB3 758 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB4 759 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB5 760 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB6 761 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB7 762 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB8 763 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB9 764 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBA 765 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBB 766 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBC 767 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBD 768 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBE 769 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBF 770 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC0 771 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC1 772 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC2 773 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC3 774 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC4 775 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC5 776 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC6 777 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC7 778 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC8 779 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC9 780 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCA 781 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCB 782 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCC 783 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCD 784 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCE 785 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCF 786 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD0 787 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD1 788 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD2 789 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD3 790 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD4 791 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD5 792 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD6 793 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD7 794 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD8 795 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD9 796 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDA 797 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDB 798 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDC 799 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDD 800 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDE 801 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDF 802 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE0 803 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE1 804 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE2 805 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE3 806 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE4 807 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE5 808 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE6 809 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE7 810 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE8 811 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE9 812 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEA 813 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEB 814 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEC 815 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xED 816 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEE 817 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEF 818 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF0 819 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF1 820 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF2 821 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF3 822 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF4 823 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF5 824 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF6 825 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF7 826 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF8 827 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF9 828 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFA 829 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFB 830 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFC 831 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFD 832 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFE 833 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFF 834 | ]; # end of LCD_FONT 835 | 836 | # ----------------------------------------------------------- 837 | # Bit patterns for TINY_FONT 838 | # Source: http://www.henningkarlsen.com/electronics/r_fonts.php 839 | # Transposed by JLCArchibald 840 | # Note: Only contains characters 0x20 - 0x7E inclusive 841 | # All others will appear as blanks 842 | 843 | TINY_FONT = [ 844 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x00 845 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x01 846 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x02 847 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x03 848 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x04 849 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x05 850 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x06 851 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x07 852 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x08 853 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x09 854 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0A 855 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0B 856 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0C 857 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0D 858 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0E 859 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x0F 860 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x10 861 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x11 862 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x12 863 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x13 864 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x14 865 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x15 866 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x16 867 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x17 868 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x18 869 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x19 870 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1A 871 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1B 872 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1C 873 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1D 874 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1E 875 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x1F 876 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # ' ' 877 | [ 0x00, 0x00, 0x06, 0x5F, 0x5F, 0x06, 0x00, 0x00 ], # '!' 878 | [ 0x00, 0x03, 0x07, 0x00, 0x00, 0x07, 0x03, 0x00 ], # '"' 879 | [ 0x14, 0x7F, 0x7F, 0x14, 0x7F, 0x7F, 0x14, 0x00 ], # '#' 880 | [ 0x00, 0x24, 0x2E, 0x6B, 0x6B, 0x3A, 0x12, 0x00 ], # '$' 881 | [ 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62, 0x00 ], # '%' 882 | [ 0x30, 0x7A, 0x4F, 0x5D, 0x37, 0x7A, 0x48, 0x00 ], # '&' 883 | [ 0x00, 0x00, 0x04, 0x07, 0x03, 0x00, 0x00, 0x00 ], # ''' 884 | [ 0x00, 0x00, 0x1C, 0x3E, 0x63, 0x41, 0x00, 0x00 ], # '(' 885 | [ 0x00, 0x00, 0x41, 0x63, 0x3E, 0x1C, 0x00, 0x00 ], # ')' 886 | [ 0x08, 0x2A, 0x3E, 0x1C, 0x1C, 0x3E, 0x2A, 0x08 ], # '*' 887 | [ 0x00, 0x08, 0x08, 0x3E, 0x3E, 0x08, 0x08, 0x00 ], # '+' 888 | [ 0x00, 0x00, 0x80, 0xE0, 0x60, 0x00, 0x00, 0x00 ], # ' 889 | [ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00 ], # '-' 890 | [ 0x00, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00 ], # '.' 891 | [ 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00 ], # '/' 892 | [ 0x3E, 0x7F, 0x51, 0x49, 0x45, 0x7F, 0x3E, 0x00 ], # '0' 893 | [ 0x00, 0x40, 0x42, 0x7F, 0x7F, 0x40, 0x40, 0x00 ], # '1' 894 | [ 0x42, 0x63, 0x71, 0x59, 0x49, 0x6F, 0x66, 0x00 ], # '2' 895 | [ 0x22, 0x63, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00 ], # '3' 896 | [ 0x18, 0x1C, 0x16, 0x53, 0x7F, 0x7F, 0x50, 0x00 ], # '4' 897 | [ 0x2F, 0x6F, 0x49, 0x49, 0x49, 0x79, 0x31, 0x00 ], # '5' 898 | [ 0x3C, 0x7E, 0x4B, 0x49, 0x49, 0x78, 0x30, 0x00 ], # '6' 899 | [ 0x03, 0x03, 0x71, 0x79, 0x0D, 0x07, 0x03, 0x00 ], # '7' 900 | [ 0x36, 0x7F, 0x49, 0x49, 0x49, 0x7F, 0x36, 0x00 ], # '8' 901 | [ 0x06, 0x4F, 0x49, 0x49, 0x69, 0x3F, 0x1E, 0x00 ], # '9' 902 | [ 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00 ], # ':' 903 | [ 0x00, 0x00, 0x80, 0xE6, 0x66, 0x00, 0x00, 0x00 ], # ';' 904 | [ 0x00, 0x00, 0x08, 0x1C, 0x36, 0x63, 0x41, 0x00 ], # '<' 905 | [ 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00 ], # '=' 906 | [ 0x00, 0x41, 0x63, 0x36, 0x1C, 0x08, 0x00, 0x00 ], # '>' 907 | [ 0x02, 0x03, 0x01, 0x59, 0x5D, 0x07, 0x02, 0x00 ], # '?' 908 | [ 0x3E, 0x7F, 0x41, 0x5D, 0x5D, 0x1F, 0x1E, 0x00 ], # '@' 909 | [ 0x7C, 0x7E, 0x0B, 0x09, 0x0B, 0x7E, 0x7C, 0x00 ], # 'A' 910 | [ 0x41, 0x7F, 0x7F, 0x49, 0x49, 0x7F, 0x36, 0x00 ], # 'B' 911 | [ 0x1C, 0x3E, 0x63, 0x41, 0x41, 0x63, 0x22, 0x00 ], # 'C' 912 | [ 0x41, 0x7F, 0x7F, 0x41, 0x63, 0x3E, 0x1C, 0x00 ], # 'D' 913 | [ 0x41, 0x7F, 0x7F, 0x49, 0x5D, 0x41, 0x63, 0x00 ], # 'E' 914 | [ 0x41, 0x7F, 0x7F, 0x49, 0x1D, 0x01, 0x03, 0x00 ], # 'F' 915 | [ 0x1C, 0x3E, 0x63, 0x41, 0x51, 0x33, 0x72, 0x00 ], # 'G' 916 | [ 0x7F, 0x7F, 0x08, 0x08, 0x08, 0x7F, 0x7F, 0x00 ], # 'H' 917 | [ 0x00, 0x00, 0x41, 0x7F, 0x7F, 0x41, 0x00, 0x00 ], # 'I' 918 | [ 0x30, 0x70, 0x40, 0x41, 0x7F, 0x3F, 0x01, 0x00 ], # 'J' 919 | [ 0x41, 0x7F, 0x7F, 0x08, 0x1C, 0x77, 0x63, 0x00 ], # 'K' 920 | [ 0x41, 0x7F, 0x7F, 0x41, 0x40, 0x60, 0x70, 0x00 ], # 'L' 921 | [ 0x7F, 0x7F, 0x0E, 0x1C, 0x0E, 0x7F, 0x7F, 0x00 ], # 'M' 922 | [ 0x7F, 0x7F, 0x06, 0x0C, 0x18, 0x7F, 0x7F, 0x00 ], # 'N' 923 | [ 0x3E, 0x7F, 0x41, 0x41, 0x41, 0x7F, 0x3E, 0x00 ], # 'O' 924 | [ 0x41, 0x7F, 0x7F, 0x49, 0x09, 0x0F, 0x06, 0x00 ], # 'P' 925 | [ 0x3E, 0x7F, 0x41, 0x41, 0xE1, 0xFF, 0xBE, 0x00 ], # 'Q' 926 | [ 0x41, 0x7F, 0x7F, 0x09, 0x19, 0x7F, 0x66, 0x00 ], # 'R' 927 | [ 0x22, 0x67, 0x4D, 0x49, 0x59, 0x73, 0x22, 0x00 ], # 'S' 928 | [ 0x00, 0x07, 0x43, 0x7F, 0x7F, 0x43, 0x07, 0x00 ], # 'T' 929 | [ 0x3F, 0x7F, 0x40, 0x40, 0x40, 0x7F, 0x3F, 0x00 ], # 'U' 930 | [ 0x1F, 0x3F, 0x60, 0x40, 0x60, 0x3F, 0x1F, 0x00 ], # 'V' 931 | [ 0x3F, 0x7F, 0x60, 0x38, 0x60, 0x7F, 0x3F, 0x00 ], # 'W' 932 | [ 0x63, 0x77, 0x1C, 0x08, 0x1C, 0x77, 0x63, 0x00 ], # 'X' 933 | [ 0x00, 0x07, 0x4F, 0x78, 0x78, 0x4F, 0x07, 0x00 ], # 'Y' 934 | [ 0x47, 0x63, 0x71, 0x59, 0x4D, 0x67, 0x73, 0x00 ], # 'Z' 935 | [ 0x00, 0x00, 0x7F, 0x7F, 0x41, 0x41, 0x00, 0x00 ], # '[' 936 | [ 0x01, 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00 ], # backslash 937 | [ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x7F, 0x00, 0x00 ], # ' 938 | [ 0x08, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x08, 0x00 ], # '^' 939 | [ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 ], # '_' 940 | [ 0x00, 0x00, 0x01, 0x03, 0x06, 0x04, 0x00, 0x00 ], # '`' 941 | [ 0x20, 0x74, 0x54, 0x54, 0x3C, 0x78, 0x40, 0x00 ], # 'a' 942 | [ 0x41, 0x7F, 0x3F, 0x44, 0x44, 0x7C, 0x38, 0x00 ], # 'b' 943 | [ 0x38, 0x7C, 0x44, 0x44, 0x44, 0x6C, 0x28, 0x00 ], # 'c' 944 | [ 0x38, 0x7C, 0x44, 0x45, 0x3F, 0x7F, 0x40, 0x00 ], # 'd' 945 | [ 0x38, 0x7C, 0x54, 0x54, 0x54, 0x5C, 0x18, 0x00 ], # 'e' 946 | [ 0x48, 0x7E, 0x7F, 0x49, 0x09, 0x03, 0x02, 0x00 ], # 'f' 947 | [ 0x98, 0xBC, 0xA4, 0xA4, 0xF8, 0x7C, 0x04, 0x00 ], # 'g' 948 | [ 0x41, 0x7F, 0x7F, 0x08, 0x04, 0x7C, 0x78, 0x00 ], # 'h' 949 | [ 0x00, 0x00, 0x44, 0x7D, 0x7D, 0x40, 0x00, 0x00 ], # 'i' 950 | [ 0x00, 0x60, 0xE0, 0x80, 0x80, 0xFD, 0x7D, 0x00 ], # 'j' 951 | [ 0x41, 0x7F, 0x7F, 0x10, 0x38, 0x6C, 0x44, 0x00 ], # 'k' 952 | [ 0x00, 0x00, 0x41, 0x7F, 0x7F, 0x40, 0x00, 0x00 ], # 'l' 953 | [ 0x7C, 0x7C, 0x0C, 0x78, 0x0C, 0x7C, 0x78, 0x00 ], # 'm' 954 | [ 0x04, 0x7C, 0x78, 0x04, 0x04, 0x7C, 0x78, 0x00 ], # 'n' 955 | [ 0x38, 0x7C, 0x44, 0x44, 0x44, 0x7C, 0x38, 0x00 ], # 'o' 956 | [ 0x84, 0xFC, 0xF8, 0xA4, 0x24, 0x3C, 0x18, 0x00 ], # 'p' 957 | [ 0x18, 0x3C, 0x24, 0xA4, 0xF8, 0xFC, 0x84, 0x00 ], # 'q' 958 | [ 0x44, 0x7C, 0x78, 0x4C, 0x04, 0x0C, 0x08, 0x00 ], # 'r' 959 | [ 0x48, 0x5C, 0x54, 0x54, 0x54, 0x74, 0x24, 0x00 ], # 's' 960 | [ 0x04, 0x04, 0x3F, 0x7F, 0x44, 0x64, 0x20, 0x00 ], # 't' 961 | [ 0x3C, 0x7C, 0x40, 0x40, 0x3C, 0x7C, 0x40, 0x00 ], # 'u' 962 | [ 0x1C, 0x3C, 0x60, 0x40, 0x60, 0x3C, 0x1C, 0x00 ], # 'v' 963 | [ 0x3C, 0x7C, 0x60, 0x38, 0x60, 0x7C, 0x3C, 0x00 ], # 'w' 964 | [ 0x44, 0x6C, 0x38, 0x10, 0x38, 0x6C, 0x44, 0x00 ], # 'x' 965 | [ 0x9C, 0xBC, 0xA0, 0xA0, 0xA0, 0xFC, 0x7C, 0x00 ], # 'y' 966 | [ 0x00, 0x4C, 0x64, 0x74, 0x5C, 0x4C, 0x64, 0x00 ], # 'z' 967 | [ 0x00, 0x08, 0x08, 0x3E, 0x77, 0x41, 0x41, 0x00 ], # '{' 968 | [ 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00, 0x00, 0x00 ], # '|' 969 | [ 0x00, 0x41, 0x41, 0x77, 0x3E, 0x08, 0x08, 0x00 ], # '}' 970 | [ 0x02, 0x03, 0x01, 0x03, 0x02, 0x03, 0x01, 0x00 ], # '~' 971 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x7F 972 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x80 973 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x81 974 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x82 975 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x83 976 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x84 977 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x85 978 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x86 979 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x87 980 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x88 981 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x89 982 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8A 983 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8B 984 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8C 985 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8D 986 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8E 987 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x8F 988 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x90 989 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x91 990 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x92 991 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x93 992 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x94 993 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x95 994 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x96 995 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x97 996 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x98 997 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x99 998 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9A 999 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9B 1000 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9C 1001 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9D 1002 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9E 1003 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0x9F 1004 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA0 1005 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA1 1006 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA2 1007 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA3 1008 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA4 1009 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA5 1010 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA6 1011 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA7 1012 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA8 1013 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xA9 1014 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAA 1015 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAB 1016 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAC 1017 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAD 1018 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAE 1019 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xAF 1020 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB0 1021 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB1 1022 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB2 1023 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB3 1024 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB4 1025 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB5 1026 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB6 1027 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB7 1028 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB8 1029 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xB9 1030 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBA 1031 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBB 1032 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBC 1033 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBD 1034 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBE 1035 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xBF 1036 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC0 1037 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC1 1038 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC2 1039 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC3 1040 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC4 1041 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC5 1042 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC6 1043 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC7 1044 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC8 1045 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xC9 1046 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCA 1047 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCB 1048 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCC 1049 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCD 1050 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCE 1051 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xCF 1052 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD0 1053 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD1 1054 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD2 1055 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD3 1056 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD4 1057 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD5 1058 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD6 1059 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD7 1060 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD8 1061 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xD9 1062 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDA 1063 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDB 1064 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDC 1065 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDD 1066 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDE 1067 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xDF 1068 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE0 1069 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE1 1070 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE2 1071 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE3 1072 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE4 1073 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE5 1074 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE6 1075 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE7 1076 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE8 1077 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xE9 1078 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEA 1079 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEB 1080 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEC 1081 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xED 1082 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEE 1083 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xEF 1084 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF0 1085 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF1 1086 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF2 1087 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF3 1088 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF4 1089 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF5 1090 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF6 1091 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF7 1092 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF8 1093 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xF9 1094 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFA 1095 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFB 1096 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFC 1097 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFD 1098 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFE 1099 | [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ], # 0xFF 1100 | ]; # end of TINY_FONT 1101 | 1102 | # ----------------------------------------------------------- 1103 | --------------------------------------------------------------------------------