Comment interfacer le Raspberry Pi Pico W avec un écran OLED en utilisant MicroPython

Raspberry Pi Pico W with OLED Display

//MicroPython driver SSD1306 OLED, interfaces I2C et SPI

 

from micropython import const

import framebuf

# définitions des registres

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)

# La sous-classe FrameBuffer prend en charge les primitives graphiques

# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html

class SSD1306(framebuf.FrameBuffer):

    def __init__(self, largeur, hauteur, external_vcc):

        self.largeur = largeur

        self.hauteur = hauteur

        self.external_vcc = external_vcc

        self.pages = self.hauteur // 8

        self.buffer = bytearray(self.pages * self.largeur)

        super().__init__(self.buffer, self.largeur, self.hauteur, framebuf.MONO_VLSB)

        self.init_display()

    def init_display(self):

        for cmd in (

            SET_DISP | 0x00,  # désactivé

            # réglage de l’adresse

            SET_MEM_ADDR,

            0x00,  # horizontal

            # résolution et disposition

            SET_DISP_START_LINE | 0x00,

            SET_SEG_REMAP | 0x01,  # l’adresse de la colonne 127 est mappée sur SEG0

            SET_MUX_RATIO,

            self.hauteur – 1,

            SET_COM_OUT_DIR | 0x08,  # balayer de COM[N] à COM0

            SET_DISP_OFFSET,

            0x00,

            SET_COM_PIN_CFG,

            0x02 if self.largeur > 2 * self.hauteur else 0x12,

            # chronométrage et schéma de pilotage

            SET_DISP_CLK_DIV,

            0x80,

            SET_PRECHARGE,

            0x22 if self.external_vcc else 0xF1,

            SET_VCOM_DESEL,

            0x30,  # 0.83*Vcc

            # affichage

            SET_CONTRAST,

            0xFF,  # maximum

            SET_ENTIRE_ON,  # la sortie suit le contenu de RAM

            SET_NORM_INV,  # non inversé

            # pompe de charge

            SET_CHARGE_PUMP,

            0x10 if self.external_vcc else 0x14,

            SET_DISP | 0x01,

        ):  # activé

            self.write_cmd(cmd)

        self.fill(0)

        self.show()

    def poweroff(self):

        self.write_cmd(SET_DISP | 0x00)

    def poweron(self):

        self.write_cmd(SET_DISP | 0x01)

    def contrast(self, contraste):

        self.write_cmd(SET_CONTRAST)

        self.write_cmd(contraste)

    def invert(self, inversion):

        self.write_cmd(SET_NORM_INV | (inversion & 1))

    def show(self):

        x0 = 0

        x1 = self.largeur – 1

        if self.largeur == 64:

            # les affichages d’une largeur de 64 pixels sont décalés de 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_data(self.buffer)

