ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı

Bu yazımızda ESP8266 ve ESP32 MicroPython kullanarak 0,96 inç SSD1306 OLED ekranın nasıl kullanılacağını göstereceğiz. Örnek olarak, basit bir ‘Hello World!’ mesajının nasıl görüntüleneceğini göstereceğiz. Daha sonra, OLED ekranla etkileşim kurmak için diğer kullanışlı işlevleri nasıl kullanacağınızı da göstereceğiz.

Ön Hazırlık

Bu yazıdaki adımları yapabilmek için ESP32 veya ESP8266 kartlarınızda kurulu MicroPython sürümüne(firmware) ihtiyacınız var. Ayrıca kodu yazıp kartınıza yüklemek için bir IDE’ye ihtiyacınız var. Thonny IDE veya uPyCraft IDE kullanmanızı öneririz:

Thonny IDE

uPyCraft IDE

OLED Ekran Kullanımı

Bu yazıda, 128×64 piksel olan ve I2C iletişim protokolünü kullanan 0,96 inç SSD1306 OLED ekranı kullanacağız. Daha önce de aynı OLED ekranı kullandığımız yazılarımıza göz atmanızı öneriyoruz.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Gerekli Malzemeler

İşte bu proje için ihtiyacınız olan parçaların bir listesi:

  • 0.96″ OLED I2C Ekran
  • ESP32 ya da ESP8266
  • Devre tahtası
  • Bağlantı kabloları

Bağlantı Şeması

ESP32 Bağlantıları

ESP32 kartı kullanıyorsanız bu şematik diyagramı izleyin:

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran
ESP32 OLED Bağlantı Şeması

ESP32 kartlarında hangi pinlerin ne işe yaradığını bilmiyorsanız, bu yazımıza bakmanızı öneririz.

ESP8266 Bağlantıları

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran
ESP8266 OLED Bağlantı Şeması

SSD1306 OLED Kütüphanesi

OLED ekrana yazdırma işleminde kullanılacak olan kütüphane, varsayılan olarak standart MicroPython kütüphanesinin bir parçası değildir. Bu yüzden kütüphaneyi ESP32/ESP8266 kartınıza yüklemeniz gerekiyor.

#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()

Kullanmakta olduğunuz IDE ye göre bir sonraki talimatları izleyin:

  • uPyCraft IDE ile OLED kitaplığını yükleme
  • Thonny IDE ile OLED kitaplığını yükleme

uPyCraft IDE ile OLED Kitaplığını Yükleme

Bu bölüm, uPyCraft IDE kullanarak bir kitaplığın nasıl yükleneceğini gösterir. Thonny IDE kullanıyorsanız sonraki bölümü okuyun.

New File düğmesine basarak yeni bir dosya oluşturun.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

OLED kütüphanesi kodunu o dosyaya kopyalayın. OLED kütüphane kodu burada bulunabilir.

Not: SSD1306 OLED ekran kütüphanesi Adafruit tarafından yapılmıştır ve artık güncellenmeyecektir.

Kodu kopyaladıktan sonra Save düğmesine basarak dosyayı kaydedin.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Bu yeni dosyayı “ssd1306.py” olarak adlandırın ve ok’a basın.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Download and Run düğmesini tıklayın.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Dosya, “ssd1306.py” adıyla cihaz klasörüne kaydedilmelidir. Aşağıdaki şekilde vurgulanmıştır:

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Artık kütüphaneyi içe aktararak kodunuzdaki kütüphane işlevlerini kullanabilirsiniz.

Thonny IDE ile OLED Kitaplığını Yükleme

Thonny IDE kullanıyorsanız bu adımları izleyin:

Kütüphane kodunu yeni bir dosyaya kopyalayın. OLED kütüphane kodu burada bulunabilir.

Dosyayı ssd1306.py olarak kaydedin.

Device Upload current script with the current name yoluna gidin

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Ve bu kadar. Kütüphane panonuza yüklendi. Başarıyla yüklendiğinden emin olmak için Shell’e şunu yazabilirsiniz:

%lsdevice

Şu anda kartınıza kayıtlı olan dosyaları döndürmelidir. Bunlardan biri ssd1306.py dosyası olmalıdır.

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Kütüphaneyi kartınıza yükledikten sonra kütüphaneyi import ederek kodunuzdaki kütüphane fonksiyonlarını kullanabilirsiniz.

Örnek Kod

Kütüphaneyi ESP32 veya ESP8266’ya yükledikten sonra aşağıdaki kodu main.py dosyasına yapıştırın. Ekranda ‘Hello, World!’ mesajını üç kez yazdırır.

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)

oled.text('Hello, World 1!', 0, 0)
oled.text('Hello, World 2!', 0, 10)
oled.text('Hello, World 3!', 0, 20)
        
oled.show()

Kod Açıklamaları

