Outils pour utilisateurs

Outils du site


issue177:micro-ci_micro-la

Well, it’s been almost a year since I’ve started this column. I hope that this has been helpful to those of you who are interested in microcontrollers. Once again, we will deal with the SSD1306 display, but this time we will be talking about creating custom fonts. This time, we are going to (as the subtitle suggests) create special fonts for use on our OLED display. For the most part, the code should work fine on the Raspberry Pi Pico, ESP32 and ESP8266. The only concern might be the memory usage due to the size of the font files. Back in issue Full Circle Magazine issue #172 Part 6, I introduced the Micropython Font To Py library from Peter Hinch, but only a small part of that package. We used a couple of his fonts and his writer library. If you didn’t get it then, here is where you can get it. https://github.com/peterhinch/micropython-font-to-py

Cela fait presque un an que j'ai commencé cette rubrique. J'espère qu'elle a été utile à ceux d'entre vous qui s'intéressent aux microcontrôleurs.

Une fois de plus, nous allons traiter de l'écran SSD1306, mais cette fois-ci, nous allons parler de la création de polices personnalisées. Cette fois, nous allons (comme le sous-titre le suggère) créer des polices spéciales à utiliser sur notre écran OLED. Dans l'ensemble, le code devrait fonctionner correctement sur les Raspberry Pi Pico, ESP32 et ESP8266. Le seul problème pourrait être l'utilisation de la mémoire en raison de la taille des fichiers de police.

Dans le numéro 172 du Full Circle Magazine, partie 6 de la rubrique, j'ai présenté la bibliothèque Micropython Font To Py de Peter Hinch, mais seulement une petite partie de ce paquet. Nous avons utilisé quelques-unes de ses polices et sa bibliothèque writer. Si vous ne l'avez pas encore récupérée, voici où vous pouvez l'obtenir. https://github.com/peterhinch/micropython-font-to-py

This time, we’ll be creating our own fonts for the OLED display using our normal desktop computers and regular Python. Once we have the fonts created and tested, we will transfer them to the microcontroller and use a simple test program there. For this project, we’ll use the Raspberry Pi Pico microcontroller and a SSD1306 128×64 OLED Display. Below is a picture showing the wiring just in case you need it. And here is the wiring grid. Next, you will want to download and unpack the micropython-font-to-py package into a folder and then create a folder somewhere to serve as your work folder. You will want to copy (at a minimum) the font_to_py.py, font_test.py, writer.py and the ssd1306_setup.py files into your working folder. If you followed along back in part 6, you probably have the writer.py file and the ssd1306_setup.py file.

Cette fois-ci, nous allons créer nos propres polices pour l'écran OLED à l'aide de nos ordinateurs de bureau habituels et de Python. Une fois les polices créées et testées, nous les transférerons sur le microcontrôleur et utiliserons un programme de test simple.

Pour ce projet, nous utiliserons le microcontrôleur Raspberry Pi Pico et un écran OLED SSD1306 128×64. Vous trouverez ci-dessous une image montrant le câblage, au cas où vous en auriez besoin.

Et voici la grille de câblage.

Ensuite, vous devez télécharger et décompresser le paquet micropython-font-to-py dans un dossier, puis créer un dossier quelque part qui servira de dossier de travail. Vous voudrez copier (au minimum) les fichiers font_to_py.py, font_test.py, writer.py et ssd1306_setup.py dans votre dossier de travail. Si vous avez suivi la partie 6, vous avez probablement le fichier writer.py et le fichier ssd1306_setup.py.

You need to modify the ssd1306_setup.py file to make it support our Pico I2C setup. There are only a couple of places that you need to change, though. Near the top of the file, after the comments, you will find the following lines of code. import machine from ssd1306 import SSD1306_SPI, SSD1306_I2C WIDTH = const(128) HEIGHT = const(64) You need to change the WIDTH and HEIGHT to match your display. While you CAN use a smaller OLED display (128×32 pixels), you will have to modify the code later on since it assumes you have 64 rows of pixels to make the text fit. Now at the bottom of the file, you will see the following lines of code. Make sure you change the i2c = machine.I2C(2) to i2c = machine.I2C(0) else: # i2c = machine.I2C(2) i2c = machine.I2C(0) ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c) return ssd

Vous devez modifier le fichier ssd1306_setup.py pour qu'il supporte la configuration I2C de notre Pico. Cependant, il n'y a que quelques endroits que vous devez changer. Vers le haut du fichier, après les commentaires, vous trouverez les lignes de code suivantes :