class SSD1306_I2C(SSD1306):

    def __init__(self, largeur, hauteur, i2c, addr=0x3C, external_vcc=False):

        self.i2c = i2c

        self.addr = addr

        self.temp = bytearray(2)

        self.write_list = [b »\x40″, None]  # Co=0, D/C#=1

        super().__init__(largeur, hauteur, 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_data(self, buf):

        self.write_list[1] = buf

        self.i2c.writevto(self.addr, self.write_list)

class SSD1306_SPI(SSD1306):

    def __init__(self, largeur, hauteur, 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

        import time

        self.res(1)

        time.sleep_ms(1)

        self.res(0)

        time.sleep_ms(10)

        self.res(1)

        super().__init__(largeur, hauteur, external_vcc)

    def write_cmd(self, cmd):

        self.spi.init(baudrate=self.rate, polarity=0, phase=0)

        self.cs(1)

        self.dc(0)

        self.cs(0)

        self.spi.write(bytearray([cmd]))

        self.cs(1)

    def write_data(self, buf):

        self.spi.init(baudrate=self.rate, polarity=0, phase=0)

        self.cs(1)

        self.dc(1)

        self.cs(0)

        self.spi.write(buf)

        self.cs(1)

 

//code pour OLED avec Pico

import machine

from machine import Pin, SoftI2C

import ssd1306

from time import sleep

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

pin = machine.Pin(16, machine.Pin.OUT)

pin.value(0)

pin.value(1)

largeur_oled = 128

hauteur_oled = 64

oled = ssd1306.SSD1306_I2C(largeur_oled, hauteur_oled, i2c)

oled.fill(0)

oled.text(‘Bonjour, Monde!’, 0, 10)

oled.show()

 

//Code pour forme carrée dans OLED

import machine

import ssd1306

from time import sleep

# Initialisation de la communication I2C

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

# Réinitialisation de l’affichage OLED (facultative)

pin = machine.Pin(16, machine.Pin.OUT)

pin.value(0)  # Mettre le GPIO16 à l’état bas pour réinitialiser l’OLED

pin.value(1)  # Pendant que l’OLED fonctionne, mettre le GPIO16 à l’état haut

# Création d’une instance du pilote OLED SSD1306

largeur_oled = 128

hauteur_oled = 64

oled = ssd1306.SSD1306_I2C(largeur_oled, hauteur_oled, i2c)

# Fonction pour dessiner un carré au centre

def dessiner_carre():

    taille_carre = 20

    centre_x = largeur_oled // 2

    centre_y = hauteur_oled // 2

    x0 = centre_x – taille_carre // 2

    y0 = centre_y – taille_carre // 2

    x1 = centre_x + taille_carre // 2

    y1 = centre_y + taille_carre // 2

    oled.rect(x0, y0, taille_carre, taille_carre, 1)

# Effacer l’affichage OLED

oled.fill(0)

# Dessiner un carré au centre de l’OLED

dessiner_carre()

# Mettre à jour l’affichage OLED pour afficher le texte et le carré

oled.show()

 

//code pour créer une animation d’une explosion de fusée

import machine

import ssd1306

from time import sleep

import math

# Initialisation de la communication I2C

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

# Réinitialisation de l’affichage OLED (facultative)

pin = machine.Pin(16, machine.Pin.OUT)

pin.value(0)  # Mettre le GPIO16 à l’état bas pour réinitialiser l’OLED

pin.value(1)  # Pendant que l’OLED fonctionne, mettre le GPIO16 à l’état haut

# Création d’une instance du pilote OLED SSD1306

largeur_oled = 128

hauteur_oled = 64

oled = ssd1306.SSD1306_I2C(largeur_oled, hauteur_oled, i2c)

# Fonction pour effacer l’écran OLED

def effacer_ecran():

    oled.fill(0)

    oled.show()

# Paramètres de l’animation

hauteur_fusee = 20  # Faire monter la fusée plus haut

x_fusee = largeur_oled // 2

y_fusee = hauteur_oled

# Fonction pour dessiner un cercle à la position donnée

def dessiner_cercle(x, y, rayon):

    for i in range(rayon * 2):

        for j in range(rayon * 2):

            distance = math.sqrt((i – rayon) ** 2 + (j – rayon) ** 2)

            if distance < rayon:

                oled.pixel(x – rayon + i, y – rayon + j, 1)

# Fonction pour afficher le motif d’explosion

def afficher_motif_explosion(x, y, rayon, iterations):

    for r in range(1, rayon, max(1, int(rayon/iterations))):

        effacer_ecran()

        dessiner_cercle(x, y, r)

        oled.show()

        sleep(0.03)

# Boucle principale d’animation

try:

    while True:

        # Animation de la fusée : Faire monter la fusée

        for y in range(hauteur_oled, hauteur_oled – hauteur_fusee, -1):

            effacer_ecran()

            oled.rect(x_fusee – 2, y – hauteur_fusee, 4, hauteur_fusee, 1)

            oled.show()

            sleep(0.1)

        # Animation d’explosion : Afficher le motif d’explosion

        x_explosion = x_fusee

        y_explosion = hauteur_oled – hauteur_fusee

        rayon_explosion = 40  # Faire 5 fois plus grand le rayon des explosions

        iterations_explosion = 20

        afficher_motif_explosion(x_explosion, y_explosion, rayon_explosion, iterations_explosion)

except KeyboardInterrupt:

    effacer_ecran()  

Retrouvez l’histoire de Raspberry Pi dans cette vidéo :

Youtube video