MicroPython : SSD1306 Fonctions de défilement de l’écran OLED et formes de dessin

MicroPython : SSD1306 Fonctions de défilement de l'écran OLED et formes de dessin

Ce guide présente des fonctions supplémentaires pour contrôler un écran OLED avec MicroPython à l’aide de l’ESP32 ou de l’ESP8266. Vous apprendrez à faire défiler tout l’écran horizontalement et verticalement et à dessiner des formes.

MicroPython : SSD1306 Fonctions de défilement de l'affichage OLED et formes de dessin ESP32 ESP8266

Nous vous recommandons de suivre ce guide de démarrage pour l’écran OLED avec MicroPython, en premier lieu : Écran OLED MicroPython avec ESP32 et ESP8266.

Conditions préalables

Pour suivre ce tutoriel, vous avez besoin du firmware MicroPython installé dans vos cartes ESP32 ou ESP8266. Vous avez également besoin d’un IDE pour écrire et télécharger le code sur votre carte. Nous vous suggérons d’utiliser Thonny IDE ou uPyCraft IDE :

En savoir plus sur MicroPython : eBook sur la programmation MicroPython avec ESP32 et ESP8266

Pièces requises

Voici une liste des pièces dont vous avez besoin pour ce tutoriel :

Vous pouvez utiliser les liens précédents ou aller directement sur MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

MicroPython SSD1306 Fonctions de defilement de lecran OLED et formes

Schéma – ESP32

Suivez le schéma suivant si vous utilisez une carte ESP32 :

Écran OLED SSD1306 avec circuit de diagramme schématique ESP32 MicroPython I2C SCL SDA

Lecture recommandée: Guide de référence du brochage ESP32

Schéma – ESP8266 NodeMCU

Suivez le schéma suivant si vous utilisez une carte ESP8266 NodeMCU :

Écran OLED SSD1306 avec ESP8266 NodeMCU MicroPython schéma du circuit I2C SCL SDA

Lecture recommandée: Guide de référence du brochage ESP8266

Bibliothèque OLED SSD1306

La bibliothèque pour écrire sur l’écran OLED ne fait pas partie de la bibliothèque MicroPython standard par défaut. Vous devez donc télécharger la bibliothèque sur votre carte ESP32/ESP8266.

#MicroPython SSD1306 OLED driver, I2C and SPI interfaces created by Adafruit

import time
import framebuf

# register definitions
SET_CONTRAST        = const(0x81)
SET_ENTIRE_ON       = const(0xa4)
SET_NORM_INV        = const(0xa6)
SET_DISP            = const(0xae)
SET_MEM_ADDR        = const(0x20)
SET_COL_ADDR        = const(0x21)
SET_PAGE_ADDR       = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP       = const(0xa0)
SET_MUX_RATIO       = const(0xa8)
SET_COM_OUT_DIR     = const(0xc0)
SET_DISP_OFFSET     = const(0xd3)
SET_COM_PIN_CFG     = const(0xda)
SET_DISP_CLK_DIV    = const(0xd5)
SET_PRECHARGE       = const(0xd9)
SET_VCOM_DESEL      = const(0xdb)
SET_CHARGE_PUMP     = const(0x8d)