import machine

from ssd1306 import SSD1306_SPI, SSD1306_I2C

WIDTH = const(128)

HEIGHT = const(64)

Vous devez modifier WIDTH et HEIGHT pour qu'elles correspondent à votre écran. Il est possible d'utiliser un écran OLED plus petit (128×32 pixels), mais vous devrez modifier le code plus tard car il suppose que vous faites tenir le texte sur 64 rangées de pixels.

Maintenant, au bas du fichier, vous verrez les lignes de code suivantes. Assurez-vous de changer le i2c = machine.I2C(2) en i2c = machine.I2C(0) :

else:

 # i2c = machine.I2C(2)
 i2c = machine.I2C(0)
 ssd = SSD1306_I2C(WIDTH, HEIGHT, i2c)

return ssd

Save your file. Copy the Writer.py and ssd1306_setup.py file to the Pico, if they are not already there. Now we can create our special font files. The idea is to convert a font from your system to a file that Micropython can use. In this article we’ll use the Ubuntu-Regular ttf file. You should have it on your normal desktop/laptop system. If not, you can find it on the Internet. In order to use the conversion utility, you need to have the freetype library installed on your desktop or laptop (not on your Microcontroller). You can install it easily by using pip install freetype-py Or pip3 install freetype-py Now that we have all our dependencies taken care of, we can start to work with the font_to_py program. You need to be working in a terminal session for the next steps. The command line should be font_to_py.py {full path to font file} {size} {-x} {file name to save to}

Enregistrez votre fichier. Copiez les fichiers Writer.py et ssd1306_setup.py sur le Pico, s'ils n'y sont pas déjà.

Nous pouvons maintenant créer nos fichiers de police spéciaux. L'idée est de convertir une police de votre système en un fichier que Micropython peut utiliser. Dans cet article, nous allons utiliser le fichier ttf Ubuntu Regular. Vous devriez l'avoir sur votre système normal de bureau/portable. Si ce n'est pas le cas, vous pouvez le trouver sur l'Internet.

Pour pouvoir utiliser l'utilitaire de conversion, vous devez avoir installé la bibliothèque freetype sur votre ordinateur de bureau ou portable (pas sur votre microcontrôleur). Vous pouvez l'installer facilement en utilisant :

pip install freetype-py

ou :

pip3 install freetype-py

Maintenant que nous nous sommes occupés de toutes nos dépendances, nous pouvons commencer à travailler avec le programme font_to_py. Vous devez travailler dans une session de terminal pour les étapes suivantes.

La ligne de commande doit être :

font_to_py.py {chemin complet du fichier de polices} {taille} {-x} {nom du fichier à sauvegarder}

You MUST include a fully qualified path to the font you want to use. On my system there are two font locations. The first in /usr/share/fonts/truetype (for the truetype fonts) and then each font has its own folder. The second is a hidden folder in my home directory and is named .fonts. I keep speciality fonts in this one. Either path is seen by my system as a font folder. You can use pretty much any .ttf font, but I don’t really see any reason to fool with fonts too fancy or too big or small, so that’s why I chose Ubuntu-Regular. You also need to be sure to include the -x parameter when you create the font file. This makes sure that the font is horizontally mapped. This information is not included in the readme directly and it took me the better part of an hour to break everything down to understand why my fonts were not working. Here is the terminal session that I did when I created my font. We will be creating a 12 point font, so I saved it as ubuntu12.py. $ python font_to_py.py /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf 12 -x ubuntu12.py Writing Python font file. Height set in 1 passes. Actual height 12 pixels. Max character width 11 pixels. ubuntu12.py written successfully.

Il est OBLIGATOIRE d'inclure un chemin d'accès complet à la police que vous souhaitez utiliser. Sur mon système, il y a deux emplacements pour les polices. Le premier est dans /usr/share/fonts/truetype (pour les polices truetype) et ensuite chaque police a son propre dossier. Le second est un dossier caché dans mon répertoire personnel qui s'appelle .fonts. Je garde les polices spéciales dans ce dossier. L'un ou l'autre chemin est vu par mon système comme un dossier de polices. Vous pouvez utiliser à peu près n'importe quelle police .ttf, mais je ne vois vraiment pas de raison de m'amuser avec des polices trop fantaisistes, trop grandes ou trop petites, c'est pourquoi j'ai choisi Ubuntu Regular.

