├── LICENSE ├── README.md ├── adafruit.py ├── example1.py ├── example2.py ├── example3.py ├── example4.py ├── example5.py ├── lib ├── README.md ├── dallas.py ├── digits.py ├── font.py └── matrix.py ├── schema.jpg ├── smile.png ├── termo.jpg └── termo.py /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Dawid Stankiewicz 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 | ![smile.png](smile.png) 2 | 3 | # M5atom matrix library 4 | 5 | A simple micropython library to support 5x5 rgb led matrix in M5Atom Matrix. The library allows you to set or delete individual pixels and set a group of pixels in one color using a "mask/pixmap". It also contains a function for the so-called flash of a single pixel and the breathing effect for a single pixel. You can also display scrolling text on your matrix. 6 | 7 | The library uses the HSV color model to simplify the implementation of the breathing effect function and support for limiting the brightness of LEDs in the matrix (due to the emission of a large amount of heat at full brightness). The color is selected from the range 0-360. It is also easy in this color model to get a smooth transition through all the colors of the rainbow by increasing the value of the variable color. 8 | 9 | Folder [/lib](/lib) contains the main library file [**matrix.py**](/lib/matrix.py) responsible for handling the embedded rbg led matrix. In addition, there is the helper library [**digits.py**](/lib/digits.py) containing pixmap data for numbers.There is also the [**dallas.py**](/lib/dallas.py) library used in the sample application. 10 | 11 | Simple examples of using this library can be found in the example.py files 12 | 13 | ## Sample application 14 | 15 | Simple thermometer application [**termo.py**](termo.py) using the dallas DS18B20 temperature sensor. The program displays the temperature in two-digit form. Due to the size of the led matrix (5x5) I did not implement the display of negative temperatures and greater than 99. I meant to show how you can display two digits at once on such a small display. In this program, the second digit overlaps the first one covering its part. The file [**example5.py**](example5.py) shows how to display the common part of overlapping digits in a different color. 16 | 17 | To simplify the sensor connection, I used three outputs located next to the ground in the connector. I used one of the inputs on the connector as a sensor 3.3V power supply pin. 18 | 19 | I did not use the 5V pin to power the sensor because of pulling the output from it to this voltage and it was given to the esp input. Various sources say that the esp gpio inputs tolerate 5V. I prefer not to risk. 20 | 21 | connection diagram: 22 | 23 | ![schema.jpg](schema.jpg) 24 | 25 | 26 | showing 28 degrees 27 | 28 | ![termo.jpg](termo.jpg) 29 | 30 | 31 | ## Scrolling text example 32 | 33 | Example script [adafruit.py](adafruit.py) displaying scrolling text with values from adafruit.io feeds. In this case to simplify acces to adafruit.io REST API was used. In this example at time when i wrote this, my feeds are updatet every 25 seconds. I do not guarantee that the feeds will be corect and current at later time. 34 | 35 | running example: 36 | 37 | ``` 38 | #load example to memory (run once) 39 | import adafruit 40 | 41 | #run this function which read actual values from adafruit.io feeds 42 | adafruit.read() 43 | ``` 44 | 45 | Watch example video on youtube: 46 | 47 | [![Watch a video](https://i9.ytimg.com/vi/D3xJCUcndfc/mq3.jpg?sqp=CMXX9_QF&rs=AOn4CLClFOlUqUlOoAcb7C-NXdrlIpgqQw)](https://youtu.be/D3xJCUcndfc) 48 | -------------------------------------------------------------------------------- /adafruit.py: -------------------------------------------------------------------------------- 1 | #M5Atom matrix scroll text example using matrix.py library 2 | #Reads data from adafruit.io using REST API. 3 | #Feed from adafruit.io who you want to read without APIKEY 4 | #must be set as PUBLIC in feed settings. 5 | #That mean that anyone can read it, but cannot write to it. 6 | 7 | import urequests 8 | import matrix 9 | import time 10 | import json 11 | import urandom 12 | 13 | import network 14 | sta_if = network.WLAN(network.STA_IF) 15 | sta_if.active(True) 16 | #REPLACE YOUR ACCES POINT CREDENTIALS BELOW 17 | sta_if.connect("YOUR_ACCES_POINT_NAME", "AP_PASSWORD") 18 | 19 | def read(delay=100): 20 | #creating aliasses 21 | r = urandom.randint 22 | m = matrix.matrix 23 | 24 | #init matrix 25 | m.init() 26 | m.clear_all() 27 | 28 | #setting adafruit.io access data 29 | USER_NAME = 'robalstona' 30 | FEED_NAME = 'feed02' 31 | #access to adafruit.io feed via REST API 32 | #read humidity value from feed 33 | response = urequests.get('https://io.adafruit.com/api/v2/' + USER_NAME + '/feeds/' + FEED_NAME) 34 | #decode json response from adafruit.io 35 | output = json.loads((response.text)) 36 | #reads a needed field from response 37 | feed_value = output['last_value'] 38 | #set random color of text 39 | m.pixel_color( r(0,360) ) 40 | text = 'humidity = ' + feed_value + ' %rh' 41 | #print value 42 | print(text) 43 | #scroll values on matrix 44 | m.text_scroll(text, delay) 45 | 46 | #setting adafruit.io access data 47 | USER_NAME = 'robalstona' 48 | FEED_NAME = 'feed01' 49 | #access to adafruit.io feed via REST API 50 | #read temperature value from feed 51 | response = urequests.get('https://io.adafruit.com/api/v2/' + USER_NAME + '/feeds/' + FEED_NAME) 52 | #decode json response from adafruit.io 53 | output = json.loads((response.text)) 54 | #reads a needed field from response 55 | feed_value = output['last_value'] 56 | #set random color of text 57 | m.pixel_color( r(0,360) ) 58 | #create celsius symbol character 59 | celsius = chr(176) 60 | text = 'temperature = ' + feed_value + ' ' + celsius + 'C' 61 | #print value 62 | print(text) 63 | #scroll values on matrix 64 | m.text_scroll(text, delay) 65 | -------------------------------------------------------------------------------- /example1.py: -------------------------------------------------------------------------------- 1 | import matrix 2 | import urandom 3 | import time 4 | 5 | 6 | #assign randint function to r 7 | r = urandom.randint 8 | 9 | #create matrix class object 10 | s = matrix.matrix 11 | 12 | #initialize matrix 13 | s.init() 14 | #clear matrix 15 | s.clear_all() 16 | #show changes 17 | s.show() 18 | 19 | while 1: 20 | #set random activr color 21 | s.pixel_color( r(0,360) ) 22 | #blink pixel at random position 23 | #pixel_blink change pixels immediately 24 | #you dont need use s.show() function 25 | s.pixel_blink( r(0,4), r(0,4), 10 ) 26 | #wait some time 27 | time.sleep_ms(10) 28 | -------------------------------------------------------------------------------- /example2.py: -------------------------------------------------------------------------------- 1 | import matrix 2 | import urandom 3 | import time 4 | 5 | #assign randint function to r 6 | r = urandom.randint 7 | 8 | #create matrix class object 9 | s = matrix.matrix 10 | 11 | #initialize matrix 12 | s.init() 13 | #clear matrix 14 | s.clear_all() 15 | #show changes 16 | s.show() 17 | 18 | while 1: 19 | #set random active color 20 | s.pixel_color( r(0,360) ) 21 | #breathe pixel at random position with random duration of effect 22 | #pixel_breathe change pixels immediately 23 | #you dont need use s.show() function 24 | delay = r(50, 100) 25 | s.pixel_breathe( r(0,4), r(0,4) ,delay, delay) 26 | #wait some time 27 | time.sleep_ms(10) 28 | 29 | -------------------------------------------------------------------------------- /example3.py: -------------------------------------------------------------------------------- 1 | import matrix 2 | import digits 3 | import urandom 4 | import time 5 | 6 | 7 | #assign randint function to r 8 | r = urandom.randint 9 | 10 | #create matrix class object 11 | s = matrix.matrix 12 | 13 | #create digits class object 14 | d = digits 15 | 16 | #initialize led matrix 17 | s.init() 18 | #clear led matrix 19 | s.clear_all() 20 | #show changes 21 | s.show() 22 | 23 | color = 0 24 | while 1: 25 | #set random active color 26 | s.pixel_color( color ) 27 | 28 | #write pixmap of random digit to pic variable 29 | pic = d.get_digit( r(0,9), d.digits_center ) 30 | #pic = d.get_digit( r(0,9), d.digits_left ) 31 | #pic = d.get_digit( r(0,9), d.digits_right ) 32 | #write pixmap to led matrix 33 | s.clear_all() 34 | s.pixel_mask( pic ) 35 | #show changes 36 | s.show() 37 | #wait some time 38 | time.sleep_ms(1000) 39 | color = color + 5 40 | 41 | -------------------------------------------------------------------------------- /example4.py: -------------------------------------------------------------------------------- 1 | import matrix 2 | import urandom 3 | import time 4 | 5 | #assign randint function to r 6 | r = urandom.randint 7 | 8 | #create matrix class object 9 | s = matrix.matrix 10 | 11 | #initialize led matrix 12 | s.init() 13 | #clear led matrix 14 | s.clear_all() 15 | #show changes 16 | s.show() 17 | 18 | #smile pixmaps 19 | smile0 = [ 20 | 0,0,0,0,0, 21 | 0,1,0,1,0, 22 | 0,0,0,0,0, 23 | 1,0,0,0,1, 24 | 0,1,1,1,0 25 | ] 26 | 27 | smile1 = [ 28 | 0,0,0,0,0, 29 | 0,1,0,1,0, 30 | 0,0,0,0,0, 31 | 1,1,1,1,1, 32 | 0,0,0,0,0 33 | ] 34 | 35 | smile2 = [ 36 | 0,0,0,0,0, 37 | 0,1,0,1,0, 38 | 0,0,0,0,0, 39 | 0,1,1,1,0, 40 | 1,0,0,0,1 41 | ] 42 | 43 | while 1: 44 | #set random active color 45 | s.pixel_color( r(0,360) ) 46 | #write smile pixmap to led matrix and show changes 47 | s.clear_all() 48 | s.pixel_mask( smile0 ) 49 | s.show() 50 | time.sleep_ms(1000) 51 | s.clear_all() 52 | s.pixel_mask( smile1 ) 53 | s.show() 54 | time.sleep_ms(1000) 55 | s.clear_all() 56 | s.pixel_mask( smile2 ) 57 | s.show() 58 | time.sleep_ms(1000) 59 | 60 | 61 | -------------------------------------------------------------------------------- /example5.py: -------------------------------------------------------------------------------- 1 | import matrix 2 | import digits 3 | import urandom 4 | import time 5 | 6 | #assign randint function to r 7 | r = urandom.randint 8 | 9 | #create matrix class object 10 | s = matrix.matrix 11 | 12 | #create digits class object 13 | d = digits 14 | 15 | #initialize led matrix 16 | s.init() 17 | #clear led matrix 18 | s.clear_all() 19 | #show changes 20 | s.show() 21 | 22 | #setings digits colors 23 | color1 = 0 #color of left digit 24 | color2 = 210 #color of right digit 25 | color3 = 300 #color of common pixels of digits 26 | 27 | number = 0 28 | while 1: 29 | d1 = int(number / 10) 30 | d2 = number % 10 31 | d_l = d.get_digit(d1, d.digits_left) 32 | d_r = d.get_digit(d2, d.digits_right) 33 | #create empty pixmap of common pixel 34 | d_com = [0] * 25 35 | #find common pixels of left and right digits and create new pixmap 36 | for pix in range (0, 25): 37 | if ((d_l[pix] + d_r[pix]) == 2): 38 | d_com[pix] = 1 39 | else: 40 | d_com[pix] = 0 41 | #show digits 42 | s.clear_all() 43 | s.pixel_color(color1) 44 | s.pixel_mask(d_l) 45 | s.pixel_color(color2) 46 | s.pixel_mask(d_r) 47 | s.pixel_color(color3) 48 | s.pixel_mask(d_com) 49 | s.show() 50 | time.sleep_ms(500) 51 | number = number +1 52 | if number > 99: 53 | number = 0 54 | 55 | -------------------------------------------------------------------------------- /lib/README.md: -------------------------------------------------------------------------------- 1 | # m5atom library files 2 | Short & simple micropython scripts for **M5atom Matrix** 3 | 4 | ## matrix.py 5 | Simple library using m5atom builtin 5x5 addressable led matrix 6 | 7 | usage model: 8 | - import library (once) 9 | - initialize matrix (once) 10 | - set drawing color 11 | - draw/clear pixels/mask 12 | - show changes you made on matrix 13 | 14 | example: 15 | ``` 16 | #import library 17 | import matrix 18 | #create scr object 19 | scr = matrix.matrix 20 | 21 | #initialize matrix 22 | scr.init() 23 | 24 | #clear matrix 25 | scr.clear_all() 26 | 27 | #set active color 28 | scr.pixel_color(120) 29 | #set pixels with given color 30 | scr.pixel_set(0,0) 31 | scr.pixel_set(1,1) 32 | scr.pixel_set(2,2) 33 | scr.pixel_clear(1,1) 34 | #show changes on matrix 35 | scr.show() 36 | ``` 37 | 38 | list of library functions: 39 | 40 | 41 | ``` 42 | init() 43 | ``` 44 | Initialize led matrix. Run it once before using other functions from this library 45 | 46 | parameters: 47 | 48 | **none** 49 | 50 | 51 | ``` 52 | show() 53 | ``` 54 | Function show/draw to matrix changes made you by other drawing function 55 | 56 | parameters: 57 | 58 | **none** 59 | 60 | 61 | ``` 62 | pixel_color(h, s=1, v=1): 63 | ``` 64 | Set color who been used for the next drawing function, Color is set in HSV color model 65 | 66 | 67 | parameters: 68 | 69 | **h** - color number from color wheel (0 - 360) 70 | 71 | **s** - optionally color saturation (0-1.0) 72 | 73 | **v** - optionally color value (brightness of color) (0-1.0) 74 | 75 | ``` 76 | pixel_set(x, y): 77 | ``` 78 | Set given coordinates pixel to color 79 | 80 | 81 | parameters: 82 | 83 | **x** - x coordinate (0-4) 84 | 85 | **y** - y coordinate (0-4) 86 | 87 | ``` 88 | pixel_clear(x, y): 89 | ``` 90 | Clear given coordinates pixel 91 | 92 | 93 | parameters: 94 | 95 | **x** - x coordinate (0-4) 96 | 97 | **y** - y coordinate (0-4) 98 | 99 | ``` 100 | pixel_blink(x, y, delay_ms=100 ) 101 | ``` 102 | Blink given coordinates pixel. Preserve previous color of pixel after blink 103 | 104 | 105 | parameters: 106 | 107 | **x** - x coordinate (0-4) 108 | 109 | **y** - y coordinate (0-4) 110 | 111 | **delay_ms** - optionally blink time of pixel in miliseconds 112 | 113 | ``` 114 | pixel_breathe(x, y, ms_in=50, ms_out=50) 115 | ``` 116 | Breathe pixel effect at given coordinates pixel. This is blocking function using **time.sleep_ms()**. Total duration of efect is **11**×**ms_in + 11**×**ms_out**. 117 | 118 | 119 | parameters: 120 | 121 | **x** - x coordinate (0-4) 122 | 123 | **y** - y coordinate (0-4) 124 | 125 | **ms_in** - optionally breathe in effect step time in miliseconds 126 | 127 | **ms_out** - optionally breathe out effect step time in miliseconds 128 | 129 | 130 | ``` 131 | pixel_mask(buf) 132 | ``` 133 | Seting pixels on matrix according to buffer containing pixmap. Function set only pixels on matrix with value greater on equal 1. Other pixels are not affected (preserve previous value). If length of **buf** is less than number of leds in matrix, the only partial leds in matrix will be set. 134 | 135 | parameters: 136 | 137 | **buf** - aray of pixels to set (0 - no change pixel, 1 or greater - set pixel ) 138 | 139 | example_buf = [ 140 | 0,0,0,0,0, 141 | 0,1,0,1,0, 142 | 0,0,0,0,0, 143 | 1,0,0,0,1, 144 | 0,1,1,1,0 145 | ] 146 | 147 | ``` 148 | write_buffer(buf) 149 | ``` 150 | Seting pixels color in RGB color. Function Function overwrite old color values. If length of **buf** is less than number of leds in matrix, the only partial leds in matrix will be set. 151 | 152 | parameters: 153 | 154 | **buf** - aray of rgb colors to set (red, green, blue ) 155 | 156 | example_buf = [ 157 | (0,0,255),(0,0,255),(0,0,255),(0,0,255),(0,0,255), 158 | (0,0,255),(0,0,0),(0,0,0),(0,0,0),(0,0,255), 159 | (0,0,255),(0,0,),(255,255,255),(0,0,0),(0,0,255), 160 | (0,0,255),(0,0,0),(0,0,0),(0,0,0),(0,0,255), 161 | (0,0,255),(0,0,255),(0,0,255),(0,0,255),(0,0,255) 162 | ] 163 | 164 | ``` 165 | text_scroll(text_to_scroll, delay=150) 166 | ``` 167 | Display scrolling text on matrix display. 168 | 169 | parameters: 170 | 171 | **text_to_scroll** - text to scroll and display. 172 | 173 | **delay** - optionally delay in ms between next frames of scrolling text, default is 150ms 174 | 175 | ## fonts.py 176 | This is a helper library for function ```text_scroll()``` from **matrix.py** library. It contains pixmaps data for ascii characters codes from 32 to 127. 177 | 178 | ``` 179 | get_letter(asci) 180 | ``` 181 | Return pixmap data of character for given ascii code. Return pixmaps for ascii codes in range 32 to 127. If ascii code value is beyound of range 32-127 return empty pixmap. 182 | 183 | parameters: 184 | 185 | **asci** - number of character ascii code 186 | 187 | ## digits.py 188 | This library contains three pixmaps array of digits from 0 to 9. Digits size: width = 3 pixel, weight = 5 pixel. 189 | 190 | 191 | ``` 192 | digits_left = [ ...... ] 193 | ``` 194 | Contain pixmap of digits displayed on left side of matrix (column: 0,1,2) 195 | 196 | ``` 197 | digits_right = [ ...... ] 198 | ``` 199 | Contain pixmap of digits displayed on right side of matrix (column: 2,3,4) 200 | 201 | ``` 202 | digits_center = [ ...... ] 203 | ``` 204 | Contain pixmap digits displayed on center of matrix (column: 1,2,3) 205 | 206 | ``` 207 | get_digit(position, data) 208 | ``` 209 | Function return pixmap of given number of digit from given pixmap array. 210 | 211 | parameters: 212 | 213 | **position** - number of digit (from 0 to 9) 214 | 215 | **data** - array of pixmaps which pixmap are returned. you can use **digits_left**, **digits_right**, **digits_center** or name of other array you are created. 216 | 217 | -------------------------------------------------------------------------------- /lib/dallas.py: -------------------------------------------------------------------------------- 1 | #simple ds1820 ds18b20 module 2 | #reads only one sensor per pin 3 | 4 | from machine import Pin 5 | import _onewire 6 | 7 | class ds1820: 8 | 9 | #configure pin to onewire transmission 10 | def init(pin): 11 | Pin(pin, Pin.OPEN_DRAIN, Pin.PULL_UP) 12 | 13 | #send convert command to sensor 14 | def convert(pin): 15 | _onewire.reset(Pin(pin)) 16 | _onewire.writebyte(Pin(pin), 0xcc) #skip rom 17 | _onewire.writebyte(Pin(pin), 0x44) #convert 18 | 19 | #send read temperature command to sensor 20 | def read(pin): 21 | _onewire.reset(Pin(pin)) 22 | _onewire.writebyte(Pin(pin), 0xcc) #skip rom 23 | _onewire.writebyte(Pin(pin), 0xbe) #read scratchpad 24 | 25 | tlo = _onewire.readbyte(Pin(pin)) 26 | thi = _onewire.readbyte(Pin(pin)) 27 | _onewire.reset(Pin(pin)) 28 | 29 | #convert raw values to human eye readable 30 | temp = tlo + thi * 256 31 | if temp > 32767: 32 | temp = temp - 65536 33 | temp = temp * 0.5 34 | return(temp) 35 | 36 | class ds18b20: 37 | 38 | #configure pin to onewire transmission 39 | def init(pin): 40 | Pin(pin, Pin.OPEN_DRAIN, Pin.PULL_UP) 41 | 42 | #send convert command to sensor 43 | def convert(pin): 44 | _onewire.reset(Pin(pin)) 45 | _onewire.writebyte(Pin(pin), 0xcc) #skip rom 46 | _onewire.writebyte(Pin(pin), 0x44) #convert 47 | 48 | #send read temperature command to sensor 49 | def read(pin): 50 | _onewire.reset(Pin(pin)) 51 | _onewire.writebyte(Pin(pin), 0xcc) #skip rom 52 | _onewire.writebyte(Pin(pin), 0xbe) #read scratchpad 53 | #read raw temperature 54 | tlo = _onewire.readbyte(Pin(pin)) 55 | thi = _onewire.readbyte(Pin(pin)) 56 | _onewire.reset(Pin(pin)) 57 | #convert raw values to human eye readable 58 | temp = tlo + thi * 256 59 | if temp > 32767: 60 | temp = temp - 65536 61 | temp = temp * 0.0625 62 | return(temp) 63 | 64 | -------------------------------------------------------------------------------- /lib/digits.py: -------------------------------------------------------------------------------- 1 | #m5 atom matrix 5x5 digits array 2 | 3 | HEIGHT = 5 4 | WIDTH = 5 5 | LENGTH = (HEIGHT * WIDTH) 6 | 7 | def get_digit(position, data): 8 | start_pos = position * LENGTH 9 | end_pos = start_pos + LENGTH 10 | buffer = data[start_pos:end_pos] 11 | return(buffer) 12 | 13 | digits_left = [ 14 | 15 | 1, 1, 1, 0, 0, 16 | 1, 0, 1, 0, 0, 17 | 1, 0, 1, 0, 0, 18 | 1, 0, 1, 0, 0, 19 | 1, 1, 1, 0, 0, 20 | 21 | 0, 1, 0, 0, 0, 22 | 0, 1, 0, 0, 0, 23 | 0, 1, 0, 0, 0, 24 | 0, 1, 0, 0, 0, 25 | 0, 1, 0, 0, 0, 26 | 27 | 1, 1, 1, 0, 0, 28 | 0, 0, 1, 0, 0, 29 | 1, 1, 1, 0, 0, 30 | 1, 0, 0, 0, 0, 31 | 1, 1, 1, 0, 0, 32 | 33 | 1, 1, 1, 0, 0, 34 | 0, 0, 1, 0, 0, 35 | 1, 1, 1, 0, 0, 36 | 0, 0, 1, 0, 0, 37 | 1, 1, 1, 0, 0, 38 | 39 | 1, 0, 1, 0, 0, 40 | 1, 0, 1, 0, 0, 41 | 1, 1, 1, 0, 0, 42 | 0, 0, 1, 0, 0, 43 | 0, 0, 1, 0, 0, 44 | 45 | 1, 1, 1, 0, 0, 46 | 1, 0, 0, 0, 0, 47 | 1, 1, 1, 0, 0, 48 | 0, 0, 1, 0, 0, 49 | 1, 1, 1, 0, 0, 50 | 51 | 1, 1, 1, 0, 0, 52 | 1, 0, 0, 0, 0, 53 | 1, 1, 1, 0, 0, 54 | 1, 0, 1, 0, 0, 55 | 1, 1, 1, 0, 0, 56 | 57 | 1, 1, 1, 0, 0, 58 | 0, 0, 1, 0, 0, 59 | 0, 0, 1, 0, 0, 60 | 0, 0, 1, 0, 0, 61 | 0, 0, 1, 0, 0, 62 | 63 | 1, 1, 1, 0, 0, 64 | 1, 0, 1, 0, 0, 65 | 1, 1, 1, 0, 0, 66 | 1, 0, 1, 0, 0, 67 | 1, 1, 1, 0, 0, 68 | 69 | 1, 1, 1, 0, 0, 70 | 1, 0, 1, 0, 0, 71 | 1, 1, 1, 0, 0, 72 | 0, 0, 1, 0, 0, 73 | 1, 1, 1, 0, 0, 74 | 75 | ] 76 | 77 | digits_right = [ 78 | 79 | 0, 0, 1, 1, 1, 80 | 0, 0, 1, 0, 1, 81 | 0, 0, 1, 0, 1, 82 | 0, 0, 1, 0, 1, 83 | 0, 0, 1, 1, 1, 84 | 85 | 0, 0, 0, 1, 0, 86 | 0, 0, 0, 1, 0, 87 | 0, 0, 0, 1, 0, 88 | 0, 0, 0, 1, 0, 89 | 0, 0, 0, 1, 0, 90 | 91 | 0, 0, 1, 1, 1, 92 | 0, 0, 0, 0, 1, 93 | 0, 0, 1, 1, 1, 94 | 0, 0, 1, 0, 0, 95 | 0, 0, 1, 1, 1, 96 | 97 | 0, 0, 1, 1, 1, 98 | 0, 0, 0, 0, 1, 99 | 0, 0, 1, 1, 1, 100 | 0, 0, 0, 0, 1, 101 | 0, 0, 1, 1, 1, 102 | 103 | 0, 0, 1, 0, 1, 104 | 0, 0, 1, 0, 1, 105 | 0, 0, 1, 1, 1, 106 | 0, 0, 0, 0, 1, 107 | 0, 0, 0, 0, 1, 108 | 109 | 0, 0, 1, 1, 1, 110 | 0, 0, 1, 0, 0, 111 | 0, 0, 1, 1, 1, 112 | 0, 0, 0, 0, 1, 113 | 0, 0, 1, 1, 1, 114 | 115 | 0, 0, 1, 1, 1, 116 | 0, 0, 1, 0, 0, 117 | 0, 0, 1, 1, 1, 118 | 0, 0, 1, 0, 1, 119 | 0, 0, 1, 1, 1, 120 | 121 | 0, 0, 1, 1, 1, 122 | 0, 0, 0, 0, 1, 123 | 0, 0, 0, 0, 1, 124 | 0, 0, 0, 0, 1, 125 | 0, 0, 0, 0, 1, 126 | 127 | 0, 0, 1, 1, 1, 128 | 0, 0, 1, 0, 1, 129 | 0, 0, 1, 1, 1, 130 | 0, 0, 1, 0, 1, 131 | 0, 0, 1, 1, 1, 132 | 133 | 0, 0, 1, 1, 1, 134 | 0, 0, 1, 0, 1, 135 | 0, 0, 1, 1, 1, 136 | 0, 0, 0, 0, 1, 137 | 0, 0, 1, 1, 1, 138 | 139 | ] 140 | 141 | digits_center = [ 142 | 143 | 0, 1, 1, 1, 0, 144 | 0, 1, 0, 1, 0, 145 | 0, 1, 0, 1, 0, 146 | 0, 1, 0, 1, 0, 147 | 0, 1, 1, 1, 0, 148 | 149 | 0, 0, 1, 0, 0, 150 | 0, 0, 1, 0, 0, 151 | 0, 0, 1, 0, 0, 152 | 0, 0, 1, 0, 0, 153 | 0, 0, 1, 0, 0, 154 | 155 | 0, 1, 1, 1, 0, 156 | 0, 0, 0, 1, 0, 157 | 0, 1, 1, 1, 0, 158 | 0, 1, 0, 0, 0, 159 | 0, 1, 1, 1, 0, 160 | 161 | 0, 1, 1, 1, 0, 162 | 0, 0, 0, 1, 0, 163 | 0, 1, 1, 1, 0, 164 | 0, 0, 0, 1, 0, 165 | 0, 1, 1, 1, 0, 166 | 167 | 0, 1, 0, 1, 0, 168 | 0, 1, 0, 1, 0, 169 | 0, 1, 1, 1, 0, 170 | 0, 0, 0, 1, 0, 171 | 0, 0, 0, 1, 0, 172 | 173 | 0, 1, 1, 1, 0, 174 | 0, 1, 0, 0, 0, 175 | 0, 1, 1, 1, 0, 176 | 0, 0, 0, 1, 0, 177 | 0, 1, 1, 1, 0, 178 | 179 | 0, 1, 1, 1, 0, 180 | 0, 1, 0, 0, 0, 181 | 0, 1, 1, 1, 0, 182 | 0, 1, 0, 1, 0, 183 | 0, 1, 1, 1, 0, 184 | 185 | 0, 1, 1, 1, 0, 186 | 0, 0, 0, 1, 0, 187 | 0, 0, 0, 1, 0, 188 | 0, 0, 0, 1, 0, 189 | 0, 0, 0, 1, 0, 190 | 191 | 0, 1, 1, 1, 0, 192 | 0, 1, 0, 1, 0, 193 | 0, 1, 1, 1, 0, 194 | 0, 1, 0, 1, 0, 195 | 0, 1, 1, 1, 0, 196 | 197 | 0, 1, 1, 1, 0, 198 | 0, 1, 0, 1, 0, 199 | 0, 1, 1, 1, 0, 200 | 0, 0, 0, 1, 0, 201 | 0, 1, 1, 1, 0, 202 | 203 | ] 204 | 205 | -------------------------------------------------------------------------------- /lib/font.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 stonatm@gmail.com 2 | # 5x5 characters pixmap font 3 | # fonts based and complete with missing chars from: 4 | # https://www.1001fonts.com/5x5-font.html 5 | # oryginally created by Juan A. Zamarrip (dabnotu) 6 | # site: dabnotu@mastodon 7 | # contact: dabnotu@tuta.io 8 | # fonts contains characters from 32 to 127 in ascii code 9 | 10 | def get_letter(asci): 11 | 12 | #capture characters beyound 127 13 | if asci == 176: 14 | return celsius 15 | if asci == 248: 16 | return celsius 17 | #capture codes out of range 18 | if asci < 32: 19 | return empty 20 | if asci > 127: 21 | return empty 22 | #return valid character in range 23 | return data[(25*(asci-32)):(25*(asci-32+1))] 24 | 25 | 26 | empty = [ 27 | 0,0,0,0,0, 28 | 0,0,0,0,0, 29 | 0,0,0,0,0, 30 | 0,0,0,0,0, 31 | 0,0,0,0,0 32 | ] 33 | 34 | celsius = [ 35 | #176 36 | 0,1,1,1,0, 37 | 0,1,0,1,0, 38 | 0,1,1,1,0, 39 | 0,0,0,0,0, 40 | 0,0,0,0,0 41 | ] 42 | 43 | data = [ 44 | #32 SPACE 45 | 0,0,0,0,0, 46 | 0,0,0,0,0, 47 | 0,0,0,0,0, 48 | 0,0,0,0,0, 49 | 0,0,0,0,0, 50 | #33 ! 51 | 0,0,1,1,0, 52 | 0,0,1,1,0, 53 | 0,0,1,1,0, 54 | 0,0,0,0,0, 55 | 0,0,1,1,0, 56 | #34 " 57 | 0,1,1,0,1, 58 | 1,1,0,1,1, 59 | 0,0,0,0,0, 60 | 0,0,0,0,0, 61 | 0,0,0,0,0, 62 | #35 # 63 | 0,1,0,1,0, 64 | 1,1,1,1,1, 65 | 0,1,0,1,0, 66 | 1,1,1,1,1, 67 | 0,1,0,1,0, 68 | #36 $ 69 | 0,0,0,0,0, 70 | 0,0,0,0,0, 71 | 0,0,0,0,0, 72 | 0,0,0,0,0, 73 | 0,0,0,0,0, 74 | #37 % 75 | 1,1,0,1,1, 76 | 1,0,1,1,0, 77 | 0,0,1,0,0, 78 | 0,1,1,0,1, 79 | 1,1,0,1,1, 80 | #38 & 81 | 0,0,0,0,0, 82 | 0,0,0,0,0, 83 | 0,0,0,0,0, 84 | 0,0,0,0,0, 85 | 0,0,0,0,0, 86 | #39 ' 87 | 0,0,1,1,0, 88 | 0,0,1,1,0, 89 | 0,0,0,1,0, 90 | 0,0,0,0,0, 91 | 0,0,0,0,0, 92 | #40 ( 93 | 0,0,1,1,0, 94 | 0,1,1,0,0, 95 | 0,1,0,0,0, 96 | 0,1,1,0,0, 97 | 0,0,1,1,0, 98 | #41 ) 99 | 0,1,1,0,0, 100 | 0,0,1,1,0, 101 | 0,0,0,1,0, 102 | 0,0,1,1,0, 103 | 0,1,1,0,0, 104 | #42 * 105 | 1,0,1,0,1, 106 | 0,1,1,1,0, 107 | 1,1,1,1,1, 108 | 0,1,1,1,0, 109 | 1,0,1,0,1, 110 | #43 + 111 | 0,0,1,0,0, 112 | 0,0,1,0,0, 113 | 1,1,1,1,1, 114 | 0,0,1,0,0, 115 | 0,0,1,0,0, 116 | #44 , 117 | 0,0,0,0,0, 118 | 0,0,0,0,0, 119 | 0,0,0,0,0, 120 | 0,0,1,1,0, 121 | 0,1,1,0,0, 122 | #45 - 123 | 0,0,0,0,0, 124 | 0,0,0,0,0, 125 | 0,1,1,1,1, 126 | 0,0,0,0,0, 127 | 0,0,0,0,0, 128 | #46 . 129 | 0,0,0,0,0, 130 | 0,0,0,0,0, 131 | 0,0,0,0,0, 132 | 0,1,1,0,0, 133 | 0,1,1,0,0, 134 | #47 / 135 | 0,0,0,1,1, 136 | 0,0,1,1,1, 137 | 0,1,1,1,0, 138 | 1,1,1,0,0, 139 | 1,1,0,0,0, 140 | #48 0 141 | 0,1,1,1,0, 142 | 1,1,0,1,1, 143 | 1,1,0,1,1, 144 | 1,1,0,1,1, 145 | 0,1,1,1,0, 146 | #49 1 147 | 0,0,1,0,0, 148 | 0,1,1,0,0, 149 | 0,0,1,0,0, 150 | 0,0,1,0,0, 151 | 1,1,1,1,1, 152 | #50 2 153 | 1,1,1,1,0, 154 | 1,0,0,1,1, 155 | 0,0,1,1,1, 156 | 0,1,1,0,0, 157 | 1,1,1,1,1, 158 | #51 3 159 | 1,1,1,1,0, 160 | 1,0,0,1,1, 161 | 0,0,1,1,0, 162 | 1,0,0,1,1, 163 | 1,1,1,1,0, 164 | #52 4 165 | 0,0,1,1,0, 166 | 0,1,1,1,0, 167 | 1,1,0,1,0, 168 | 1,1,1,1,1, 169 | 0,0,0,1,0, 170 | #53 5 171 | 1,1,1,1,1, 172 | 1,0,0,0,0, 173 | 1,1,1,1,1, 174 | 0,0,0,1,1, 175 | 1,1,1,1,0, 176 | #54 6 177 | 0,1,1,1,0, 178 | 1,1,0,0,0, 179 | 1,1,1,1,1, 180 | 1,1,0,1,1, 181 | 0,1,1,1,0, 182 | #55 7 183 | 1,1,1,1,1, 184 | 1,0,0,0,1, 185 | 0,0,0,1,1, 186 | 0,0,1,1,0, 187 | 0,0,1,0,0, 188 | #56 8 189 | 0,1,1,1,0, 190 | 1,1,0,1,1, 191 | 0,1,1,1,0, 192 | 1,1,0,1,1, 193 | 0,1,1,1,0, 194 | #57 9 195 | 0,1,1,1,0, 196 | 1,1,0,1,1, 197 | 1,1,1,1,1, 198 | 0,0,0,1,1, 199 | 0,1,1,1,0, 200 | #58 : 201 | 0,0,0,0,0, 202 | 0,0,1,1,0, 203 | 0,0,0,0,0, 204 | 0,0,1,1,0, 205 | 0,0,0,0,0, 206 | #59 ; 207 | 0,0,0,0,0, 208 | 0,0,1,1,0, 209 | 0,0,0,0,0, 210 | 0,0,1,1,0, 211 | 0,1,1,0,0, 212 | #60 < 213 | 0,0,1,0,0, 214 | 0,1,1,0,0, 215 | 1,1,0,0,0, 216 | 0,1,1,0,0, 217 | 0,0,1,0,0, 218 | #61 = 219 | 0,0,0,0,0, 220 | 0,1,1,1,0, 221 | 0,0,0,0,0, 222 | 0,1,1,1,0, 223 | 0,1,1,1,0, 224 | #62 > 225 | 0,0,1,0,0, 226 | 0,0,1,1,0, 227 | 0,0,0,1,1, 228 | 0,0,1,1,0, 229 | 0,0,1,0,0, 230 | #63 ? 231 | 1,1,1,1,0, 232 | 1,0,0,1,1, 233 | 0,0,1,1,0, 234 | 0,0,0,0,0, 235 | 0,0,1,1,0, 236 | #64 @ 237 | 0,1,1,1,0, 238 | 1,0,1,1,1, 239 | 1,0,1,1,1, 240 | 1,1,0,0,0, 241 | 0,1,1,1,0, 242 | #65 A 243 | 0,1,1,1,0, 244 | 0,1,0,1,0, 245 | 1,1,1,1,1, 246 | 1,0,0,0,1, 247 | 1,1,0,1,1, 248 | #66 B 249 | 1,1,1,1,0, 250 | 0,1,0,1,1, 251 | 1,1,1,1,0, 252 | 0,1,0,1,1, 253 | 1,1,1,1,0, 254 | #67 C 255 | 0,0,1,1,1, 256 | 0,1,1,0,1, 257 | 1,1,0,0,0, 258 | 0,1,1,0,1, 259 | 0,0,1,1,1, 260 | #68 D 261 | 1,1,1,1,0, 262 | 0,1,0,1,1, 263 | 0,1,0,1,1, 264 | 0,1,0,1,1, 265 | 1,1,1,1,0, 266 | #69 E 267 | 1,1,1,1,1, 268 | 0,1,0,0,1, 269 | 1,1,1,0,0, 270 | 0,1,0,0,1, 271 | 1,1,1,1,1, 272 | #70 F 273 | 1,1,1,1,1, 274 | 0,1,0,0,1, 275 | 1,1,1,0,0, 276 | 0,1,0,0,0, 277 | 1,1,1,0,0, 278 | #71 G 279 | 0,1,1,1,0, 280 | 1,1,0,0,0, 281 | 1,0,0,1,1, 282 | 1,1,0,0,1, 283 | 0,1,1,1,1, 284 | #72 H 285 | 1,1,0,1,1, 286 | 0,1,0,0,1, 287 | 0,1,1,1,1, 288 | 0,1,0,0,1, 289 | 1,1,0,1,1, 290 | #73 I 291 | 1,1,1,1,1, 292 | 0,0,1,0,0, 293 | 0,0,1,0,0, 294 | 0,0,1,0,0, 295 | 1,1,1,1,1, 296 | #74 J 297 | 1,1,1,1,1, 298 | 0,0,1,0,0, 299 | 0,0,1,0,0, 300 | 1,0,1,0,0, 301 | 1,1,1,0,0, 302 | #75 K 303 | 1,0,0,1,1, 304 | 1,0,1,1,0, 305 | 1,1,1,0,0, 306 | 1,0,1,1,0, 307 | 1,0,0,1,1, 308 | #76 L 309 | 1,1,1,0,0, 310 | 0,1,0,0,0, 311 | 0,1,0,0,0, 312 | 0,1,0,0,1, 313 | 1,1,1,1,1, 314 | #77 M 315 | 1,1,0,1,1, 316 | 1,1,1,1,1, 317 | 1,0,1,0,1, 318 | 1,0,0,0,1, 319 | 1,1,0,1,1, 320 | #78 N 321 | 1,1,0,0,1, 322 | 1,1,1,0,1, 323 | 1,0,1,0,1, 324 | 1,0,1,1,1, 325 | 1,0,0,1,1, 326 | #79 O 327 | 0,1,1,1,0, 328 | 1,1,1,1,1, 329 | 1,0,0,0,1, 330 | 1,1,1,1,1, 331 | 0,1,1,1,0, 332 | #80 P 333 | 1,1,1,1,0, 334 | 0,1,0,1,1, 335 | 0,1,1,1,0, 336 | 0,1,0,0,0, 337 | 1,1,1,0,0, 338 | #81 Q 339 | 0,1,1,1,0, 340 | 1,1,0,1,1, 341 | 0,1,1,1,0, 342 | 0,0,1,0,0, 343 | 0,0,1,1,1, 344 | #82 R 345 | 1,1,1,1,1, 346 | 0,1,1,0,1, 347 | 1,1,1,1,1, 348 | 0,1,0,1,0, 349 | 1,1,0,1,1, 350 | #83 S 351 | 0,1,1,1,1, 352 | 1,1,0,0,0, 353 | 1,1,1,1,1, 354 | 0,0,0,1,1, 355 | 1,1,1,1,0, 356 | #84 T 357 | 1,1,1,1,1, 358 | 1,0,1,0,1, 359 | 0,0,1,0,0, 360 | 0,0,1,0,0, 361 | 0,1,1,1,0, 362 | #85 U 363 | 1,0,0,0,1, 364 | 1,0,0,0,1, 365 | 1,0,0,0,1, 366 | 1,1,0,1,1, 367 | 0,1,1,1,0, 368 | #86 V 369 | 1,0,0,0,1, 370 | 1,1,0,1,1, 371 | 0,1,0,1,0, 372 | 0,1,1,1,0, 373 | 0,0,1,0,0, 374 | #87 W 375 | 1,0,0,0,1, 376 | 1,0,1,0,1, 377 | 1,0,1,0,1, 378 | 1,1,1,1,1, 379 | 0,1,0,1,0, 380 | #88 X 381 | 1,0,0,0,1, 382 | 1,1,0,1,1, 383 | 0,1,1,1,0, 384 | 1,1,0,1,1, 385 | 1,0,0,0,1, 386 | #89 Y 387 | 1,0,0,0,1, 388 | 1,1,0,1,1, 389 | 0,1,1,1,0, 390 | 0,0,1,0,0, 391 | 0,1,1,1,0, 392 | #90 Z 393 | 1,1,1,1,1, 394 | 1,0,1,1,0, 395 | 0,0,1,0,0, 396 | 0,1,1,0,1, 397 | 1,1,1,1,1, 398 | #91 [ 399 | 0,1,1,1,0, 400 | 0,1,1,0,0, 401 | 0,1,1,0,0, 402 | 0,1,1,0,0, 403 | 0,1,1,1,0, 404 | #92 \ 405 | 1,1,0,0,0, 406 | 1,1,1,0,0, 407 | 0,1,1,1,0, 408 | 0,0,1,1,1, 409 | 0,0,0,1,1, 410 | #93 ] 411 | 0,1,1,1,0, 412 | 0,0,1,1,0, 413 | 0,0,1,1,0, 414 | 0,0,1,1,0, 415 | 0,1,1,1,0, 416 | #94 ^ 417 | 0,0,1,0,0, 418 | 0,1,1,1,0, 419 | 1,1,0,1,1, 420 | 0,0,0,0,0, 421 | 0,0,0,0,0, 422 | #95 _ 423 | 0,0,0,0,0, 424 | 0,0,0,0,0, 425 | 0,0,0,0,0, 426 | 1,1,1,1,1, 427 | 1,1,1,1,1, 428 | #96 ' 429 | 0,1,1,0,0, 430 | 0,0,1,1,0, 431 | 0,0,0,0,0, 432 | 0,0,0,0,0, 433 | 0,0,0,0,0, 434 | #97 a 435 | 0,1,1,1,0, 436 | 0,0,0,1,1, 437 | 1,1,1,1,1, 438 | 1,1,0,1,1, 439 | 0,1,1,1,0, 440 | #98 b 441 | 1,1,0,0,0, 442 | 0,1,0,0,0, 443 | 0,1,1,1,0, 444 | 0,1,0,1,1, 445 | 1,1,1,1,0, 446 | #99 c 447 | 0,1,1,1,0, 448 | 1,1,0,1,1, 449 | 1,0,0,0,0, 450 | 1,1,0,1,1, 451 | 0,1,1,1,0, 452 | #100 d 453 | 0,0,0,1,1, 454 | 0,0,0,1,0, 455 | 0,1,1,1,0, 456 | 1,1,0,1,0, 457 | 0,1,1,1,1, 458 | #101 e 459 | 0,1,1,1,0, 460 | 1,1,0,1,1, 461 | 1,1,1,1,1, 462 | 1,1,0,0,0, 463 | 0,1,1,1,0, 464 | #102 f 465 | 0,0,1,1,1, 466 | 0,0,1,0,0, 467 | 1,1,1,1,1, 468 | 0,0,1,0,0, 469 | 0,1,1,1,0, 470 | #103 g 471 | 0,0,1,1,1, 472 | 0,1,1,0,1, 473 | 0,0,1,1,1, 474 | 1,0,0,0,1, 475 | 1,1,1,1,1, 476 | #104 h 477 | 1,1,0,0,0, 478 | 0,1,0,0,0, 479 | 0,1,1,1,0, 480 | 0,1,0,1,0, 481 | 1,1,0,1,1, 482 | #105 i 483 | 0,0,1,0,0, 484 | 0,0,0,0,0, 485 | 0,1,1,0,0, 486 | 0,0,1,0,0, 487 | 1,1,1,1,1, 488 | #106 j 489 | 0,0,0,0,1, 490 | 0,0,0,0,0, 491 | 0,0,0,1,1, 492 | 1,0,0,0,1, 493 | 1,1,1,1,1, 494 | #107 k 495 | 1,1,0,0,0, 496 | 0,1,0,1,1, 497 | 0,1,1,1,0, 498 | 0,1,0,1,1, 499 | 1,1,0,0,1, 500 | #108 l 501 | 0,1,1,0,0, 502 | 0,0,1,0,0, 503 | 0,0,1,0,0, 504 | 0,0,1,0,0, 505 | 1,1,1,1,1, 506 | #10 m 507 | 1,0,0,0,0, 508 | 1,1,1,1,1, 509 | 1,0,1,0,1, 510 | 1,0,1,0,1, 511 | 1,0,1,0,1, 512 | #110 n 513 | 1,0,0,0,0, 514 | 1,1,1,1,0, 515 | 1,0,0,1,0, 516 | 1,0,0,1,0, 517 | 1,0,0,1,1, 518 | #111 o 519 | 0,0,1,0,0, 520 | 0,1,1,1,0, 521 | 1,1,0,1,1, 522 | 0,1,1,1,0, 523 | 0,0,1,0,0, 524 | #112 p 525 | 1,1,1,1,0, 526 | 1,1,0,1,1, 527 | 1,1,1,1,0, 528 | 1,0,0,0,0, 529 | 1,1,0,0,0, 530 | #113 q 531 | 0,1,1,1,1, 532 | 1,1,0,1,1, 533 | 0,1,1,1,1, 534 | 0,0,0,0,1, 535 | 0,0,0,1,1, 536 | #114 r 537 | 1,1,0,1,1, 538 | 0,1,1,1,1, 539 | 0,1,0,0,1, 540 | 0,1,0,0,0, 541 | 1,1,1,0,0, 542 | #115 s 543 | 0,1,0,0,0, 544 | 1,1,0,0,0, 545 | 0,1,1,1,0, 546 | 0,0,0,1,1, 547 | 1,1,1,1,0, 548 | #116 t 549 | 0,0,1,0,0, 550 | 0,0,1,0,0, 551 | 1,1,1,1,1, 552 | 0,0,1,0,0, 553 | 0,0,1,1,1, 554 | #117 u 555 | 1,0,0,1,1, 556 | 1,0,0,1,0, 557 | 1,0,0,1,0, 558 | 1,0,0,1,0, 559 | 1,1,1,1,1, 560 | #118 v 561 | 1,1,0,1,1, 562 | 1,0,0,0,1, 563 | 1,1,0,1,1, 564 | 0,1,1,1,0, 565 | 0,0,1,0,0, 566 | #119 w 567 | 0,0,1,0,0, 568 | 1,0,1,0,1, 569 | 1,0,1,0,1, 570 | 1,1,1,1,1, 571 | 0,1,0,1,0, 572 | #120 x 573 | 1,1,0,1,1, 574 | 0,1,1,1,0, 575 | 0,0,1,0,0, 576 | 0,1,1,1,0, 577 | 1,1,0,1,1, 578 | #121 y 579 | 1,1,0,1,1, 580 | 0,1,0,1,0, 581 | 0,1,1,1,0, 582 | 0,0,1,1,0, 583 | 1,1,1,0,0, 584 | #122 z 585 | 1,1,1,1,1, 586 | 0,0,0,1,1, 587 | 0,1,1,1,0, 588 | 1,1,0,0,0, 589 | 1,1,1,1,1, 590 | #123 { 591 | 0,0,1,1,0, 592 | 0,0,1,0,0, 593 | 0,1,1,0,0, 594 | 0,0,1,0,0, 595 | 0,0,1,1,0, 596 | #124 | 597 | 0,0,1,1,0, 598 | 0,0,1,1,0, 599 | 0,0,1,1,0, 600 | 0,0,1,1,0, 601 | 0,0,1,1,0, 602 | #125 } 603 | 0,1,1,0,0, 604 | 0,0,1,0,0, 605 | 0,0,1,1,0, 606 | 0,0,1,0,0, 607 | 0,1,1,0,0, 608 | #126 ~ 609 | 0,0,0,0,0, 610 | 1,1,0,0,0, 611 | 0,1,1,1,0, 612 | 0,0,0,1,1, 613 | 0,0,0,0,0, 614 | #127 615 | 0,0,0,0,0, 616 | 0,0,0,0,0, 617 | 0,0,0,0,0, 618 | 0,0,0,0,0, 619 | 0,0,0,0,0 620 | ] 621 | 622 | 623 | 624 | -------------------------------------------------------------------------------- /lib/matrix.py: -------------------------------------------------------------------------------- 1 | 2 | #Copyright (c) 2020 stonatm@gmail.com 3 | #m5atom matrix 4 | #neopixel 5x5 matrix library V2 with text scrolling 5 | #HSV color model 6 | 7 | from machine import Pin 8 | import neopixel 9 | import time 10 | import math 11 | import font 12 | 13 | class matrix: 14 | 15 | # m5atom matrix hardware specific values 16 | LED_PIN = 27 17 | LED_WIDTH = 5 18 | LED_HEIGHT = 5 19 | LED_NUM = LED_WIDTH * LED_HEIGHT 20 | LED_BRIGHTNESS = 0.25 #max led brightness due to heating up to high temperature 21 | INSTA_DRAW = 0 22 | np = None 23 | 24 | #color in hsv color model color(h, s, v) 25 | #h = 0 - 360 26 | #s = 0 - 1.0 27 | #v = 0 - 1.0 28 | color = (0, 0, 1 * LED_BRIGHTNESS) #initial set color to white 29 | 30 | def init(): 31 | matrix.np = neopixel.NeoPixel(Pin(matrix.LED_PIN), matrix.LED_NUM) 32 | 33 | def translate(value, inMin, inMax, outMin, outMax): 34 | return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin 35 | 36 | #convert color from hsv to rgb 37 | def hsv(h, s=1, v=1): 38 | h = float(h) 39 | s = float(s) 40 | v = float(v) 41 | h60 = h / 60.0 42 | h60f = math.floor(h60) 43 | hi = int(h60f) % 6 44 | f = h60 - h60f 45 | p = v * (1 - s) 46 | q = v * (1 - f * s) 47 | t = v * (1 - (1 - f) * s) 48 | r, g, b = 0, 0, 0 49 | if hi == 0: r, g, b = v, t, p 50 | elif hi == 1: r, g, b = q, v, p 51 | elif hi == 2: r, g, b = p, v, t 52 | elif hi == 3: r, g, b = p, q, v 53 | elif hi == 4: r, g, b = t, p, v 54 | elif hi == 5: r, g, b = v, p, q 55 | r, g, b = int(r * 255), int(g * 255), int(b * 255) 56 | return r, g, b 57 | 58 | #set color used to draw function 59 | def pixel_color(h, s=1, v=1): 60 | matrix.color = (h, s, v * matrix.LED_BRIGHTNESS) 61 | 62 | def pixel_set(x, y): 63 | matrix.np[x + y * matrix.LED_HEIGHT] = matrix.hsv(*matrix.color) 64 | if matrix.INSTA_DRAW: matrix.show() 65 | 66 | def pixel_clear(x, y): 67 | matrix.np[x + y * matrix.LED_HEIGHT] = (0, 0, 0) 68 | if matrix.INSTA_DRAW: matrix.show() 69 | 70 | def pixel_blink(x, y, delay_ms=100 ): 71 | previous = matrix.np[x + y * matrix.LED_HEIGHT] 72 | matrix.np[x + y * matrix.LED_HEIGHT] = matrix.hsv(*matrix.color) 73 | matrix.np.write() 74 | time.sleep_ms( delay_ms ) 75 | matrix.np[x + y * matrix.LED_HEIGHT] = previous 76 | matrix.np.write() 77 | 78 | def clear_all(): 79 | matrix.np.fill((0,0,0)) 80 | if matrix.INSTA_DRAW: matrix.show() 81 | 82 | def show(): 83 | matrix.np.write() 84 | 85 | #write raw rgb value buffer to matrix 86 | def write_buffer(buf): 87 | size = matrix.LED_NUM 88 | if len(buf) < matrix.LED_NUM: 89 | size = len(buf) 90 | for pix in range (0, size): 91 | matrix.np[pix] = buf[pix] 92 | if matrix.INSTA_DRAW: matrix.show() 93 | 94 | def pixel_breathe(x, y, ms_in=50, ms_out=50): 95 | for i in range (0, 11, 1): 96 | val = math.pow(2, i) - 1 97 | matrix.np[x + y * matrix.LED_HEIGHT] = matrix.hsv(matrix.color[0], matrix.color[1], (matrix.LED_BRIGHTNESS * matrix.translate(val, 0, 1024, 0, 1)) ) 98 | matrix.np.write() 99 | time.sleep_ms(ms_in) 100 | for i in range (10, -1, -1): 101 | val = math.pow(2, i) - 1 102 | matrix.np[x + y * matrix.LED_HEIGHT] = matrix.hsv(matrix.color[0], matrix.color[1], (matrix.LED_BRIGHTNESS * matrix.translate(val, 0, 1024, 0, 1)) ) 103 | matrix.np.write() 104 | time.sleep_ms(ms_out) 105 | 106 | def pixel_mask(buf): 107 | size = matrix.LED_NUM 108 | if len(buf) < matrix.LED_NUM: 109 | size = len(buf) 110 | for pix in range (0, size): 111 | if buf[pix]: 112 | matrix.np[pix] = matrix.hsv(*matrix.color) 113 | if matrix.INSTA_DRAW: matrix.show() 114 | 115 | def _add(a,b): 116 | w_a = int(len(a)/5) 117 | w_b = int(len(b)/5) 118 | out = [0] *len(a) 119 | for i in range(len(a)): 120 | out[i] = a[i] 121 | for i in range(5): 122 | out[(i*w_a+i*w_b):(i*w_a+i*w_b)] = b[(i*w_b):((i+1)*w_b)] 123 | return out 124 | 125 | def _get_frame(buffer, offest): 126 | w_buf = int(len(buffer)/5) 127 | out = [0] *25 128 | for x in range (5): 129 | for y in range (5): 130 | out[x + y * 5] = buffer[(x+offest)+(y*w_buf)] 131 | return out 132 | 133 | def _create_pixmap(input): 134 | spacer = [0] *5 135 | empty = [0] *25 136 | text_buffer = [0] *25 137 | for i in range (len(input)): 138 | text_buffer = matrix._add(text_buffer, font.get_letter( ord( input[len(input)-1-i] ) ) ) 139 | text_buffer = matrix._add(text_buffer, spacer) 140 | text_buffer = matrix._add(text_buffer, empty) 141 | return text_buffer 142 | 143 | def text_scroll(text_to_scroll, delay=150): 144 | t_buf = matrix._create_pixmap(text_to_scroll) 145 | #scrolling pixmap on matrix 146 | for pos in range ( int(len(t_buf)/5) -5 +1 ): 147 | matrix.clear_all() 148 | matrix.pixel_mask(matrix._get_frame(t_buf, pos) ) 149 | matrix.show() 150 | time.sleep_ms(delay) 151 | 152 | 153 | -------------------------------------------------------------------------------- /schema.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stonatm/M5Atom_matrix_library/54c27ce9544a03284f3434673c1a9709236fc730/schema.jpg -------------------------------------------------------------------------------- /smile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stonatm/M5Atom_matrix_library/54c27ce9544a03284f3434673c1a9709236fc730/smile.png -------------------------------------------------------------------------------- /termo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stonatm/M5Atom_matrix_library/54c27ce9544a03284f3434673c1a9709236fc730/termo.jpg -------------------------------------------------------------------------------- /termo.py: -------------------------------------------------------------------------------- 1 | #m5atom matrix termometer example with ds18b20 sensor 2 | #this example is only an idea, not a final code 3 | #its simple example display only positive temperature 4 | # from 0 to 99 degrees (two digits) only 5 | #negative temperatures or greater than 99 can cause errors. 6 | 7 | #sensor connect schema to atom 8 | # 1 GND to GND 9 | # 2 DQ to GPIO25 10 | # 3 VCC to GPIO21 11 | # connect 2.2 - 4.7 kohm resistor betwen DQ and VCC 12 | 13 | import dallas 14 | import matrix 15 | import digits 16 | import time 17 | 18 | from machine import Pin 19 | 20 | l = matrix.matrix 21 | d = digits 22 | t = dallas.ds18b20 23 | 24 | #ds18b20 data pin 25 | DS_PIN = 25 26 | #main loop delay minimum 750ms for correct reads from sensor 27 | LOOP_DELAY = 1000 28 | 29 | #initialize matrix 30 | l.init() 31 | l.clear_all() 32 | 33 | #set gpio 21 as power line for temperature sensor 34 | power = Pin(21,Pin.OUT) 35 | power.value(1) 36 | 37 | #initialise temperature sensor 38 | #and do first temperature measure 39 | t.init(DS_PIN) 40 | t.convert(DS_PIN) 41 | #wait minimum 750ms betwen measure and read temperature 42 | time.sleep_ms(750) 43 | 44 | while 1: 45 | #read temperature from sensor 46 | temp_f = t.read(DS_PIN) 47 | temp = int(temp_f) 48 | d1 = int(temp/10) 49 | d2 = temp%10 50 | 51 | #debug line 52 | print(temp_f,temp,d1,d2) 53 | 54 | l.clear_all() 55 | l.show() 56 | #show left digit 57 | l.pixel_color(60) 58 | l.pixel_mask(d.digits_left[d1*25:]) 59 | l.show() 60 | #show right digit 61 | l.pixel_color(120) 62 | l.pixel_mask(d.digits_right[d2*25:]) 63 | l.show() 64 | 65 | #start measure temperature 66 | t.convert(DS_PIN) 67 | #wait minimum 750ms 68 | time.sleep_ms(LOOP_DELAY) 69 | --------------------------------------------------------------------------------