class SSD1306:
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        # Note the subclass must initialize self.framebuf to a framebuffer.
        # This is necessary because the underlying data buffer is different
        # between I2C and SPI implementations (I2C needs an extra byte).
        self.poweron()
        self.init_display()

    def init_display(self):
        for cmd in (
            SET_DISP | 0x00, # off
            # address setting
            SET_MEM_ADDR, 0x00, # horizontal
            # resolution and layout
            SET_DISP_START_LINE | 0x00,
            SET_SEG_REMAP | 0x01, # column addr 127 mapped to SEG0
            SET_MUX_RATIO, self.height - 1,
            SET_COM_OUT_DIR | 0x08, # scan from COM[N] to COM0
            SET_DISP_OFFSET, 0x00,
            SET_COM_PIN_CFG, 0x02 if self.height == 32 else 0x12,
            # timing and driving scheme
            SET_DISP_CLK_DIV, 0x80,
            SET_PRECHARGE, 0x22 if self.external_vcc else 0xf1,
            SET_VCOM_DESEL, 0x30, # 0.83*Vcc
            # display
            SET_CONTRAST, 0xff, # maximum
            SET_ENTIRE_ON, # output follows RAM contents
            SET_NORM_INV, # not inverted
            # charge pump
            SET_CHARGE_PUMP, 0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01): # on
            self.write_cmd(cmd)
        self.fill(0)
        self.show()

    def poweroff(self):
        self.write_cmd(SET_DISP | 0x00)

    def contrast(self, contrast):
        self.write_cmd(SET_CONTRAST)
        self.write_cmd(contrast)

    def invert(self, invert):
        self.write_cmd(SET_NORM_INV | (invert & 1))

    def show(self):
        x0 = 0
        x1 = self.width - 1
        if self.width == 64:
            # displays with width of 64 pixels are shifted by 32
            x0 += 32
            x1 += 32
        self.write_cmd(SET_COL_ADDR)
        self.write_cmd(x0)
        self.write_cmd(x1)
        self.write_cmd(SET_PAGE_ADDR)
        self.write_cmd(0)
        self.write_cmd(self.pages - 1)
        self.write_framebuf()

    def fill(self, col):
        self.framebuf.fill(col)

    def pixel(self, x, y, col):
        self.framebuf.pixel(x, y, col)

    def scroll(self, dx, dy):
        self.framebuf.scroll(dx, dy)

    def text(self, string, x, y, col=1):
        self.framebuf.text(string, x, y, col)


