├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── _config.yml ├── icon.png ├── max7219.ts ├── pxt.json ├── test.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | built 2 | node_modules 3 | yotta_modules 4 | yotta_targets 5 | pxt_modules 6 | *.db 7 | *.tgz 8 | .header.json 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8.9.4" 4 | script: 5 | - "npm install -g pxt" 6 | - "pxt target microbit" 7 | - "pxt install" 8 | - "pxt build" 9 | sudo: false 10 | cache: 11 | directories: 12 | - npm_modules 13 | - pxt_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alan Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: deploy 2 | 3 | build: 4 | pxt build 5 | 6 | deploy: 7 | pxt deploy 8 | 9 | test: 10 | pxt test 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BBC micro:bit MakeCode editor extension for MAX7219 8x8 matrix LED modules 2 | 3 | This extension works with single or multiple MAX7219 8x8 LED matrix display modules. 4 | 5 | To import this extension, go to Advanced -> +extension and enter "MAX7219" in the search box, or copy/paste [https://github.com/alankrantas/pxt-MAX7219_8x8](https://github.com/alankrantas/pxt-MAX7219_8x8). Press enter and click the extension. 6 | 7 | ![led-matrix-display-8x8-dots-rood-max7219-bovenkant](https://user-images.githubusercontent.com/44191076/50701188-d0ba2400-1087-11e9-9588-d57f678010d7.jpg) 8 | 9 | ![img_0005](https://user-images.githubusercontent.com/44191076/50698899-3fe04a00-1081-11e9-95c8-de5ba55b44d9.JPG) 10 | 11 | ![1](https://user-images.githubusercontent.com/44191076/50700935-eda22780-1086-11e9-8d7a-0fd285bd5a2d.jpg) 12 | 13 | ## Modules Wiring 14 | 15 | For the module at the head of the chain, connect it to micro:bit as follows: 16 | 17 | * VCC -> 3.3V or 5V (both works; using 5V make the LEDs a bit brighter, which is more preferable for some people.) 18 | * GND -> GND 19 | * DIN (MOSI or MO in SPI) -> default P15 20 | * CS (LOAD pin) -> any pin you want (default P16) 21 | * CLK (SCK in SPI) -> default P13 22 | 23 | MISO or MI (default P14) is not used, but included anyway for SPI pins are reassigned together. 24 | 25 | Of course, you can reassign these SPI pins in anyway you want; just use the setup block and remember to set the correct number of matrixs. 26 | 27 | ![img_0003](https://user-images.githubusercontent.com/44191076/50699442-d95c2b80-1082-11e9-8f68-9f0b0a47eeb4.JPG) 28 | 29 | The rest of the modules (if any) are connected as follows: 30 | 31 | ![untitled sketch_bb](https://user-images.githubusercontent.com/44191076/51085259-ae07c980-1771-11e9-8b82-60d474c336fd.jpg) 32 | 33 | It's basicly the same as the first one, except all module's DIN connects to DOUT on the previous one. Be noted that in the wiring picture above the order of the pins are slightly different (for example, CS and CLK) from the module I used. 34 | 35 | In my test the 3.3V power from micro:bit itself (90mA) is sufficient to power 4 chained MAX7219 modules. You may need more for a longer matrix chain. 36 | 37 | ## Index of Modules 38 | 39 | This extension assumes that you arrange single MAX7219 modules as a "chain", that they linked into a larger horizonal LED display. 40 | 41 | For linked individual matrix modules, the one directly connected to micro:bit has the highest index number (total number - 1), and the furthest one (far right) has index of 0. You can use the index number to print something onto a specific module. 42 | 43 | ![img_0004](https://user-images.githubusercontent.com/44191076/50699988-5e941000-1084-11e9-841e-5ff173872540.JPG) 44 | 45 | ## Matrix Rotation/Reverse Printing Order 46 | 47 | Some people use the 4-in-1 MAX7219 modules, which are 4 matrixs already linked together, but wired in different directions and/or order. 48 | 49 | ![max7219-dot - main-500x500](https://user-images.githubusercontent.com/44191076/53904356-d2e93080-4080-11e9-96bd-c1c3e5111a4b.jpg) 50 | 51 | You can choose to rotate and reverse the display by using the following block in the advanced section: 52 | 53 | ![1](https://user-images.githubusercontent.com/44191076/54478164-47268f80-484a-11e9-98de-76c1406e43e3.jpg) 54 | 55 | Warning: the extra rotation/reverse calculating process slow down the text scrolling/refreshing speed. You may have to reduce the scrolling delay time to 0. 56 | 57 | ## Text Scrolling 58 | 59 | There are currently two built-in display modes; first is the simple text printing mode, which use the whole LED display to show or scroll a string. 60 | 61 | ![microbit-screenshot](https://user-images.githubusercontent.com/44191076/50701355-84bbaf00-1088-11e9-9744-1df09ab2f2cd.png) 62 | 63 | ```blocks 64 | MAX7219_Matrix.setup( 65 | 4, 66 | DigitalPin.P16, 67 | DigitalPin.P15, 68 | DigitalPin.P14, 69 | DigitalPin.P13 70 | ) 71 | basic.forever(function () { 72 | MAX7219_Matrix.scrollText( 73 | "Hello world!", 74 | 75, 75 | 500 76 | ) 77 | }) 78 | ``` 79 | 80 | ![img_0002](https://user-images.githubusercontent.com/44191076/50700052-88e5cd80-1084-11e9-843f-2fa339c39b6f.JPG) 81 | 82 | The scrolling text block shows the whole sentence by scrolling it from right to left, speed adjustable. However, the program will not contiune to do anything until scrolling is finished. 83 | 84 | Be noted that if you put in a very very long string, the micro:bit may run out of memory and show the error code of 20. 85 | 86 | ## Text Printing 87 | 88 | Next, the display text block prints words on the LED display without (perceivable) delays, and you can choose offset (the starting point along the LED display, from -8 to the end of line). This is more sutiable for very short texts or characters, and you can print them seperatly along the LED display. (You will have to set the clear screen option to false.) 89 | 90 | You can also print a custom character or image on the LED display. Use [this 8x8 LED generator](http://robojax.com/learn/arduino/8x8LED/) (right side is "up") and copy the byte array as input string. Paste the text in the block you find in "more" section; it would transform the text into a number array which can be used to print special characters. 91 | 92 | ![3](https://user-images.githubusercontent.com/44191076/50700687-2261af00-1086-11e9-8451-aff7c771dc64.jpg) 93 | 94 | ![microbit-screenshot 3](https://user-images.githubusercontent.com/44191076/50702213-31972b80-108b-11e9-928e-9e4a991c5dbb.png) 95 | 96 | ```blocks 97 | let ChstomChr: number[] = [] 98 | MAX7219_Matrix.setup( 99 | 4, 100 | DigitalPin.P16, 101 | DigitalPin.P15, 102 | DigitalPin.P14, 103 | DigitalPin.P13 104 | ) 105 | ChstomChr = MAX7219_Matrix.getCustomCharacterArray( 106 | "B00100000,B01000000,B10000110,B10000000,B10000000,B10000110,B01000000,B00100000" 107 | ) 108 | MAX7219_Matrix.displayCustomCharacter( 109 | ChstomChr, 110 | 0, 111 | true 112 | ) 113 | ``` 114 | 115 | ![img_0001](https://user-images.githubusercontent.com/44191076/50700621-ff36ff80-1085-11e9-942d-0ef1c3cef84f.JPG) 116 | 117 | So far the extension only contains a simple ASCII character library. If you input a character that's not in the library, it will not be displayed (skipped) anyway. However, you can add custom character or images into the library by using some unusual [Unicode characters](https://en.wikipedia.org/wiki/List_of_Unicode_characters) as index/tokens. 118 | 119 | There's a block that displays all the characters in the library. 120 | 121 | ## Direct Matrix Array Setting 122 | 123 | The second mode allows you to get/modify a 8x8 number array variable and use it to directly set any or all of the modules. 124 | 125 | Due to the nature of the control method of MAX7219s, it is actually harder to toggle a single LED on the 8x8 matrix. (They set one whole column at a time.) So is this mode you'll have to keep track the status of all LEDs by youself. The example below will show a anti-slash line on module 1 (second from the right). 126 | 127 | ![microbit-screenshot 2](https://user-images.githubusercontent.com/44191076/50701394-9f8e2380-1088-11e9-9d71-376778ea8d74.png) 128 | 129 | ```blocks 130 | let matrix: number[][] = [] 131 | MAX7219_Matrix.setup( 132 | 4, 133 | DigitalPin.P16, 134 | DigitalPin.P15, 135 | DigitalPin.P14, 136 | DigitalPin.P13 137 | ) 138 | matrix = MAX7219_Matrix.getEmptyMatrix() 139 | for (let index = 0; index <= 4; index++) { 140 | MAX7219_Matrix.setValueInMatrix( 141 | matrix, 142 | index, 143 | index, 144 | 1 145 | ) 146 | } 147 | MAX7219_Matrix.displayLEDsForOne( 148 | matrix, 149 | 1 150 | ) 151 | ``` 152 | 153 | It would also be easier if you modify the 8x8 array variable in JavaScript mode. 154 | 155 | ## Known Issue Combining With Bluetooth Extension 156 | 157 | If you use Bluetooth extension along with this extension, you would get error code 20 (out of memory) on your micro:bit. It's probably because the BLuetooth extension use a lot of memory and there's not enough RAM to run both. 158 | 159 | ## License 160 | 161 | MIT 162 | 163 | ## Supported targets 164 | 165 | * for PXT/microbit 166 | (The metadata above is needed for package search.) 167 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alankrantas/pxt-MAX7219_8x8/2e882779c04f6c89150c71fc373d943dc82fc13d/icon.png -------------------------------------------------------------------------------- /max7219.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * MakeCode editor extension for single or multiple MAX7219 8x8 matrix LED modules 3 | * by Alan Wang 4 | */ 5 | 6 | //% weight=100 color=#006d19 icon="\uf00a" block="MAX7219 8x8" 7 | namespace max7219_matrix { 8 | 9 | //Registers (command) for MAX7219 10 | const _NOOP = 0 // no-op (do nothing, doesn't change current status) 11 | const _DIGIT = [1, 2, 3, 4, 5, 6, 7, 8] // digit (LED column) 12 | const _DECODEMODE = 9 // decode mode (1=on, 0-off; for 7-segment display on MAX7219, no usage here) 13 | const _INTENSITY = 10 // intensity (LED brightness level, 0-15) 14 | const _SCANLIMIT = 11 // scan limit (number of scanned digits) 15 | const _SHUTDOWN = 12 // turn on (1) or off (0) 16 | const _DISPLAYTEST = 15 // force all LEDs light up, no usage here 17 | 18 | let _pinCS = DigitalPin.P16 // LOAD pin, 0=ready to receive command, 1=command take effect 19 | let _matrixNum = 1 // number of MAX7219 matrix linked in the chain 20 | let _displayArray: number[] = [] // display array to show accross all matrixs 21 | let _rotation = 0 // rotate matrixs display for 4-in-1 modules 22 | let _reversed = false // reverse matrixs display order for 4-in-1 modules 23 | 24 | /** 25 | * Setup/reset MAX7219s. If you are using 4-in-1 module you'll need to set rotation as true. If your chain are consisted of single modules set it as false (default). 26 | */ 27 | //% block="Setup MAX7219:|Number of matrixs $num|CS(LOAD) = $cs|MOSI(DIN) = $mosi|MISO(not used) = $miso|SCK(CLK) = $sck" 28 | //% num.min=1 num.defl=1 cs.defl=DigitalPin.P16 mosi.defl=DigitalPin.P15 miso.defl=DigitalPin.P14 sck.defl=DigitalPin.P13 rotate.defl=false group="1. Setup" 29 | export function setup(num: number, cs: DigitalPin, mosi: DigitalPin, miso: DigitalPin, sck: DigitalPin) { 30 | // set internal variables 31 | _pinCS = cs 32 | _matrixNum = num 33 | // prepare display array (for displaying texts; add extra 8 columns at each side as buffers) 34 | for (let i = 0; i < (num + 2) * 8; i++) _displayArray.push(0) 35 | // set micro:bit SPI 36 | pins.spiPins(mosi, miso, sck) 37 | pins.spiFormat(8, 3) 38 | pins.spiFrequency(1000000) 39 | // initialize MAX7219s 40 | _registerAll(_SHUTDOWN, 0) // turn off 41 | _registerAll(_DISPLAYTEST, 0) // test mode off 42 | _registerAll(_DECODEMODE, 0) // decode mode off 43 | _registerAll(_SCANLIMIT, 7) // set scan limit to 7 (column 0-7) 44 | _registerAll(_INTENSITY, 15) // set brightness to 15 45 | _registerAll(_SHUTDOWN, 1) // turn on 46 | clearAll() // clear screen on all MAX7219s 47 | } 48 | 49 | /** 50 | * Rotation/reverse order options for 4-in-1 MAX7219 modules 51 | */ 52 | //% block="Rotate matrix display $rotation|Reverse printing order $reversed" rotation.defl=rotation_direction.none group="1. Setup" blockExternalInputs=true advanced=true 53 | export function for_4_in_1_modules(rotation: rotation_direction, reversed: boolean) { 54 | _rotation = rotation 55 | _reversed = reversed 56 | } 57 | 58 | /** 59 | * (internal function) write command and data to all MAX7219s 60 | */ 61 | function _registerAll(addressCode: number, data: number) { 62 | pins.digitalWritePin(_pinCS, 0) // LOAD=LOW, start to receive commands 63 | for (let i = 0; i < _matrixNum; i++) { 64 | // when a MAX7219 received a new command/data set 65 | // the previous one would be pushed to the next matrix along the chain via DOUT 66 | pins.spiWrite(addressCode) // command (8 bits) 67 | pins.spiWrite(data) //data (8 bits) 68 | } 69 | pins.digitalWritePin(_pinCS, 1) // LOAD=HIGH, commands take effect 70 | } 71 | 72 | /** 73 | * (internal function) write command and data to a specific MAX7219 (index 0=farthest on the chain) 74 | */ 75 | function _registerForOne(addressCode: number, data: number, matrixIndex: number) { 76 | if (matrixIndex <= _matrixNum - 1) { 77 | pins.digitalWritePin(_pinCS, 0) // LOAD=LOW, start to receive commands 78 | for (let i = 0; i < _matrixNum; i++) { 79 | // when a MAX7219 received a new command/data set 80 | // the previous one would be pushed to the next matrix along the chain via DOUT 81 | if (i == matrixIndex) { // send change to target 82 | pins.spiWrite(addressCode) // command (8 bits) 83 | pins.spiWrite(data) //data (8 bits) 84 | } else { // do nothing to non-targets 85 | pins.spiWrite(_NOOP) 86 | pins.spiWrite(0) 87 | } 88 | } 89 | pins.digitalWritePin(_pinCS, 1) // LOAD=HIGH, commands take effect 90 | } 91 | } 92 | 93 | /** 94 | * (internal function) rotate matrix 95 | */ 96 | function _rotateMatrix(matrix: number[][]): number[][] { 97 | let tmp = 0 98 | for (let i = 0; i < 4; i++) { 99 | for (let j = i; j < 7 - i; j++) { 100 | tmp = matrix[i][j] 101 | if (_rotation == rotation_direction.clockwise) { // clockwise 102 | matrix[i][j] = matrix[j][7 - i] 103 | matrix[j][7 - i] = matrix[7 - i][7 - j] 104 | matrix[7 - i][7 - j] = matrix[7 - j][i] 105 | matrix[7 - j][i] = tmp 106 | } else if (_rotation == rotation_direction.counterclockwise) { // counter-clockwise 107 | matrix[i][j] = matrix[7 - j][i] 108 | matrix[7 - j][i] = matrix[7 - i][7 - j] 109 | matrix[7 - i][7 - j] = matrix[j][7 - i] 110 | matrix[j][7 - i] = tmp 111 | } else if (_rotation == rotation_direction.one_eighty_degree) { // 180 degree 112 | matrix[i][j] = matrix[7 - i][7 - j] 113 | matrix[7 - i][7 - j] = tmp 114 | tmp = matrix[7 - j][i] 115 | matrix[7 - j][i] = matrix[j][7 - i] 116 | matrix[j][7 - i] = tmp 117 | } 118 | } 119 | } 120 | return matrix 121 | } 122 | 123 | /** 124 | * (internal function) get 8x8 matrix from a column array 125 | */ 126 | function _getMatrixFromColumns(columns: number[]): number[][] { 127 | let matrix: number[][] = getEmptyMatrix() 128 | for (let i = 0; i < 8; i++) { 129 | for (let j = 7; j >= 0; j--) { 130 | if (columns[i] >= 2 ** j) { 131 | columns[i] -= 2 ** j 132 | matrix[i][j] = 1 133 | } else if (columns[i] == 0) { 134 | break 135 | } 136 | } 137 | } 138 | return matrix 139 | } 140 | 141 | /** 142 | * Scroll a text accross all MAX7219 matrixs for once 143 | */ 144 | //% block="Scroll text $text|delay (ms) $delay|at the end wait (ms) $endDelay" text.defl="Hello world!" delay.min=0 delay.defl=75 endDelay.min=0 endDelay.defl=500 group="2. Display text on matrixs" blockExternalInputs=true 145 | export function scrollText(text: string, delay: number, endDelay: number) { 146 | let printPosition = _displayArray.length - 8 147 | let characters_index: number[] = [] 148 | let currentChrIndex = 0 149 | let currentFontArray: number[] = [] 150 | let nextChrCountdown = 1 151 | let chrCountdown: number[] = [] 152 | let totalScrollTime = 0 153 | // clear screen and array 154 | for (let i = 0; i < _displayArray.length; i++) _displayArray[i] = 0 155 | clearAll() 156 | // get font index of every characters and total scroll time needed 157 | for (let i = 0; i < text.length; i++) { 158 | let index = font.indexOf(text.substr(i, 1)) 159 | if (index >= 0) { 160 | characters_index.push(index) 161 | chrCountdown.push(font_matrix[index].length) 162 | totalScrollTime += font_matrix[index].length 163 | } 164 | } 165 | totalScrollTime += _matrixNum * 8 166 | // print characters into array and scroll the array 167 | for (let i = 0; i < totalScrollTime; i++) { 168 | nextChrCountdown -= 1 169 | if (currentChrIndex < characters_index.length && nextChrCountdown == 0) { 170 | // print a character just "outside" visible area 171 | currentFontArray = font_matrix[characters_index[currentChrIndex]] 172 | if (currentFontArray != null) 173 | for (let j = 0; j < currentFontArray.length; j++) 174 | _displayArray[printPosition + j] = currentFontArray[j] 175 | // wait until current character scrolled into visible area 176 | nextChrCountdown = chrCountdown[currentChrIndex] 177 | currentChrIndex += 1 178 | } 179 | // scroll array (copy all columns to the one before it) 180 | for (let j = 0; j < _displayArray.length - 1; j++) { 181 | _displayArray[j] = _displayArray[j + 1] 182 | } 183 | _displayArray[_displayArray.length - 1] = 0 184 | // write every 8 columns of display array (visible area) to each MAX7219s 185 | let matrixCountdown = _matrixNum - 1 186 | let actualMatrixIndex = 0 187 | for (let j = 8; j < _displayArray.length - 8; j += 8) { 188 | if (matrixCountdown < 0) break 189 | if (!_reversed) actualMatrixIndex = matrixCountdown 190 | else actualMatrixIndex = _matrixNum - 1 - matrixCountdown 191 | if (_rotation == rotation_direction.none) { 192 | for (let k = j; k < j + 8; k++) 193 | _registerForOne(_DIGIT[k - j], _displayArray[k], actualMatrixIndex) 194 | } else { // rotate matrix if needed 195 | let tmpColumns = [0, 0, 0, 0, 0, 0, 0, 0] 196 | let l = 0 197 | for (let k = j; k < j + 8; k++) tmpColumns[l++] = _displayArray[k] 198 | displayLEDsForOne(_getMatrixFromColumns(tmpColumns), actualMatrixIndex) 199 | } 200 | matrixCountdown-- 201 | } 202 | basic.pause(delay) 203 | } 204 | basic.pause(endDelay) 205 | } 206 | 207 | /** 208 | * Print a text accross the chain of MAX7219 matrixs at a specific spot. Offset value -8 ~ last column of matrixs. You can choose to clear the screen or not (if not it can be used to print multiple string on the MAX7219 chain). 209 | */ 210 | //% block="Display text (align left) $text|offset $offset|clear screen first $clear" text.defl="Hi!" offset.min=-8 clear.defl=true group="2. Display text on matrixs" blockExternalInputs=true 211 | export function displayText(text: string, offset: number, clear: boolean) { 212 | // clear screen and array if needed 213 | if (clear) { 214 | for (let i = 0; i < _displayArray.length; i++) _displayArray[i] = 0 215 | clearAll() 216 | } 217 | let printPosition = Math.constrain(offset, -8, _displayArray.length - 9) + 8 218 | let currentPosition = printPosition 219 | let characters_index: number[] = [] 220 | let currentChrIndex = 0 221 | let currentFontArray: number[] = [] 222 | // get font index of every characters 223 | for (let i = 0; i < text.length; i++) { 224 | let index = font.indexOf(text.substr(i, 1)) 225 | if (index >= 0) characters_index.push(index) 226 | } 227 | // print characters into array from offset position 228 | while (currentPosition < _displayArray.length - 8) { 229 | currentFontArray = font_matrix[characters_index[currentChrIndex]] 230 | if (currentFontArray != null) 231 | for (let j = 0; j < currentFontArray.length; j++) 232 | _displayArray[printPosition++] = currentFontArray[j] 233 | currentChrIndex += 1 234 | if (currentChrIndex == characters_index.length) break 235 | } 236 | // write every 8 columns of display array (visible area) to each MAX7219s 237 | let matrixCountdown = _matrixNum - 1 238 | let actualMatrixIndex = 0 239 | for (let i = 8; i < _displayArray.length - 8; i += 8) { 240 | if (matrixCountdown < 0) break 241 | if (!_reversed) actualMatrixIndex = matrixCountdown 242 | else actualMatrixIndex = _matrixNum - 1 - matrixCountdown 243 | if (_rotation == rotation_direction.none) { 244 | for (let j = i; j < i + 8; j++) 245 | _registerForOne(_DIGIT[j - i], _displayArray[j], actualMatrixIndex) 246 | } else { // rotate matrix and reverse order if needed 247 | let tmpColumns = [0, 0, 0, 0, 0, 0, 0, 0] 248 | let l = 0 249 | for (let j = i; j < i + 8; j++) tmpColumns[l++] = _displayArray[j] 250 | displayLEDsForOne(_getMatrixFromColumns(tmpColumns), actualMatrixIndex) 251 | } 252 | matrixCountdown-- 253 | } 254 | } 255 | 256 | /** 257 | * Print a text on the chain of MAX7219 matrixs and automatically align to the right. 258 | */ 259 | //% block="Display text (align right) $text|clear screen first $clear" text.defl="Hi!" clear.defl=true group="2. Display text on matrixs" blockExternalInputs=true 260 | export function displayTextAlignRight(text: string, clear: boolean) { 261 | let len = 0 262 | for (let i = 0; i < text.length; i++) { 263 | let index = font.indexOf(text.substr(i, 1)) 264 | if (index >= 0) len += font_matrix[index].length 265 | } 266 | displayText(text, _matrixNum * 8 - len, clear) 267 | } 268 | 269 | /** 270 | * Print a custom character from a number array on the chain of MAX7219 matrixs at a specific spot. Each number in the array is 0-255, the decimal version of column's byte number. Offset value -8 ~ last column of matrixs. You can choose to clear the screen or not (if not it can be used to print multiple string on the MAX7219 chain). 271 | */ 272 | //% block="Display custom character from|number array $customCharArray|offset $offset|clear screen first $clear" offset.min=-8 clear.defl=true group="2. Display text on matrixs" blockExternalInputs=true advanced=true 273 | export function displayCustomCharacter(customCharArray: number[], offset: number, clear: boolean) { 274 | // clear screen and array if needed 275 | if (clear) { 276 | for (let i = 0; i < _displayArray.length; i++) _displayArray[i] = 0 277 | clearAll() 278 | } 279 | let printPosition: number = Math.constrain(offset, -8, _displayArray.length - 9) + 8 280 | if (customCharArray != null) { 281 | // print column data to display array 282 | for (let i = 0; i < customCharArray.length; i++) 283 | _displayArray[printPosition + i] = customCharArray[i] 284 | // write every 8 columns of display array (visible area) to each MAX7219s 285 | let matrixCountdown = _matrixNum - 1 286 | let actualMatrixIndex = 0 287 | for (let i = 8; i < _displayArray.length - 8; i += 8) { 288 | if (matrixCountdown < 0) break 289 | if (!_reversed) actualMatrixIndex = matrixCountdown 290 | else actualMatrixIndex = _matrixNum - 1 - matrixCountdown 291 | if (_rotation == rotation_direction.none) { 292 | for (let j = i; j < i + 8; j++) 293 | _registerForOne(_DIGIT[j - i], _displayArray[j], actualMatrixIndex) 294 | } else { // rotate matrix and reverse order if needed 295 | let tmpColumns = [0, 0, 0, 0, 0, 0, 0, 0] 296 | let l = 0 297 | for (let j = i; j < i + 8; j++) tmpColumns[l++] = _displayArray[j] 298 | displayLEDsForOne(_getMatrixFromColumns(tmpColumns), actualMatrixIndex) 299 | } 300 | matrixCountdown-- 301 | } 302 | } 303 | } 304 | 305 | /** 306 | * Return a number array calculated from a 8x8 LED byte array (example: B00100000,B01000000,B10000110,B10000000,B10000000,B10000110,B01000000,B00100000) 307 | */ 308 | //% block="Get custom character number array|from byte-array string $text" text.defl="B00100000,B01000000,B10000110,B10000000,B10000000,B10000110,B01000000,B00100000" group="2. Display text on matrixs" blockExternalInputs=true advanced=true 309 | export function getCustomCharacterArray(text: string) { 310 | let tempTextArray: string[] = [] 311 | let resultNumberArray: number[] = [] 312 | let currentIndex = 0 313 | let currentChr = "" 314 | let currentNum = 0 315 | let columnNum = 0 316 | if (text != null && text.length >= 0) { 317 | // seperate each byte number to a string 318 | while (currentIndex < text.length) { 319 | tempTextArray.push(text.substr(currentIndex + 1, 8)) 320 | currentIndex += 10 321 | } 322 | for (let i = 0; i < tempTextArray.length; i++) { 323 | columnNum = 0 324 | // read each bit and calculate the decimal sum 325 | for (let j = tempTextArray[i].length - 1; j >= 0; j--) { 326 | currentChr = tempTextArray[i].substr(j, 1) 327 | if (currentChr == "1" || currentChr == "0") 328 | currentNum = parseInt(currentChr) 329 | else 330 | currentNum = 0 331 | columnNum += (2 ** (tempTextArray[i].length - j - 1)) * currentNum 332 | } 333 | // generate new decimal array 334 | resultNumberArray.push(columnNum) 335 | } 336 | return resultNumberArray 337 | } else { 338 | return null 339 | } 340 | } 341 | 342 | /** 343 | * Add a custom character from a number array at the end of the extension's font library. 344 | * Each number in the array is 0-255, the decimal version of column's byte number. 345 | */ 346 | //% block="Add custom character $chr|number array $customCharArray|to the extension font library" 347 | //% chr.defl="" 348 | //% blockExternalInputs=true 349 | //% group="2. Display text on matrixs" 350 | //% advanced=true 351 | export function addCustomChr(chr: string, customCharArray: number[]) { 352 | if (chr != null && chr.length == 1 && customCharArray != null) { 353 | // add new character 354 | font.push(chr) 355 | font_matrix.push(customCharArray) 356 | } 357 | } 358 | 359 | /** 360 | * Display all fonts in the extension font library 361 | */ 362 | //% block="Display all fonts at delay $delay" delay.min=0 delay.defl=200 group="2. Display text on matrixs" advanced=true 363 | export function fontDemo(delay: number) { 364 | let offsetIndex = 0 365 | clearAll() 366 | // print all characters on all matrixs 367 | for (let i = 1; i < font_matrix.length; i++) { 368 | // print two blank spaces to "reset" a matrix 369 | displayCustomCharacter(font_matrix[0], offsetIndex * 8, false) 370 | displayCustomCharacter(font_matrix[0], offsetIndex * 8 + 4, false) 371 | // print a character 372 | displayCustomCharacter(font_matrix[i], offsetIndex * 8, false) 373 | if (offsetIndex == _matrixNum - 1) offsetIndex = 0 374 | else offsetIndex += 1 375 | basic.pause(delay) 376 | } 377 | basic.pause(delay) 378 | clearAll() 379 | } 380 | 381 | /** 382 | * Turn on or off all MAX7219s 383 | */ 384 | //% block="Turn on all matrixs $status" status.defl=true group="3. Basic light control" advanced=true 385 | export function togglePower(status: boolean) { 386 | if (status) _registerAll(_SHUTDOWN, 1) 387 | else _registerAll(_SHUTDOWN, 0) 388 | } 389 | 390 | /** 391 | * Set brightness level of LEDs on all MAX7219s 392 | */ 393 | //% block="Set all brightness level $level" level.min=0 level.max=15 level.defl=15 group="3. Basic light control" 394 | export function brightnessAll(level: number) { 395 | _registerAll(_INTENSITY, level) 396 | } 397 | 398 | /** 399 | * Set brightness level of LEDs on a specific MAX7219s (index 0=farthest on the chain) 400 | */ 401 | //% block="Set brightness level $level on matrix index = $index" level.min=0 level.max=15 level.defl=15 index.min=0 group="3. Basic light control" advanced=true 402 | export function brightnessForOne(level: number, index: number) { 403 | _registerForOne(_INTENSITY, level, index) 404 | } 405 | 406 | /** 407 | * Turn on all LEDs on all MAX7219s 408 | */ 409 | //% block="Fill all LEDs" group="3. Basic light control" 410 | export function fillAll() { 411 | for (let i = 0; i < 8; i++) _registerAll(_DIGIT[i], 255) 412 | } 413 | 414 | /** 415 | * Turn on LEDs on a specific MAX7219 416 | */ 417 | //% block="Fill LEDs on matrix index = $index" index.min=0 group="3. Basic light control" advanced=true 418 | export function fillForOne(index: number) { 419 | for (let i = 0; i < 8; i++) _registerForOne(_DIGIT[i], 255, index) 420 | } 421 | 422 | /** 423 | * Turn off LEDs on all MAX7219s 424 | */ 425 | //% block="Clear all LEDs" group="3. Basic light control" 426 | export function clearAll() { 427 | for (let i = 0; i < 8; i++) _registerAll(_DIGIT[i], 0) 428 | } 429 | 430 | /** 431 | * Turn off LEDs on a specific MAX7219 (index 0=farthest on the chain) 432 | */ 433 | //% block="Clear LEDs on matrix index = $index" index.min=0 group="3. Basic light control" advanced=true 434 | export function clearForOne(index: number) { 435 | for (let i = 0; i < 8; i++) _registerForOne(_DIGIT[i], 0, index) 436 | } 437 | 438 | /** 439 | * Turn on LEDs randomly on all MAX7219s 440 | */ 441 | //% block="Randomize all LEDs" index.min=0 group="3. Basic light control" 442 | export function randomizeAll() { 443 | for (let i = 0; i < 8; i++) _registerAll(_DIGIT[i], Math.randomRange(0, 255)) 444 | } 445 | 446 | /** 447 | * Turn on LEDs randomly on a specific MAX7219 (index 0=farthest on the chain) 448 | */ 449 | //% block="Randomize LEDs on matrix index = $index" index.min=0 group="3. Basic light control" advanced=true 450 | export function randomizeForOne(index: number) { 451 | for (let i = 0; i < 8; i++) _registerForOne(_DIGIT[i], Math.randomRange(0, 255), index) 452 | } 453 | 454 | /** 455 | * Set LEDs of all MAX7219s to a pattern from a 8x8 matrix variable (index 0=farthest on the chain) 456 | */ 457 | //% block="Display 8x8 pattern $newMatrix on all matrixs" group="4. Set custom LED pattern on matrixs" advanced=true 458 | export function displayLEDsToAll(newMatrix: number[][]) { 459 | let columnValue = 0 460 | if (newMatrix != null) { 461 | if (_rotation != rotation_direction.none) newMatrix = _rotateMatrix(newMatrix) // rotate matrix if needed 462 | for (let i = 0; i < 8; i++) { 463 | if (newMatrix[i] != null) { 464 | columnValue = 0 465 | for (let j = 0; j < 8; j++) { 466 | if (newMatrix[i][j]) { 467 | // combine row 0-7 status into a byte number (0-255) 468 | columnValue += 2 ** j 469 | } 470 | } 471 | _registerAll(_DIGIT[i], columnValue) 472 | } 473 | } 474 | } 475 | } 476 | 477 | /** 478 | * Set LEDs of a specific MAX7219s to a pattern from a 8x8 number matrix variable (index 0=farthest on the chain) 479 | */ 480 | //% block="Display 8x8 pattern $newMatrix|on matrix index = $index" index.min=0 blockExternalInputs=true group="4. Set custom LED pattern on matrixs" 481 | export function displayLEDsForOne(newMatrix: number[][], index: number) { 482 | let columnValue = 0 483 | if (newMatrix != null) { 484 | if (_rotation != rotation_direction.none) newMatrix = _rotateMatrix(newMatrix) // rotate matrix if needed 485 | for (let i = 0; i < 8; i++) { 486 | if (newMatrix[i] != null) { 487 | columnValue = 0 488 | for (let j = 0; j < 8; j++) { 489 | if (newMatrix[i][j]) { 490 | // combine row 0-7 status into a byte number (0-255) 491 | columnValue += 2 ** j 492 | } 493 | } 494 | _registerForOne(_DIGIT[i], columnValue, index) 495 | } 496 | } 497 | } 498 | } 499 | 500 | /** 501 | * Return a empty 8x8 number matrix variable 502 | */ 503 | //% block="Empty 8x8 pattern" group="4. Set custom LED pattern on matrixs" 504 | export function getEmptyMatrix() { 505 | return [ 506 | [0, 0, 0, 0, 0, 0, 0, 0], 507 | [0, 0, 0, 0, 0, 0, 0, 0], 508 | [0, 0, 0, 0, 0, 0, 0, 0], 509 | [0, 0, 0, 0, 0, 0, 0, 0], 510 | [0, 0, 0, 0, 0, 0, 0, 0], 511 | [0, 0, 0, 0, 0, 0, 0, 0], 512 | [0, 0, 0, 0, 0, 0, 0, 0], 513 | [0, 0, 0, 0, 0, 0, 0, 0], 514 | ] 515 | } 516 | 517 | /** 518 | * Return a full 8x8 number matrix variable 519 | */ 520 | //% block="Full 8x8 pattern" group="4. Set custom LED pattern on matrixs" advanced=true 521 | export function getFullMatrix() { 522 | return [ 523 | [1, 1, 1, 1, 1, 1, 1, 1], 524 | [1, 1, 1, 1, 1, 1, 1, 1], 525 | [1, 1, 1, 1, 1, 1, 1, 1], 526 | [1, 1, 1, 1, 1, 1, 1, 1], 527 | [1, 1, 1, 1, 1, 1, 1, 1], 528 | [1, 1, 1, 1, 1, 1, 1, 1], 529 | [1, 1, 1, 1, 1, 1, 1, 1], 530 | [1, 1, 1, 1, 1, 1, 1, 1], 531 | ] 532 | } 533 | 534 | /** 535 | * Return a specific value from a 8x8 number matrix variable 536 | */ 537 | //% block="Get value from 8x8 pattern %matrix|x = $x y = $y" x.min=0 x.max=7 y.min=0 y.max=7 group="4. Set custom LED pattern on matrixs" blockExternalInputs=true advanced=true 538 | export function getValueFromMatrix(matrix: number[][], x: number, y: number) { 539 | return matrix[x][y] 540 | } 541 | 542 | /** 543 | * Set a specific value in a 8x8 number matrix variable 544 | */ 545 | //% block="Set 8x8 pattern %matrix|x = $x y = $y value to $value" value.min=0 value.max=1 x.min=0 x.max=7 y.min=0 y.max=7 group="4. Set custom LED pattern on matrixs" blockExternalInputs=true 546 | export function setValueInMatrix(matrix: number[][], x: number, y: number, value: number) { 547 | matrix[x][y] = value 548 | } 549 | 550 | /** 551 | * Toggle (between 0/1) a specific value in a 8x8 number matrix variable 552 | */ 553 | //% block="Toogle value in 8x8 pattern %matrix|x = $x y = $y" x.min=0 x.max=7 y.min=0 y.max=7 group="4. Set custom LED pattern on matrixs" blockExternalInputs=true advanced=true 554 | export function toogleValueInMatrix(matrix: number[][], x: number, y: number) { 555 | if (matrix[x][y] == 1) matrix[x][y] = 0 556 | else if (matrix[x][y] == 0) matrix[x][y] = 1 557 | } 558 | 559 | // ASCII fonts borrowed from https://github.com/lyle/matrix-led-font/blob/master/src/index.js 560 | 561 | let font = [" ", "!", "\"", "#", "$", "%", "&", "\'", "(", ")", 562 | "*", "+", ",", "-", ".", "/", 563 | "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 564 | ":", ";", "<", "=", ">", "?", "@", 565 | "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", 566 | "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", 567 | "[", "\\", "]", "_", "`", 568 | "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", 569 | "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", 570 | "{", "|", "}", "~", "^"] 571 | 572 | let font_matrix = [ 573 | [0b00000000, 574 | 0b00000000, 575 | 0b00000000, 576 | 0b00000000], 577 | [0b01011111, 578 | 0b00000000], 579 | [0b00000011, 580 | 0b00000000, 581 | 0b00000011, 582 | 0b00000000], 583 | [0b00010100, 584 | 0b00111110, 585 | 0b00010100, 586 | 0b00111110, 587 | 0b00010100, 588 | 0b00000000], 589 | [0b00100100, 590 | 0b01101010, 591 | 0b00101011, 592 | 0b00010010, 593 | 0b00000000], 594 | [0b01100011, 595 | 0b00010011, 596 | 0b00001000, 597 | 0b01100100, 598 | 0b01100011, 599 | 0b00000000], 600 | [0b00110110, 601 | 0b01001001, 602 | 0b01010110, 603 | 0b00100000, 604 | 0b01010000, 605 | 0b00000000], 606 | [0b00000011, 607 | 0b00000000], 608 | [0b00011100, 609 | 0b00100010, 610 | 0b01000001, 611 | 0b00000000], 612 | [0b01000001, 613 | 0b00100010, 614 | 0b00011100, 615 | 0b00000000], 616 | [0b00101000, 617 | 0b00011000, 618 | 0b00001110, 619 | 0b00011000, 620 | 0b00101000, 621 | 0b00000000], 622 | [0b00001000, 623 | 0b00001000, 624 | 0b00111110, 625 | 0b00001000, 626 | 0b00001000, 627 | 0b00000000], 628 | [0b10110000, 629 | 0b01110000, 630 | 0b00000000], 631 | [0b00001000, 632 | 0b00001000, 633 | 0b00001000], 634 | [0b01100000, 635 | 0b01100000, 636 | 0b00000000], 637 | [0b01100000, 638 | 0b00011000, 639 | 0b00000110, 640 | 0b00000001, 641 | 0b00000000], 642 | [0b00111110, 643 | 0b01000001, 644 | 0b01000001, 645 | 0b00111110, 646 | 0b00000000], 647 | [0b01000010, 648 | 0b01111111, 649 | 0b01000000, 650 | 0b00000000], 651 | [0b01100010, 652 | 0b01010001, 653 | 0b01001001, 654 | 0b01000110, 655 | 0b00000000], 656 | [0b00100010, 657 | 0b01000001, 658 | 0b01001001, 659 | 0b00110110, 660 | 0b00000000], 661 | [0b00011000, 662 | 0b00010100, 663 | 0b00010010, 664 | 0b01111111, 665 | 0b00000000], 666 | [0b00100111, 667 | 0b01000101, 668 | 0b01000101, 669 | 0b00111001, 670 | 0b00000000], 671 | [0b00111110, 672 | 0b01001001, 673 | 0b01001001, 674 | 0b00110000, 675 | 0b00000000], 676 | [0b01100001, 677 | 0b00010001, 678 | 0b00001001, 679 | 0b00000111, 680 | 0b00000000], 681 | [0b00110110, 682 | 0b01001001, 683 | 0b01001001, 684 | 0b00110110, 685 | 0b00000000], 686 | [0b00000110, 687 | 0b01001001, 688 | 0b01001001, 689 | 0b00111110, 690 | 0b00000000], 691 | [0b00010100, 692 | 0b00000000], 693 | [0b00100000, 694 | 0b00010100, 695 | 0b00000000], 696 | [0b00001000, 697 | 0b00010100, 698 | 0b00100010, 699 | 0b00000000], 700 | [0b00010100, 701 | 0b00010100, 702 | 0b00010100, 703 | 0b00000000], 704 | [0b00100010, 705 | 0b00010100, 706 | 0b00001000, 707 | 0b00000000], 708 | [0b00000010, 709 | 0b01011001, 710 | 0b00001001, 711 | 0b00000110, 712 | 0b00000000], 713 | [0b00111110, 714 | 0b01001001, 715 | 0b01010101, 716 | 0b01011101, 717 | 0b00001110, 718 | 0b00000000], 719 | [0b01111110, 720 | 0b00010001, 721 | 0b00010001, 722 | 0b01111110, 723 | 0b00000000], 724 | [0b01111111, 725 | 0b01001001, 726 | 0b01001001, 727 | 0b00110110, 728 | 0b00000000], 729 | [0b00111110, 730 | 0b01000001, 731 | 0b01000001, 732 | 0b00100010, 733 | 0b00000000], 734 | [0b01111111, 735 | 0b01000001, 736 | 0b01000001, 737 | 0b00111110, 738 | 0b00000000], 739 | [0b01111111, 740 | 0b01001001, 741 | 0b01001001, 742 | 0b01000001, 743 | 0b00000000], 744 | [0b01111111, 745 | 0b00001001, 746 | 0b00001001, 747 | 0b00000001, 748 | 0b00000000], 749 | [0b00111110, 750 | 0b01000001, 751 | 0b01001001, 752 | 0b01111010, 753 | 0b00000000], 754 | [0b01111111, 755 | 0b00001000, 756 | 0b00001000, 757 | 0b01111111, 758 | 0b00000000], 759 | [0b01000001, 760 | 0b01111111, 761 | 0b01000001, 762 | 0b00000000], 763 | [0b00110000, 764 | 0b01000000, 765 | 0b01000001, 766 | 0b00111111, 767 | 0b00000000], 768 | [0b01111111, 769 | 0b00001000, 770 | 0b00010100, 771 | 0b01100011, 772 | 0b00000000], 773 | [0b01111111, 774 | 0b01000000, 775 | 0b01000000, 776 | 0b01000000, 777 | 0b00000000], 778 | [0b01111111, 779 | 0b00000010, 780 | 0b00001100, 781 | 0b00000010, 782 | 0b01111111, 783 | 0b00000000], 784 | [0b01111111, 785 | 0b00000100, 786 | 0b00001000, 787 | 0b00010000, 788 | 0b01111111, 789 | 0b00000000], 790 | [0b00111110, 791 | 0b01000001, 792 | 0b01000001, 793 | 0b00111110, 794 | 0b00000000], 795 | [0b01111111, 796 | 0b00001001, 797 | 0b00001001, 798 | 0b00000110, 799 | 0b00000000], 800 | [0b00111110, 801 | 0b01000001, 802 | 0b01000001, 803 | 0b10111110, 804 | 0b00000000], 805 | [0b01111111, 806 | 0b00001001, 807 | 0b00001001, 808 | 0b01110110, 809 | 0b00000000], 810 | [0b01000110, 811 | 0b01001001, 812 | 0b01001001, 813 | 0b00110010, 814 | 0b00000000], 815 | [0b00000001, 816 | 0b00000001, 817 | 0b01111111, 818 | 0b00000001, 819 | 0b00000001, 820 | 0b00000000], 821 | [0b00111111, 822 | 0b01000000, 823 | 0b01000000, 824 | 0b00111111, 825 | 0b00000000], 826 | [0b00001111, 827 | 0b00110000, 828 | 0b01000000, 829 | 0b00110000, 830 | 0b00001111, 831 | 0b00000000], 832 | [0b00111111, 833 | 0b01000000, 834 | 0b00111000, 835 | 0b01000000, 836 | 0b00111111, 837 | 0b00000000], 838 | [0b01100011, 839 | 0b00010100, 840 | 0b00001000, 841 | 0b00010100, 842 | 0b01100011, 843 | 0b00000000], 844 | [0b00000111, 845 | 0b00001000, 846 | 0b01110000, 847 | 0b00001000, 848 | 0b00000111, 849 | 0b00000000], 850 | [0b01100001, 851 | 0b01010001, 852 | 0b01001001, 853 | 0b01000111, 854 | 0b00000000], 855 | [0b01111111, 856 | 0b01000001, 857 | 0b00000000], 858 | [0b00000001, 859 | 0b00000110, 860 | 0b00011000, 861 | 0b01100000, 862 | 0b00000000], 863 | [0b01000001, 864 | 0b01111111, 865 | 0b00000000], 866 | [0b01000000, 867 | 0b01000000, 868 | 0b01000000, 869 | 0b01000000, 870 | 0b00000000], 871 | [0b00000001, 872 | 0b00000010, 873 | 0b00000000], 874 | [0b00100000, 875 | 0b01010100, 876 | 0b01010100, 877 | 0b01111000, 878 | 0b00000000], 879 | [0b01111111, 880 | 0b01000100, 881 | 0b01000100, 882 | 0b00111000, 883 | 0b00000000], 884 | [0b00111000, 885 | 0b01000100, 886 | 0b01000100, 887 | 0b00101000, 888 | 0b00000000], 889 | [0b00111000, 890 | 0b01000100, 891 | 0b01000100, 892 | 0b01111111, 893 | 0b00000000], 894 | [0b00111000, 895 | 0b01010100, 896 | 0b01010100, 897 | 0b00011000, 898 | 0b00000000], 899 | [0b00000100, 900 | 0b01111110, 901 | 0b00000101, 902 | 0b00000000], 903 | [0b10011000, 904 | 0b10100100, 905 | 0b10100100, 906 | 0b01111000, 907 | 0b00000000], 908 | [0b01111111, 909 | 0b00000100, 910 | 0b00000100, 911 | 0b01111000, 912 | 0b00000000], 913 | [0b01000100, 914 | 0b01111101, 915 | 0b01000000, 916 | 0b00000000], 917 | [0b01000000, 918 | 0b10000000, 919 | 0b10000100, 920 | 0b01111101, 921 | 0b00000000], 922 | [0b01111111, 923 | 0b00010000, 924 | 0b00101000, 925 | 0b01000100, 926 | 0b00000000], 927 | [0b01000001, 928 | 0b01111111, 929 | 0b01000000, 930 | 0b00000000], 931 | [0b01111100, 932 | 0b00000100, 933 | 0b01111100, 934 | 0b00000100, 935 | 0b01111000, 936 | 0b00000000], 937 | [0b01111100, 938 | 0b00000100, 939 | 0b00000100, 940 | 0b01111000, 941 | 0b00000000], 942 | [0b00111000, 943 | 0b01000100, 944 | 0b01000100, 945 | 0b00111000, 946 | 0b00000000], 947 | [0b11111100, 948 | 0b00100100, 949 | 0b00100100, 950 | 0b00011000, 951 | 0b00000000], 952 | [0b00011000, 953 | 0b00100100, 954 | 0b00100100, 955 | 0b11111100, 956 | 0b00000000], 957 | [0b01111100, 958 | 0b00001000, 959 | 0b00000100, 960 | 0b00000100, 961 | 0b00000000], 962 | [0b01001000, 963 | 0b01010100, 964 | 0b01010100, 965 | 0b00100100, 966 | 0b00000000], 967 | [0b00000100, 968 | 0b00111111, 969 | 0b01000100, 970 | 0b00000000], 971 | [0b00111100, 972 | 0b01000000, 973 | 0b01000000, 974 | 0b01111100, 975 | 0b00000000], 976 | [0b00011100, 977 | 0b00100000, 978 | 0b01000000, 979 | 0b00100000, 980 | 0b00011100, 981 | 0b00000000], 982 | [0b00111100, 983 | 0b01000000, 984 | 0b00111100, 985 | 0b01000000, 986 | 0b00111100, 987 | 0b00000000], 988 | [0b01000100, 989 | 0b00101000, 990 | 0b00010000, 991 | 0b00101000, 992 | 0b01000100, 993 | 0b00000000], 994 | [0b10011100, 995 | 0b10100000, 996 | 0b10100000, 997 | 0b01111100, 998 | 0b00000000], 999 | [0b01100100, 1000 | 0b01010100, 1001 | 0b01001100, 1002 | 0b00000000], 1003 | [0b00001000, 1004 | 0b00110110, 1005 | 0b01000001, 1006 | 0b00000000], 1007 | [0b01111111, 1008 | 0b00000000], 1009 | [0b01000001, 1010 | 0b00110110, 1011 | 0b00001000, 1012 | 0b00000000], 1013 | [0b00001000, 1014 | 0b00000100, 1015 | 0b00001000, 1016 | 0b00000100, 1017 | 0b00000000], 1018 | [0b00000010, 1019 | 0b00000001, 1020 | 0b00000010, 1021 | 0b00000000]] 1022 | 1023 | } 1024 | 1025 | enum rotation_direction { 1026 | //% block="none" 1027 | none = 0, 1028 | //% block="clockwise" 1029 | clockwise = 1, 1030 | //% block="counter-clockwise" 1031 | counterclockwise = 2, 1032 | //% block="180-degree" 1033 | one_eighty_degree = 3, 1034 | } 1035 | -------------------------------------------------------------------------------- /pxt.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pxt-max7219_8x8", 3 | "version": "0.0.3", 4 | "description": "MakeCode editor extension for single or multiple MAX7219 8x8 matrix LED modules", 5 | "license": "MIT", 6 | "dependencies": { 7 | "core": "*" 8 | }, 9 | "files": [ 10 | "README.md", 11 | "max7219.ts" 12 | ], 13 | "testFiles": [ 14 | "test.ts" 15 | ], 16 | "public": true 17 | } 18 | -------------------------------------------------------------------------------- /test.ts: -------------------------------------------------------------------------------- 1 | MAX7219_Matrix.setup( 2 | 4, 3 | DigitalPin.P16, 4 | DigitalPin.P15, 5 | DigitalPin.P14, 6 | DigitalPin.P13 7 | ) 8 | basic.forever(function () { 9 | MAX7219_Matrix.scrollText( 10 | "Hello world!", 11 | 50, 12 | 50 13 | ) 14 | for (let index = 0; index <= 23; index++) { 15 | MAX7219_Matrix.displayCustomCharacter( 16 | MAX7219_Matrix.getCustomCharacterArray( 17 | "B00100000,B01000000,B10000110,B10000000,B10000000,B10000110,B01000000,B00100000" 18 | ), 19 | index, 20 | true 21 | ) 22 | basic.pause(50) 23 | } 24 | }) 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "noImplicitAny": true, 5 | "outDir": "built", 6 | "rootDir": "." 7 | }, 8 | "exclude": ["pxt_modules/**/*test.ts"] 9 | } 10 | --------------------------------------------------------------------------------