Vous devez également vous assurer d'inclure le paramètre -x lorsque vous créez le fichier de police. Cela permet de s'assurer que la police est mappée horizontalement. Cette information n'est pas incluse directement dans le fichier readme et il m'a fallu près d'une heure pour tout décortiquer et comprendre pourquoi mes polices ne fonctionnaient pas. Voici la session de terminal que j'ai effectuée lorsque j'ai créé ma police. Nous allons créer une police de 12 points, je l'ai donc enregistrée sous le nom de ubuntu12.py.

$ python font_to_py.py /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf 12 -x ubuntu12.py

Writing Python font file.

Height set in 1 passes. Actual height 12 pixels.

Max character width 11 pixels.

ubuntu12.py written successfully.

Now we can see that the characters are 12 pixels in height and the width is 11 pixels. This will help decide how many characters you can fit on a line and how many lines you can fit on the 128×64 display. Now that we have the font created, let’s do a quick test. Peter has provided a utility to do just that. It’s called font_test.py. You provide the font name as the first parameter and what you want to view as the second. Here is the terminal output that I got. $ python font_test.py ubuntu12 Hello Horizontal map Normal bit order Proportional spacing Dimensions height*max_width 12 * 11 Start char “ ” (ord 32) end char “~” (ord 126) ………………………. …………….#..#…….. .#….#………#..#…….. .#….#………#..#…….. .#….#…###…#..#…###.. .######..#…#..#..#..#…#. .#….#..#####..#..#..#…#. .#….#..#……#..#..#…#. .#….#..#……#..#..#…#. .#….#…####…#..#..###.. ………………………. ………………………. Now we need to do the same thing but this time make the font a 16 point font. We’ll keep the font as Ubuntu-Regular.

Nous pouvons maintenant voir que les caractères ont une hauteur de 12 pixels et une largeur de 11 pixels. Cela nous aidera à déterminer le nombre de caractères que vous pouvez faire tenir sur une ligne et le nombre de lignes que vous pouvez faire tenir sur l'écran 128×64. Maintenant que nous avons créé la police, nous allons faire un test rapide. Peter a fourni un utilitaire pour faire cela. Il s'appelle font_test.py. Vous fournissez le nom de la police comme premier paramètre et ce que vous voulez afficher comme deuxième paramètre. Voici la sortie du terminal que j'ai obtenue :

$ python font_test.py ubuntu12 Hello

Horizontal map

Normal bit order

Proportional spacing

Dimensions height*max_width 12 * 11

Start char “ ” (ord 32) end char “~” (ord 126)

……………………….

…………….#..#…….. .#….#………#..#…….. .#….#………#..#…….. .#….#…###…#..#…###.. .######..#…#..#..#..#…#. .#….#..#####..#..#..#…#. .#….#..#……#..#..#…#. .#….#..#……#..#..#…#. .#….#…####…#..#..###.. ………………………. ……………………….

Maintenant, nous devons faire la même chose, mais cette fois-ci en utilisant une police de 16 points. Nous allons garder la police Ubuntu Regular.

$ python font_to_py.py /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf 16 -x ubuntu16.py Writing Python font file. Height set in 1 passes. Actual height 16 pixels. Max character width 15 pixels. ubuntu16.py written successfully. Now let’s test the 16 point font file. $ python font_test.py ubuntu16 HelloHorizontal map Normal bit order Proportional spacing Dimensions height*max_width 16 * 15 Start char “ ” (ord 32) end char “~” (ord 126) ……………………………….. …………………#…#………… .#…….#………..#…#………… .#…….#………..#…#………… .#…….#………..#…#………… .#…….#….###….#…#…..####… .#…….#…#…#…#…#….#….#.. .#########..#…..#..#…#…#……#. .#…….#..#######..#…#…#……#. .#…….#..#……..#…#…#……#. .#…….#..#……..#…#…#……#. .#…….#…#…….#…#….#….#.. .#…….#….####….##..##…####… ……………………………….. ……………………………….. ………………………………..

$ python font_to_py.py /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf 16 -x ubuntu16.py

Writing Python font file.

Height set in 1 passes. Actual height 16 pixels.

Max character width 15 pixels.

ubuntu16.py written successfully.

Maintenant, testons le fichier de police 16 points.

$ python font_test.py ubuntu16 Hello

Horizontal map

Normal bit order

Proportional spacing

Dimensions height*max_width 16 * 15

Start char “ ” (ord 32) end char “~” (ord 126)