class SSD1306_I2C(SSD1306):
    def __init__(self, width, height, i2c, addr=0x3c, external_vcc=False):
        self.i2c = i2c
        self.addr = addr
        self.temp = bytearray(2)
        # Add an extra byte to the data buffer to hold an I2C data/command byte
        # to use hardware-compatible I2C transactions.  A memoryview of the
        # buffer is used to mask this byte from the framebuffer operations
        # (without a major memory hit as memoryview doesn't copy to a separate
        # buffer).
        self.buffer = bytearray(((height // 8) * width) + 1)
        self.buffer[0] = 0x40  # Set first byte of data buffer to Co=0, D/C=1
        self.framebuf = framebuf.FrameBuffer1(memoryview(self.buffer)[1:], width, height)
        super().__init__(width, height, external_vcc)

    def write_cmd(self, cmd):
        self.temp[0] = 0x80 # Co=1, D/C#=0
        self.temp[1] = cmd
        self.i2c.writeto(self.addr, self.temp)

    def write_framebuf(self):
        # Blast out the frame buffer using a single I2C transaction to support
        # hardware I2C interfaces.
        self.i2c.writeto(self.addr, self.buffer)

    def poweron(self):
        pass


class SSD1306_SPI(SSD1306):
    def __init__(self, width, height, spi, dc, res, cs, external_vcc=False):
        self.rate = 10 * 1024 * 1024
        dc.init(dc.OUT, value=0)
        res.init(res.OUT, value=0)
        cs.init(cs.OUT, value=1)
        self.spi = spi
        self.dc = dc
        self.res = res
        self.cs = cs
        self.buffer = bytearray((height // 8) * width)
        self.framebuf = framebuf.FrameBuffer1(self.buffer, width, height)
        super().__init__(width, height, external_vcc)

    def write_cmd(self, cmd):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs.high()
        self.dc.low()
        self.cs.low()
        self.spi.write(bytearray([cmd]))
        self.cs.high()

    def write_framebuf(self):
        self.spi.init(baudrate=self.rate, polarity=0, phase=0)
        self.cs.high()
        self.dc.high()
        self.cs.low()
        self.spi.write(self.buffer)
        self.cs.high()

    def poweron(self):
        self.res.high()
        time.sleep_ms(1)
        self.res.low()
        time.sleep_ms(10)
        self.res.high()

Afficher le code brut

Suivez les instructions suivantes pour l’IDE que vous utilisez :

  • A. Téléchargez la bibliothèque OLED avec IDE uPyCraft
  • B. Téléchargez la bibliothèque OLED avec Thonny IDE

A. Télécharger la bibliothèque OLED avec uPyCraft IDE

Cette section montre comment télécharger une bibliothèque à l’aide de l’IDE uPyCraft. Si vous utilisez Thonny IDE, lisez la section suivante.

1. Créez un nouveau fichier en appuyant sur le Nouveau fichier bouton.

1641530167 505 MicroPython SSD1306 Fonctions de defilement de lecran OLED et formes

2. Copiez le code de la bibliothèque OLED dans ce fichier. le Le code de la bibliothèque OLED peut être trouvé ici.

Noter: la bibliothèque d’affichage SSD1306 OLED a été construite par Adafruit et ne sera plus
être mis à jour. Pour le moment, ça marche bien. Cependant, nous mettrons à jour ce guide si nous
trouver une bibliothèque similaire qui fonctionne aussi bien que celle-ci.

3. Après avoir copié le code, enregistrez le fichier en appuyant sur la touche Sauvegarder bouton.

1641530167 608 MicroPython SSD1306 Fonctions de defilement de lecran OLED et formes

4. Appelez ce nouveau fichier « ssd1306.py » et appuyez sur d’accord.

importer la bibliothèque upycraft ide enregistrer le fichier

5. Clique le Télécharger et exécuter bouton.

1641530167 585 MicroPython SSD1306 Fonctions de defilement de lecran OLED et formes

Le fichier doit être enregistré dans le dossier de l’appareil sous le nom « ssd1306.py » comme
mis en évidence dans la figure suivante.

importer enregistrer le fichier de script IDE uPyCraft de la bibliothèque

Maintenant, vous pouvez utiliser les fonctionnalités de la bibliothèque dans votre code en important la bibliothèque.

B. Télécharger la bibliothèque OLED avec Thonny IDE

Si vous utilisez Thonny IDE, suivez les étapes suivantes :

1. Copiez le code de la bibliothèque dans un nouveau fichier. le Le code de la bibliothèque OLED peut être trouvé ici.

2. Enregistrez ce fichier sous ssd1306.py.

3. Aller à Appareil > Télécharger le script actuel avec le nom actuel

thonny ide télécharger le fichier de bibliothèque script micropython

Et c’est tout. La bibliothèque a été téléchargée sur votre tableau. Pour vous assurer qu’il a été téléchargé avec succès, dans le Shell, vous pouvez taper :

%lsdevice

Il devrait renvoyer les fichiers actuellement enregistrés sur votre tableau. L’un d’eux devrait être le ssd1306.py déposer.

afficher le dossier de l'appareil thonny ide

Après avoir téléchargé la bibliothèque sur votre tableau, vous pouvez utiliser les fonctionnalités de la bibliothèque dans votre code en important la bibliothèque.

Fonctions de défilement MicroPython OLED

La bibliothèque ss1306.py est livrée avec un faire défiler (x, y) une fonction. Il fait défiler x nombre de pixels vers la droite et y nombre de pixels vers le bas.

Faites défiler l’écran OLED horizontalement

Parfois, vous souhaitez afficher différents écrans sur l’écran OLED. Par exemple, le premier écran affiche les lectures des capteurs et le deuxième écran affiche les états GPIO.

Faites défiler horizontalement

La fonction suivante scroll_in_screen(écran) fait défiler le contenu d’un écran entier (de droite à gauche).

def scroll_in_screen(screen):
  for i in range (0, oled_width+1, 4):
    for line in screen:
      oled.text(line[2], -oled_width+i, line[1])
    oled.show()
    if i!= oled_width:
      oled.fill(0)

Cette fonction accepte en argument une liste de listes. Par example:

screen1 = [[0, 0 , screen1_row1], [0, 16, screen1_row2], [0, 32, screen1_row3]]

Chaque liste de la liste contient la coordonnée x, la coordonnée y et le message [x, y, message].

À titre d’exemple, nous afficherons trois lignes sur le premier écran avec les messages suivants.

screen1_row1 = "Screen 1, row 1"
screen1_row2 = "Screen 1, row 2"
screen1_row3 = "Screen 1, row 3"

Ensuite, pour faire défiler votre écran de gauche à droite, il vous suffit d’appeler le scroll_in_screen() fonction et passez en argument la liste des listes :

scroll_in_screen(screen1)

Vous obtiendrez quelque chose comme suit :

Faites défiler horizontalement

Pour faire défiler l’écran, vous pouvez utiliser le scroll_out_screen(vitesse) fonction qui fait défiler tout l’écran hors de l’OLED. Il accepte comme argument un nombre qui contrôle la vitesse de défilement. La vitesse doit être un diviseur de 128 (largeur_oled)

def scroll_out_screen(speed):
  for i in range ((oled_width+1)/speed):
    for j in range (oled_height):
      oled.pixel(i, j, 0)
    oled.scroll(speed,0)
    oled.show()

Maintenant, vous pouvez utiliser les deux fonctions pour faire défiler les écrans. Par example:

scroll_in_screen(screen1)
scroll_out_screen(4)
scroll_in_screen(screen2)
scroll_out_screen(4)

Défilement horizontal continu

Si vous souhaitez faire défiler l’écran en continu, vous pouvez utiliser le scroll_screen_in_out(écran) fonction à la place.

def scroll_screen_in_out(screen):
  for i in range (0, (oled_width+1)*2, 1):
    for line in screen:
      oled.text(line[2], -oled_width+i, line[1])
    oled.show()
    if i!= oled_width:
      oled.fill(0)

Vous pouvez utiliser cette fonction pour faire défiler les écrans ou pour faire défiler le même écran encore et encore.

scroll_screen_in_out(screen1)
scroll_screen_in_out(screen2)
scroll_screen_in_out(screen3)

Faites défiler l’écran OLED verticalement

Nous avons également créé des fonctions similaires pour faire défiler l’écran verticalement.

Faites défiler verticalement

le scroll_in_screen_v(écran) défile dans le contenu de tout l’écran.

def scroll_in_screen_v(screen):
  for i in range (0, (oled_height+1), 1):
    for line in screen:
      oled.text(line[2], line[0], -oled_height+i+line[1])
    oled.show()
    if i!= oled_height:
      oled.fill(0)

Faites défiler verticalement

Vous pouvez utiliser le scroll_out_screen_v(vitesse) fonction pour faire défiler l’écran verticalement. De la même manière que la fonction horizontale, elle accepte comme argument, la vitesse de défilement qui doit être un nombre diviseur de 64 (hauteur_oled).

def scroll_out_screen_v(speed):
  for i in range ((oled_height+1)/speed):
    for j in range (oled_width):
      oled.pixel(j, i, 0)
    oled.scroll(0,speed)
    oled.show()

Défilement vertical continu

Si vous souhaitez faire défiler l’écran verticalement en continu, vous pouvez utiliser le scroll_in_out_screen_v(écran) une fonction.

def scroll_screen_in_out_v(screen):
  for i in range (0, (oled_height*2+1), 1):
    for line in screen:
      oled.text(line[2], line[0], -oled_height+i+line[1])
    oled.show()
    if i!= oled_height:
      oled.fill(0)

Faites défiler le script MicroPython de l’écran OLED

Le script suivant applique toutes les fonctions que nous avons décrites précédemment. Vous pouvez télécharger le code suivant sur votre tableau pour voir tous les effets de défilement.

# Complete project details at https://Raspberryme.com/micropython-ssd1306-oled-scroll-shapes-esp32-esp8266/

from machine import Pin, SoftI2C
import ssd1306
from time import sleep

# ESP32 Pin assignment
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))

# ESP8266 Pin assignment
#i2c = SoftI2C(scl=Pin(5), sda=Pin(4))

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

screen1_row1 = "Screen 1, row 1"
screen1_row2 = "Screen 1, row 2"
screen1_row3 = "Screen 1, row 3"

screen2_row1 = "Screen 2, row 1"
screen2_row2 = "Screen 2, row 2"

screen3_row1 = "Screen 3, row 1"

screen1 = [[0, 0 , screen1_row1], [0, 16, screen1_row2], [0, 32, screen1_row3]]
screen2 = [[0, 0 , screen2_row1], [0, 16, screen2_row2]]
screen3 = [[0, 40 , screen3_row1]]

# Scroll in screen horizontally from left to right
def scroll_in_screen(screen):
  for i in range (0, oled_width+1, 4):
    for line in screen:
      oled.text(line[2], -oled_width+i, line[1])
    oled.show()
    if i!= oled_width:
      oled.fill(0)

# Scroll out screen horizontally from left to right
def scroll_out_screen(speed):
  for i in range ((oled_width+1)/speed):
    for j in range (oled_height):
      oled.pixel(i, j, 0)
    oled.scroll(speed,0)
    oled.show()

# Continuous horizontal scroll
def scroll_screen_in_out(screen):
  for i in range (0, (oled_width+1)*2, 1):
    for line in screen:
      oled.text(line[2], -oled_width+i, line[1])
    oled.show()
    if i!= oled_width:
      oled.fill(0)

# Scroll in screen vertically
def scroll_in_screen_v(screen):
  for i in range (0, (oled_height+1), 1):
    for line in screen:
      oled.text(line[2], line[0], -oled_height+i+line[1])
    oled.show()
    if i!= oled_height:
      oled.fill(0)

# Scroll out screen vertically
def scroll_out_screen_v(speed):
  for i in range ((oled_height+1)/speed):
    for j in range (oled_width):
      oled.pixel(j, i, 0)
    oled.scroll(0,speed)
    oled.show()

# Continous vertical scroll
def scroll_screen_in_out_v(screen):
  for i in range (0, (oled_height*2+1), 1):
    for line in screen:
      oled.text(line[2], line[0], -oled_height+i+line[1])
    oled.show()
    if i!= oled_height:
      oled.fill(0)

while True:

  # Scroll in, stop, scroll out (horizontal)
  scroll_in_screen(screen1)
  sleep(2)
  scroll_out_screen(4)

  scroll_in_screen(screen2)
  sleep(2)
  scroll_out_screen(4)

  scroll_in_screen(screen3)
  sleep(2)
  scroll_out_screen(4)

  # Continuous horizontal scroll
  scroll_screen_in_out(screen1)
  scroll_screen_in_out(screen2)
  scroll_screen_in_out(screen3)

  # Scroll in, stop, scroll out (vertical)
  scroll_in_screen_v(screen1)
  sleep(2)
  scroll_out_screen_v(4)

  scroll_in_screen_v(screen2)
  sleep(2)
  scroll_out_screen_v(4)

  scroll_in_screen_v(screen3)
  sleep(2)
  scroll_out_screen_v(4)

  # Continuous verticall scroll
  scroll_screen_in_out_v(screen1)
  scroll_screen_in_out_v(screen2)
  scroll_screen_in_out_v(screen3)

Afficher le code brut

Formes de dessin MicroPython OLED

Pour dessiner des formes sur l’écran OLED à l’aide de MicroPython, nous utiliserons la bibliothèque MicroPython Adafruit_GFX.

Bibliothèque GFX Adafruit

Pour dessiner des formes sur l’écran OLED, nous utiliserons le Bibliothèque GFX Adafruit. Cette bibliothèque ne fait pas partie de la bibliothèque MicroPython standard par défaut. Vous devez donc télécharger la bibliothèque sur votre carte ESP32/ESP8266.

# Port of Adafruit GFX Arduino library to MicroPython.
# Based on: https://github.com/adafruit/Adafruit-GFX-Library
# Author: Thomas DiCola (original GFX author Phil Burgess)
# License: MIT License (https://opensource.org/licenses/MIT)

class GFX:

    def __init__(self, width, height, pixel, hline=None, vline=None):
        # Create an instance of the GFX drawing class.  You must pass in the
        # following parameters:
        #  - width = The width of the drawing area in pixels.
        #  - height = The height of the drawing area in pixels.
        #  - pixel = A function to call when a pixel is drawn on the display.
        #            This function should take at least an x and y position
        #            and then any number of optional color or other parameters.
        #  You can also provide the following optional keyword argument to
        #  improve the performance of drawing:
        #  - hline = A function to quickly draw a horizontal line on the display.
        #            This should take at least an x, y, and width parameter and
        #            any number of optional color or other parameters.
        #  - vline = A function to quickly draw a vertical line on the display.
        #            This should take at least an x, y, and height paraemter and
        #            any number of optional color or other parameters.
        self.width = width
        self.height = height
        self._pixel = pixel
        # Default to slow horizontal & vertical line implementations if no
        # faster versions are provided.
        if hline is None:
            self.hline = self._slow_hline
        else:
            self.hline = hline
        if vline is None:
            self.vline = self._slow_vline
        else:
            self.vline = vline

    def _slow_hline(self, x0, y0, width, *args, **kwargs):
        # Slow implementation of a horizontal line using pixel drawing.
        # This is used as the default horizontal line if no faster override
        # is provided.
        if y0 < 0 or y0 > self.height or x0 < -width or x0 > self.width:
            return
        for i in range(width):
            self._pixel(x0+i, y0, *args, **kwargs)

    def _slow_vline(self, x0, y0, height, *args, **kwargs):
        # Slow implementation of a vertical line using pixel drawing.
        # This is used as the default vertical line if no faster override
        # is provided.
        if y0 < -height or y0 > self.height or x0 < 0 or x0 > self.width:
            return
        for i in range(height):
            self._pixel(x0, y0+i, *args, **kwargs)

    def rect(self, x0, y0, width, height, *args, **kwargs):
        # Rectangle drawing function.  Will draw a single pixel wide rectangle
        # starting in the upper left x0, y0 position and width, height pixels in
        # size.
        if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width:
            return
        self.hline(x0, y0, width, *args, **kwargs)
        self.hline(x0, y0+height-1, width, *args, **kwargs)
        self.vline(x0, y0, height, *args, **kwargs)
        self.vline(x0+width-1, y0, height, *args, **kwargs)

    def fill_rect(self, x0, y0, width, height, *args, **kwargs):
        # Filled rectangle drawing function.  Will draw a single pixel wide
        # rectangle starting in the upper left x0, y0 position and width, height
        # pixels in size.
        if y0 < -height or y0 > self.height or x0 < -width or x0 > self.width:
            return
        for i in range(x0, x0+width):
            self.vline(i, y0, height, *args, **kwargs)

    def line(self, x0, y0, x1, y1, *args, **kwargs):
        # Line drawing function.  Will draw a single pixel wide line starting at
        # x0, y0 and ending at x1, y1.
        steep = abs(y1 - y0) > abs(x1 - x0)
        if steep:
            x0, y0 = y0, x0
            x1, y1 = y1, x1
        if x0 > x1:
            x0, x1 = x1, x0
            y0, y1 = y1, y0
        dx = x1 - x0
        dy = abs(y1 - y0)
        err = dx // 2
        ystep = 0
        if y0 < y1:
            ystep = 1
        else:
            ystep = -1
        while x0 <= x1:
            if steep:
                self._pixel(y0, x0, *args, **kwargs)
            else:
                self._pixel(x0, y0, *args, **kwargs)
            err -= dy
            if err < 0:
                y0 += ystep
                err += dx
            x0 += 1

    def circle(self, x0, y0, radius, *args, **kwargs):
        # Circle drawing function.  Will draw a single pixel wide circle with
        # center at x0, y0 and the specified radius.
        f = 1 - radius
        ddF_x = 1
        ddF_y = -2 * radius
        x = 0
        y = radius
        self._pixel(x0, y0 + radius, *args, **kwargs)
        self._pixel(x0, y0 - radius, *args, **kwargs)
        self._pixel(x0 + radius, y0, *args, **kwargs)
        self._pixel(x0 - radius, y0, *args, **kwargs)
        while x < y:
            if f >= 0:
                y -= 1
                ddF_y += 2
                f += ddF_y
            x += 1
            ddF_x += 2
            f += ddF_x
            self._pixel(x0 + x, y0 + y, *args, **kwargs)
            self._pixel(x0 - x, y0 + y, *args, **kwargs)
            self._pixel(x0 + x, y0 - y, *args, **kwargs)
            self._pixel(x0 - x, y0 - y, *args, **kwargs)
            self._pixel(x0 + y, y0 + x, *args, **kwargs)
            self._pixel(x0 - y, y0 + x, *args, **kwargs)
            self._pixel(x0 + y, y0 - x, *args, **kwargs)
            self._pixel(x0 - y, y0 - x, *args, **kwargs)

    def fill_circle(self, x0, y0, radius, *args, **kwargs):
        # Filled circle drawing function.  Will draw a filled circule with
        # center at x0, y0 and the specified radius.
        self.vline(x0, y0 - radius, 2*radius + 1, *args, **kwargs)
        f = 1 - radius
        ddF_x = 1
        ddF_y = -2 * radius
        x = 0
        y = radius
        while x < y:
            if f >= 0:
                y -= 1
                ddF_y += 2
                f += ddF_y
            x += 1
            ddF_x += 2
            f += ddF_x
            self.vline(x0 + x, y0 - y, 2*y + 1, *args, **kwargs)
            self.vline(x0 + y, y0 - x, 2*x + 1, *args, **kwargs)
            self.vline(x0 - x, y0 - y, 2*y + 1, *args, **kwargs)
            self.vline(x0 - y, y0 - x, 2*x + 1, *args, **kwargs)

    def triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs):
        # Triangle drawing function.  Will draw a single pixel wide triangle
        # around the points (x0, y0), (x1, y1), and (x2, y2).
        self.line(x0, y0, x1, y1, *args, **kwargs)
        self.line(x1, y1, x2, y2, *args, **kwargs)
        self.line(x2, y2, x0, y0, *args, **kwargs)

    def fill_triangle(self, x0, y0, x1, y1, x2, y2, *args, **kwargs):
        # Filled triangle drawing function.  Will draw a filled triangle around
        # the points (x0, y0), (x1, y1), and (x2, y2).
        if y0 > y1:
            y0, y1 = y1, y0
            x0, x1 = x1, x0
        if y1 > y2:
            y2, y1 = y1, y2
            x2, x1 = x1, x2
        if y0 > y1:
            y0, y1 = y1, y0
            x0, x1 = x1, x0
        a = 0
        b = 0
        y = 0
        last = 0
        if y0 == y2:
            a = x0
            b = x0
            if x1 < a:
                a = x1
            elif x1 > b:
                b = x1
            if x2 < a:
                a = x2
            elif x2 > b:
                b = x2
            self.hline(a, y0, b-a+1, *args, **kwargs)
            return
        dx01 = x1 - x0
        dy01 = y1 - y0
        dx02 = x2 - x0
        dy02 = y2 - y0
        dx12 = x2 - x1
        dy12 = y2 - y1
        if dy01 == 0:
            dy01 = 1
        if dy02 == 0:
            dy02 = 1
        if dy12 == 0:
            dy12 = 1
        sa = 0
        sb = 0
        if y1 == y2:
            last = y1
        else:
            last = y1-1
        for y in range(y0, last+1):
            a = x0 + sa // dy01
            b = x0 + sb // dy02
            sa += dx01
            sb += dx02
            if a > b:
                a, b = b, a
            self.hline(a, y, b-a+1, *args, **kwargs)
        sa = dx12 * (y - y1)
        sb = dx02 * (y - y0)
        while y <= y2:
            a = x1 + sa // dy12
            b = x0 + sb // dy02
            sa += dx12
            sb += dx02
            if a > b:
                a, b = b, a
            self.hline(a, y, b-a+1, *args, **kwargs)
            y += 1

Afficher le code brut

Suivez les instructions précédentes sur la façon d’installer une bibliothèque, mais pour la bibliothèque GFX. Enregistrez le fichier de bibliothèque GFX sous gfx.py. Ensuite, vous pouvez utiliser les fonctionnalités de la bibliothèque en important la bibliothèque dans votre code.

En résumé, voici comment dessiner des formes. Tout d’abord, vous devez inclure le ssd1306 et gfx bibliothèques ainsi que les Épingler et SoftI2C modules.

from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import gfx

Ensuite, définissez les broches de l’ESP32.

i2c = SoftI2C(scl=Pin(22), sda=Pin(21))

Si vous utilisez un ESP8266, utilisez plutôt les broches suivantes :

i2c = SoftI2C(scl=Pin(5), sda=Pin(4))

Nous utilisons un écran OLED 128 × 64. Si vous utilisez un écran OLED avec des dimensions différentes, modifiez cela sur les lignes suivantes :

oled_width = 128
oled_height = 64

Créé un SS1306 objet appelé vieux.

oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

Ensuite, nous devons créer un gfx objet pour dessiner des formes. Dans ce cas, ça s’appelle graphique. Il prend comme arguments, la largeur et la hauteur de la zone de dessin. Dans ce cas, nous voulons dessiner dans l’ensemble de l’OLED, nous passons donc la largeur et la hauteur de l’OLED. Nous devrions également passer en argument une fonction de notre affichage qui dessine des pixels, dans notre cas est oled.pixel.

graphics = gfx.GFX(oled_width, oled_height, oled.pixel)

Ensuite, vous pouvez utiliser les fonctions de dessin que nous allons vous montrer à côté pour afficher des formes.

Tracer une ligne

ESP32 ESP8266 Ligne d'affichage Arduino OLED

Utilisez le ligne(x0, y0, x1, y1, couleur) méthode sur le gfx objet pour créer une ligne. Les coordonnées (x0, y0) indiquent le début de la ligne et les coordonnées (x1, y1) indiquent où se termine la ligne. Vous devez toujours appeler oled.show() pour afficher réellement les formes sur l’OLED. Voici un exemple :

graphics.line(0, 0, 127, 20, 1)
oled.show()

Rectangle

ESP32 ESP8266 Arduino OLED Affichage Rectangle

Pour dessiner un rectangle, vous pouvez utiliser le rect(x0, y0, largeur, hauteur, couleur) méthode sur le gfx objet. Les coordonnées (x0, y0) indiquent le coin supérieur gauche du rectangle. Ensuite, vous devez spécifier la largeur, la hauteur et la couleur du rectangle. Par example:

graphics.rect(10, 10, 50, 30, 1)
oled.show()

Rectangle rempli

ESP32 ESP8266 Arduino OLED Display Rempli

Vous pouvez utiliser le fill_rect(x0, y0, largeur, hauteur, couleur) méthode pour dessiner un rectangle rempli. Cette méthode accepte les mêmes arguments que dessinerRect().

graphics.rect(10, 10, 50, 30, 1)
oled.show()

Cercle

Cercle d'affichage OLED ESP32 ESP8266 Arduino

Tracez un cercle à l’aide du cercle(x0, y0, rayon, couleur) méthode. Les coordonnées (x0, y0) indiquent le centre du cercle. Voici un exemple :

graphics.circle(64, 32, 10, 1)
oled.show()

Cercle rempli

ESP32 ESP8266 Arduino OLED Display Circle Rempli

Tracez un cercle plein à l’aide du fill_circle(x0, y0, rayon, couleur) méthode.

graphics.fill_circle(64, 32, 10, 1)
oled.show()

Triangle

ESP32 ESP8266 Arduino OLED Triangle d'affichage

Il existe également une méthode pour dessiner un triangle : triangle(x0, y0, x1, y1, x2, y2, couleur). Cette méthode accepte comme arguments les coordonnées de chaque coin et la couleur.

graphics.triangle(10,10,55,20,5,40,1)
oled.show()

Triangle rempli

ESP32 ESP8266 Arduino OLED Affichage Triangle Rempli

Utilisez le fill_triangle(x0, y0, x1, y1, x2, y2, couleur) méthode pour dessiner un triangle plein.

graphics.fill_triangle(10,10,55,20,5,40,1)
oled.show()

Script MicroPython – Dessiner des formes

Le script suivant implémente toutes les méthodes de dessin présentées précédemment.

# Complete project details at https://Raspberryme.com/micropython-ssd1306-oled-scroll-shapes-esp32-esp8266/

from machine import Pin, SoftI2C
import ssd1306
from time import sleep
import gfx

# ESP32 Pin assignment
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))