GPIO’larla etkileşim kurmak için gerekli modülleri içe aktararak başlıyoruz ve I2C iletişimi yoluyla OLED’e veri gönderiyoruz. Pin ve SoftI2C sınıflarını makine modülünden içe aktarmanız gerekiyor.

from machine import Pin, SoftI2C

Ayrıca daha önce karta yüklediğiniz OLED kitaplığını ssd1306.py dosyası olarak içe aktarmanız gerekir.

import ssd1306

ESP32’nin varsayılan I2C pinleri GPIO 22 (SCL) ve GPIO 21 (SDA)’dir. ESP8266 varsayılan I2C pinleri GPIO 5 (SLC) ve GPIO 4 (SDA)’tür.

ESP32 kartı kullanıyorsanız aşağıdaki satırı kullanın:

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

Eğer ESP8266 kartı kullanıyorsanız, önceki satırı yorumlayın ve aşağıdakilerin yorumunu kaldırın:

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

OLED ekran genişliğini ve yüksekliğini aşağıdaki değişkenlerde tanımlayın:

oled_width = 128
oled_height = 64

Bundan sonra oled adlı bir SSD1306_I2C nesnesi oluşturun. Bu nesne, daha önce tanımladığınız OLED genişliğini, yüksekliğini ve I2C pinlerini kabul eder.

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

OLED ekranı başlattıktan sonra, metin yazmak için oled nesnesi üzerindeki text() işlevini kullanmanız yeterlidir. text() işlevinden sonra OLED’i güncellemek için show() yöntemini çağırmanız gerekir.

oled.text('Hello, World 1!', 0, 0)
oled.text('Hello, World 2!', 0, 10)
oled.text('Hello, World 3!', 0, 20)
oled.show()

text() yöntemi aşağıdaki argümanları kabul eder (bu sırayla):

Mesaj: String türünde olmalıdır
X konumu: metnin başladığı yer
Y konumu: metnin dikey olarak görüntülendiği yer
Metin rengi: siyah veya beyaz olabilir. Varsayılan renk beyazdır ve bu parametre isteğe bağlıdır.
0 = siyah
1 = beyaz
Örneğin, aşağıdaki satırda beyaz renkte 0,0 konumunda başlayarak ‘Hello, World 1!’ mesajı yazıyor.

oled.text('Hello, World 1!', 0, 0)

Bir kod satırı ise, metni sonraki satıra yazar (y =10).

oled.text('Hello, World 2!', 0, 10)

Son olarak, değişikliklerin etkili olması için oled nesnesinde show() yöntemini kullanın.

oled.show()

Son Görüntü

Kodu kartınıza yükleyin. OLED ekranınız aşağıdaki gibi görünmelidir:

ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Diğer Fonksiyonlar

Kütüphane, OLED ekranıyla etkileşim kurmak için başka fonksiyonlar sağlar.

Ekranı Doldurma

Tüm ekranı beyazla/maviyle doldurmak için aşağıdaki gibi fill() işlevini kullanın:

oled.fill(1)
oled.show()
ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Ekranı temizlemek için tekrar fill() yöntemini kullanın. (Tüm pikselleri siyaha ayarlar):

oled.fill(0)
oled.show()

Piksel Çizdirme

Bir piksel çizmek için, pixel() yöntemini ve ardından show() yöntemini kullanın. pixel() yöntemi aşağıdaki argümanları kabul eder:

X koordinatı: yatay olarak piksel konumu
Y koordinatı: dikey olarak piksel konumu
Piksel rengi: siyah veya beyaz olabilir
0 = siyah
1 = beyaz

Örneğin, sol üst köşeye beyaz bir piksel çizmek için:

oled.pixel(0, 0, 1)
oled.show()
ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Renkleri Tersine Çevirme

Ayrıca, invert() yöntemini kullanarak OLED renklerini de tersine çevirebilirsiniz: beyaz ile siyah ve tam tersi:

oled.invert(True)
ESP8266 ve ESP32 MicroPython ile OLED Ekran Kullanımı esp32 micropython,micropython,micropython esp32,micropython ile oled ekran

Orijinal renklere geri dönmek için şunu kullanın:

oled.invert(False)

Sensörlerden Gelen Verileri Görüntüleme

text() işlevi, yalnızca string türündeki değişkenleri mesaj olarak kabul eder. Sensör okumaları genellikle int veya float değişkenlerinde saklanır.

Sensör okumalarını görüntülemek istiyorsanız ve bunlar int veya float değişkenlerinde saklanıyorsa, string’e dönüştürülmeleri gerekir. Verileri bir stringe dönüştürmek için str() işlevini kullanabilirsiniz:

sicaklik = 12.34
sicaklik_string = str(sicaklik)

Ardından, text() ve show() yöntemlerini kullanarak OLED’de sicaklık_string değişkenini görüntüleyebilirsiniz:

oled.text(sicaklik_string, 0, 0)
oled.show()