……………………………….. …………………#…#………… .#…….#………..#…#………… .#…….#………..#…#………… .#…….#………..#…#………… .#…….#….###….#…#…..####… .#…….#…#…#…#…#….#….#.. .#########..#…..#..#…#…#……#. .#…….#..#######..#…#…#……#. .#…….#..#……..#…#…#……#. .#…….#..#……..#…#…#……#. .#…….#…#…….#…#….#….#.. .#…….#….####….##..##…####… ……………………………….. ……………………………….. ………………………………..

In case you are curious about what the font file looks like, it’s a “normal” python file that contains the font definitions in byte format. You can certainly take a look at it, just be sure not to make any changes. Now we need to transfer the font files and write our test code on the Pico Microcontroller. I connected my Pico to the USB port and brought up Thonny. Since I’ve been working with my ESP32 and my ESP8266, I needed to click on the bottom right corner to make sure it was connected to the RPi Pico. I used the File | Open menu command and selected “This computer”. I navigated to where I had created and saved the font files and transferred the ubuntu12.py file first. Once it was displayed in an editor window, I selected File | Save Copy and this time selected “Raspberry Pi Pico” and then named the file ubuntu12.py. I repeated the process with the 16 point font, saving it as ubuntu16.py. Now open a new editor tab in Thonny and we’ll start writing the code for the Pico. First, we’ll (as always) setup the imports. import machine from ssd1306_setup import WIDTH, HEIGHT, setup from writer import Writer import time

Au cas où vous seriez curieux de savoir à quoi ressemble le fichier de police, il s'agit d'un fichier python « normal » qui contient les définitions des polices au format octet. Vous pouvez certainement y jeter un coup d'œil, mais veillez à ne pas le modifier.

Maintenant, nous devons transférer les fichiers de police et écrire notre code de test sur le microcontrôleur Pico.

J'ai connecté mon Pico au port USB et j'ai lancé Thonny. Comme j'ai travaillé avec mon ESP32 et mon ESP8266, j'ai dû cliquer sur le coin inférieur droit pour m'assurer qu'il était connecté au RPi Pico.

J'ai utilisé la commande du menu File | Open et sélectionné « This computer ». J'ai navigué jusqu'à l'endroit où j'avais créé et enregistré les fichiers de police et j'ai transféré le fichier ubuntu12.py en premier. Une fois qu'il s'est affiché dans une fenêtre d'édition, j'ai sélectionné la commande de menu File | Save Copy et, cette fois, j'ai choisi « Raspberry Pi Pico », puis j'ai nommé le fichier ubuntu12.py. J'ai répété le processus avec la police 16 points, en l'enregistrant sous le nom de ubuntu16.py.

Maintenant, ouvrez un nouvel onglet d'édition dans Thonny et nous allons commencer à écrire le code pour le Pico. Tout d'abord, nous allons (comme toujours) configurer les importations :

import machine

from ssd1306_setup import WIDTH, HEIGHT, setup

from writer import Writer

import time

# Font import ubuntu12 import ubuntu16 Now we’ll create a very simple function that does major work for us. We’ll call it “test”. Within the function, we’ll start by calling the setup function from ssd1306_setup which will make our I2C connections for us and then tell the Writer function to use the ubuntu12 font we just created. Then we’ll set the text position to 0,0 (row and column) and print two lines of the uppercase alphabet, first from A to N then from O to Z on the second line. Next we’ll print a line containing the numbers from 1 to 0. Finally we’ll print two more lines, this time with the alphabet in lowercase. Just before we send a string to the display, we will increment the row number by 12. The row numbers would be 0, 12, 24, 36 and 48. We finish up with making a call to ssd.show() in order to actually display the data we just sent and then we’ll sleep for 3 seconds and after the 3 second delay, we’ll clear the display with ssd.fill(0) which turns off all the pixels. Next, we’ll display the same data in the 16 point font. Because the font is 16 point, we can’t fit all of the text in one screen like we did with the 12 point font. We’ll break it into two parts, the first two lines of alphabet characters, the numbers 1 to 0 and then some shifted characters. Notice we also have to shift some of the characters from one line to another to get it all to fit. We’ll push the data to the display to show it, sleep for another 3 seconds and then clear the display screen again.

# Font

import ubuntu12

import ubuntu16

Maintenant, nous allons créer une fonction très simple qui fait le gros du travail pour nous. Nous l'appellerons « test ».