# ESP8266 Pin assignment
#i2c = SoftI2C(scl=Pin(5), sda=Pin(4))

oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)

graphics = gfx.GFX(oled_width, oled_height, oled.pixel)

while True:

  graphics.line(0, 0, 127, 20, 1)
  oled.show()
  sleep(1)
  oled.fill(0)

  graphics.rect(10, 10, 50, 30, 1)
  oled.show()
  sleep(1)
  oled.fill(0)

  graphics.fill_rect(10, 10, 50, 30, 1)
  oled.show()
  sleep(1)
  oled.fill(0)


  graphics.circle(64, 32, 10, 1)
  oled.show()
  sleep(1)
  oled.fill(0)

  graphics.fill_circle(64, 32, 10, 1)
  oled.show()
  sleep(1)
  oled.fill(0)

  graphics.triangle(10,10,55,20,5,40,1)
  oled.show()
  sleep(1)
  oled.fill(0)

  graphics.fill_triangle(10,10,55,20,5,40,1)
  oled.show()
  sleep(1)
  oled.fill(0)

Afficher le code brut

Conclusion

Dans ce didacticiel, vous avez appris à utiliser des fonctions plus avancées pour faire défiler l’écran OLED et dessiner des formes à l’aide de MicroPython avec l’ESP32 ou l’ESP8266. Pour dessiner des formes, vous devez importer la bibliothèque Adafruit GFX MicroPython.

Nous espérons que vous avez trouvé ce tutoriel utile. Si c’est la première fois que vous utilisez l’écran OLED à l’aide de MicroPython, nous vous recommandons de suivre d’abord le guide de démarrage :

Nous avons des tutoriels similaires, mais en utilisant Arduino IDE :

Si vous souhaitez en savoir plus sur MicroPython, consultez notre eBook :