├── LICENSE.txt ├── README.md └── max7219.py /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Mike Causer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroPython MAX7219 8x8 LED Matrix 2 | 3 | A MicroPython library for the MAX7219 8x8 LED matrix driver, SPI interface, supports cascading and uses [framebuf](http://docs.micropython.org/en/latest/pyboard/library/framebuf.html) 4 | 5 | ## PyBoard Examples 6 | 7 | **Single 8x8 LED Matrix** 8 | 9 | ```python 10 | import max7219 11 | from machine import Pin, SPI 12 | spi = SPI(1) 13 | display = max7219.Matrix8x8(spi, Pin('X5'), 1) 14 | display.text('1',0,0,1) 15 | display.show() 16 | ``` 17 | 18 | **Chain of 4x 8x8 LED Matrices** 19 | Where the 4 is drawn on the DIN matrix. 20 | 21 | ```python 22 | import max7219 23 | from machine import Pin, SPI 24 | spi = SPI(1) 25 | display = max7219.Matrix8x8(spi, Pin('X5'), 4) 26 | display.text('1234',0,0,1) 27 | display.show() 28 | ``` 29 | 30 | **Chain of 8x 8x8 LED Matrices** 31 | Where the 8 is drawn on the DIN matrix 32 | 33 | ```python 34 | import max7219 35 | from machine import Pin, SPI 36 | spi = SPI(1) 37 | display = max7219.Matrix8x8(spi, Pin('X5'), 8) 38 | display.text('12345678',0,0,1) 39 | display.show() 40 | ``` 41 | 42 | **Framebuf shapes and text** 43 | 44 | ```python 45 | display.fill(0) 46 | display.show() 47 | 48 | display.pixel(0,0,1) 49 | display.pixel(1,1,1) 50 | display.hline(0,4,8,1) 51 | display.vline(4,0,8,1) 52 | display.line(8, 0, 16, 8, 1) 53 | display.rect(17,1,6,6,1) 54 | display.fill_rect(25,1,6,6,1) 55 | display.show() 56 | 57 | display.fill(0) 58 | display.text('dead',0,0,1) 59 | display.text('beef',32,0,1) 60 | display.show() 61 | 62 | display.fill(0) 63 | display.text('12345678',0,0,1) 64 | display.show() 65 | display.scroll(-8,0) # 23456788 66 | display.scroll(-8,0) # 34567888 67 | display.show() 68 | ``` 69 | 70 | ## ESP8266 Examples 71 | 72 | Default baud rate of 80Mhz was introducing errors, dropped from 10Mhz and it works consistently. 73 | 74 | ```python 75 | import max7219 76 | from machine import Pin, SPI 77 | spi = SPI(1, baudrate=10000000, polarity=0, phase=0) 78 | display = max7219.Matrix8x8(spi, Pin(15), 4) 79 | display.brightness(0) 80 | display.fill(0) 81 | display.text('1234',0,0,1) 82 | display.show() 83 | ``` 84 | 85 | ## ESP32 Examples 86 | 87 | Default baud rate of 80Mhz was introducing errors, dropped from 10Mhz and it works consistently. 88 | 89 | ```python 90 | import max7219 91 | from machine import Pin, SPI 92 | spi = SPI(1, baudrate=10000000, polarity=1, phase=0, sck=Pin(4), mosi=Pin(2)) 93 | ss = Pin(5, Pin.OUT) 94 | display = max7219.Matrix8x8(spi, ss, 4) 95 | display.text('1234',0,0,1) 96 | display.show() 97 | ``` 98 | 99 | ## Connections 100 | 101 | PyBoard | max7219 8x8 LED Matrix 102 | ------- | ---------------------- 103 | VIN | VCC 104 | GND | GND 105 | X8 MOSI | DIN 106 | X5 CS | CS 107 | X6 SCK | CLK 108 | 109 | Wemos D1 Mini | max7219 8x8 LED Matrix 110 | ---------------- | ---------------------- 111 | 5V | VCC 112 | GND | GND 113 | D7 MOSI (GPIO13) | DIN 114 | D8 CS (GPIO15) | CS 115 | D5 SCK (GPIO14) | CLK 116 | 117 | ESP32 | max7219 8x8 LED Matrix 118 | ---------------- | ---------------------- 119 | 5V | VCC 120 | GND | GND 121 | D2 MOSI | DIN 122 | D5 CS | CS 123 | D4 SCK | CLK 124 | 125 | ## Links 126 | 127 | * Based on [deshipu's max7219.py](https://bitbucket.org/thesheep/micropython-max7219/src) 128 | * [micropython.org](http://micropython.org) 129 | * [Docs on framebuf](http://docs.micropython.org/en/latest/pyboard/library/framebuf.html) 130 | 131 | ## License 132 | 133 | Licensed under the [MIT License](http://opensource.org/licenses/MIT). 134 | -------------------------------------------------------------------------------- /max7219.py: -------------------------------------------------------------------------------- 1 | """ 2 | MicroPython max7219 cascadable 8x8 LED matrix driver 3 | https://github.com/mcauser/micropython-max7219 4 | 5 | MIT License 6 | Copyright (c) 2017 Mike Causer 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in all 16 | copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | SOFTWARE. 25 | """ 26 | 27 | from micropython import const 28 | import framebuf 29 | 30 | _NOOP = const(0) 31 | _DIGIT0 = const(1) 32 | _DECODEMODE = const(9) 33 | _INTENSITY = const(10) 34 | _SCANLIMIT = const(11) 35 | _SHUTDOWN = const(12) 36 | _DISPLAYTEST = const(15) 37 | 38 | class Matrix8x8: 39 | def __init__(self, spi, cs, num): 40 | """ 41 | Driver for cascading MAX7219 8x8 LED matrices. 42 | 43 | >>> import max7219 44 | >>> from machine import Pin, SPI 45 | >>> spi = SPI(1) 46 | >>> display = max7219.Matrix8x8(spi, Pin('X5'), 4) 47 | >>> display.text('1234',0,0,1) 48 | >>> display.show() 49 | 50 | """ 51 | self.spi = spi 52 | self.cs = cs 53 | self.cs.init(cs.OUT, True) 54 | self.buffer = bytearray(8 * num) 55 | self.num = num 56 | fb = framebuf.FrameBuffer(self.buffer, 8 * num, 8, framebuf.MONO_HLSB) 57 | self.framebuf = fb 58 | # Provide methods for accessing FrameBuffer graphics primitives. This is a workround 59 | # because inheritance from a native class is currently unsupported. 60 | # http://docs.micropython.org/en/latest/pyboard/library/framebuf.html 61 | self.fill = fb.fill # (col) 62 | self.pixel = fb.pixel # (x, y[, c]) 63 | self.hline = fb.hline # (x, y, w, col) 64 | self.vline = fb.vline # (x, y, h, col) 65 | self.line = fb.line # (x1, y1, x2, y2, col) 66 | self.rect = fb.rect # (x, y, w, h, col) 67 | self.fill_rect = fb.fill_rect # (x, y, w, h, col) 68 | self.text = fb.text # (string, x, y, col=1) 69 | self.scroll = fb.scroll # (dx, dy) 70 | self.blit = fb.blit # (fbuf, x, y[, key]) 71 | self.init() 72 | 73 | def _write(self, command, data): 74 | self.cs(0) 75 | for m in range(self.num): 76 | self.spi.write(bytearray([command, data])) 77 | self.cs(1) 78 | 79 | def init(self): 80 | for command, data in ( 81 | (_SHUTDOWN, 0), 82 | (_DISPLAYTEST, 0), 83 | (_SCANLIMIT, 7), 84 | (_DECODEMODE, 0), 85 | (_SHUTDOWN, 1), 86 | ): 87 | self._write(command, data) 88 | 89 | def brightness(self, value): 90 | if not 0 <= value <= 15: 91 | raise ValueError("Brightness out of range") 92 | self._write(_INTENSITY, value) 93 | 94 | def show(self): 95 | for y in range(8): 96 | self.cs(0) 97 | for m in range(self.num): 98 | self.spi.write(bytearray([_DIGIT0 + y, self.buffer[(y * self.num) + m]])) 99 | self.cs(1) 100 | --------------------------------------------------------------------------------