Dans cette fonction, nous commencerons par appeler la fonction setup de ssd1306_setup qui fera nos connexions I2C pour nous et dira à la fonction Writer d'utiliser la police ubuntu12 que nous venons de créer. Ensuite, nous allons définir la position du texte à 0,0 (ligne et colonne) et imprimer deux lignes de l'alphabet en majuscules, d'abord de A à N, puis de O à Z sur la deuxième ligne. Puis, nous imprimerons une ligne contenant les chiffres de 1 à 0. Enfin, nous imprimerons deux autres lignes, cette fois avec l'alphabet en minuscules. Juste avant d'envoyer une chaîne à l'écran, nous incrémenterons le numéro de ligne de 12. Les numéros de ligne seront 0, 12, 24, 36 et 48.

Nous terminons par un appel à ssd.show() afin d'afficher réellement les données que nous venons d'envoyer, puis nous dormirons pendant 3 secondes et après ce délai de 3 secondes, nous effacerons l'affichage avec ssd.fill(0) qui éteint tous les pixels.

Ensuite, nous afficherons les mêmes données dans une police de 16 points. Comme la police est de 16 points, nous ne pouvons pas faire tenir tout le texte sur un seul écran comme nous le faisions avec la police de 12 points. Nous allons le diviser en deux parties, les deux premières lignes de caractères de l'alphabet, les chiffres 1 à 0 et ensuite quelques caractères décalés. Remarquez que nous devons également décaler certains caractères d'une ligne à l'autre pour que le tout tienne. Nous enverrons les données vers l'écran pour les afficher, nous resterons en veille pendant 3 secondes et nous effacerons l'écran à nouveau.

wri = Writer(ssd, ubuntu16) Writer.set_textpos(ssd,0,0) wri.printstring('ABCDEFGHIJKLM') Writer.set_textpos(ssd,16,0) wri.printstring('NOPQRSTUVWXY') Writer.set_textpos(ssd,32,0) wri.printstring('Z - 1234567890') Writer.set_textpos(ssd,48,0) wri.printstring('!@#$%^&*()_+=-') ssd.show() time.sleep(3) ssd.fill(0) Finally we’ll send out the lower case characters in the 16 point font as we did above. We sleep again for 3 seconds, then clear the display to avoid burnin.

wri = Writer(ssd, ubuntu16)

Writer.set_textpos(ssd,0,0)

wri.printstring('ABCDEFGHIJKLM')

Writer.set_textpos(ssd,16,0)

wri.printstring('NOPQRSTUVWXY')

Writer.set_textpos(ssd,32,0)

wri.printstring('Z - 1234567890')

Writer.set_textpos(ssd,48,0)

wri.printstring('!@#$%^&*()_+=-')

ssd.show()
time.sleep(3)
ssd.fill(0)

Enfin, nous envoyons les caractères minuscules dans la police 16 points comme nous l'avons fait ci-dessus. On se remet en veille pendant 3 secondes, puis on efface l'écran pour éviter les brûlures.

Writer.set_textpos(ssd,0,0) wri.printstring('abcdefghijklm') Writer.set_textpos(ssd,18,0) wri.printstring('nopqrstuvwxyz') ssd.show() time.sleep(3) ssd.fill(0) ssd.show() Finally, we call the function from code to get it all to start. test() That’s it. Save the program as ubuntutest.py. Now when we run the program you can see the result of the hard work. I’ve put the font files and the code files on my repository at https://github.com/gregwa1953/FCM-177_MicroThisMicroThat At this point, you should be able to pick a font of your choice and convert it to run on your microcontroller to support your own programs. Until next time, as always; stay safe, healthy, positive and creative!

Writer.set_textpos(ssd,0,0)

wri.printstring('abcdefghijklm')

Writer.set_textpos(ssd,18,0)

wri.printstring('nopqrstuvwxyz')

ssd.show()
time.sleep(3)
ssd.fill(0)
ssd.show()

Enfin, nous appelons la fonction du code pour que tout démarre :

test()

C'est tout. Enregistrez le programme sous le nom de ubuntutest.py.

Maintenant, lorsque nous exécutons le programme, vous pouvez voir le résultat de ce dur labeur.

J'ai mis les fichiers de police et les fichiers de code sur mon dépôt à https://github.com/gregwa1953/FCM-177_MicroThisMicroThat.

À ce stade, vous devriez être en mesure de choisir une police de votre choix et de la convertir pour qu'elle fonctionne sur votre microcontrôleur en support de vos propres programmes.

Jusqu'à la prochaine fois, comme toujours, restez en sécurité, en bonne santé, positif et créatif !

issue177/micro-ci_micro-la.txt · Dernière modification : 2022/02/02 09:04 de d52fr