Pada artikel ini, Arduino Indonesia akan membahas tentang cara menggunakan layar OLED SSD1306 0.96 inci dengan ESP32 atau ESP8266 menggunakan firmware MicroPython. Sebagai contoh, kami akan menunjukkan cara menampilkan pesan sederhana 'Hello, World!'. Selanjutnya, kami juga akan menunjukkan fungsi-fungsi berguna lainnya untuk berinteraksi dengan layar OLED.
Pengenalan Layar OLED
Dalam artikel ini, kami akan menggunakan layar OLED SSD1306 0.96 inci dengan resolusi 128×64 piksel yang menggunakan protokol komunikasi I2C.
Komunikasi I2C
Untuk layar OLED I2C, berikut adalah koneksi yang perlu Anda buat:
Komponen yang Diperlukan
Berikut daftar komponen untuk proyek ini:
- Layar OLED 0.96 inci
- ESP32 atau ESP8266
- Breadboard
- Kabel jumper
Baca juga: MicroPython ESP32/ESP8266 - Cara Mengontrol Modul Relay Menggunakan Web Server
Diagram Rangkaian – ESP32
Gunakan diagram skematik ini sebagai panduan jika Anda menggunakan papan ESP32:
Diagram Rangkaian – ESP8266
Gunakan diagram skematik ini sebagai panduan jika Anda menggunakan papan ESP8266:
Library SSD1306 OLED
Library untuk menulis ke layar OLED tidak termasuk dalam paket standar MicroPython. Oleh karena itu, Anda perlu mengunggah file library-nya ke papan ESP32 atau ESP8266.
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()
Ikuti langkah-langkah di bawah ini sesuai dengan IDE yang Anda gunakan:
- Mengunggah Library OLED dengan uPyCraft IDE
- Mengunggah Library OLED dengan Thonny IDE
Mengunggah Library OLED dengan uPyCraft IDE
Bagian ini menjelaskan cara mengunggah library menggunakan uPyCraft IDE. Jika Anda menggunakan Thonny IDE, silakan langsung ke bagian berikutnya.
1. Buat file baru dengan menekan tombol New File.
2. Salin kode library OLED ke dalam file tersebut.
Catatan: Library untuk layar OLED SSD1306 ini dikembangkan oleh Adafruit dan tidak lagi diperbarui. Saat ini, library tersebut masih berfungsi dengan baik. Namun, kami akan memperbarui panduan ini jika ditemukan library serupa yang memiliki kinerja setara.
3. Setelah menyalin kode, simpan file dengan menekan tombol Save.
4. Beri nama file tersebut "ssd1306.py" lalu tekan OK.
5. Klik tombol Download and Run.
File akan tersimpan dalam folder perangkat dengan nama "ssd1306.py", seperti yang ditunjukkan pada gambar di bawah ini.
Sekarang, Anda dapat menggunakan fungsi-fungsi dari library ini dalam kode Anda dengan melakukan impor library.
Mengunggah Library OLED dengan Thonny IDE
Jika Anda menggunakan Thonny IDE, ikuti langkah-langkah berikut:
1. Buat file baru di Thonny IDE dan salin kode library.
2. Buka menuFile > Save as dan pilih MicroPython device.
3. Beri nama file ssd1306.py dan klik OK untuk menyimpan file di sistem file ESP.
Selesai. Library telah berhasil diunggah ke papan Anda. Sekarang, Anda dapat menggunakan fungsionalitasnya dalam kode dengan mengimpor library tersebut.
Kode Program
Setelah mengunggah library ke ESP32 atau ESP8266, salin kode berikut ke dalam file main.py. Kode ini menampilkan pesan 'Hello, World!' sebanyak tiga kali pada layar.
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()
Penjelasan Kode
Mulailah dengan mengimpor modul yang diperlukan untuk berinteraksi dengan GPIO dan mengirim data ke OLED melalui komunikasi I2C. Anda perlu mengimpor kelas Pin dan SoftI2C dari modul machine.
from machine import Pin, SoftI2C
Anda juga perlu mengimpor library OLED yang telah diunggah sebelumnya ke papan sebagai file ssd1306.py.
import ssd1306
Pin I2C bawaan ESP32 adalah GPIO 22 (SCL) dan GPIO 21 (SDA). Pin I2C bawaan ESP8266 adalah GPIO 5 (SCL) dan GPIO 4 (SDA).
Gunakan baris berikut jika Anda menggunakan papan ESP32:
# ESP32 Pin assignment
i2c = SoftI2C(scl=Pin(22), sda=Pin(21))
Beri komentar pada baris sebelumnya dan hapus komentar pada baris berikut jika Anda menggunakan papan ESP8266:
#ESP8266 Pin assignment
i2c = SoftI2C(scl=Pin(5), sda=Pin(4))
Tentukan lebar dan tinggi OLED pada variabel berikut:
oled_width = 128
oled_height = 64
Setelah itu, buat objek SSD1306_I2C bernama oled. Objek ini menerima parameter lebar OLED, tinggi OLED, dan pin I2C yang telah Anda definisikan sebelumnya.
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
Setelah menginisialisasi layar OLED, Anda hanya perlu menggunakan fungsi text() pada objek oled untuk menulis teks. Setelah fungsi text(), Anda harus memanggil metode show() untuk memperbarui tampilan OLED.
oled.text('Hello, World 1!', 0, 0)
oled.text('Hello, World 2!', 0, 10)
oled.text('Hello, World 3!', 0, 20)
oled.show()
Metode text() menerima argumen berikut (berurutan):
1. Pesan: harus bertipe String
2. Posisi X: tempat teks dimulai secara horizontal
3. Posisi Y: tempat teks ditampilkan secara vertikal
4. Warna teks: dapat berwarna hitam atau putih. Warna default adalah putih dan parameter ini opsional.
- `0` = hitam
- `1` = putih
Contoh, baris berikut menulis pesan 'Hello, World 1!' dengan warna putih. Teks dimulai pada x = 0 dan y = 0.
oled.text('Hello, World 1!', 0, 0)
Baris kode berikutnya menulis teks di baris berikutnya (y = 10).
oled.text('Hello, World 2!', 0, 10)
Akhirnya, agar perubahan diterapkan, gunakan metode show() pada objek oled.
oled.show() Untuk mengosongkan layar, gunakan metode fill() dan berikan 0 sebagai argumen (mengatur semua piksel menjadi hitam):
Demonstrasi
Unggah kode ke papan Anda. Layar OLED Anda akan terlihat seperti berikut:
Fungsi OLED Lainnya
Library ini menyediakan metode lain untuk berinteraksi dengan layar OLED.
Mengisi Layar
Untuk mengisi seluruh layar dengan warna putih, gunakan fungsi fill() seperti berikut:
oled.fill(1)
oled.show()
Untuk mengosongkan layar, gunakan metode fill() dan berikan 0 sebagai argumen (mengatur semua piksel menjadi hitam):
oled.fill(0)
oled.show()
Menggambar Piksel
Untuk menggambar sebuah piksel, gunakan metode pixel() diikuti dengan show(). Metode pixel() menerima argumen berikut:
1. Koordinat X: lokasi piksel secara horizontal
2. Koordinat Y: lokasi piksel secara vertikal
3. Warna piksel: dapat berwarna hitam atau putih
- `0` = hitam
- `1` = putih
Contoh, untuk menggambar piksel putih di sudut kiri atas:
oled.pixel(0, 0, 1)
oled.show()
Membalikkan Warna
Anda juga dapat membalikkan warna OLED: putih jadi hitam dan sebaliknya, menggunakan metode invert():
oled.invert(True)
Untuk kembali ke warna asli, gunakan:
oled.invert(False)
Menampilkan Data dari Sensor
Fungsi text() hanya menerima variabel bertipe string sebagai pesan. Pembacaan sensor biasanya disimpan dalam variabel bertipe int atau float.
Jika Anda ingin menampilkan pembacaan sensor dan data tersebut disimpan dalam variabel int atau float, data tersebut harus dikonversi ke string. Untuk mengonversi data menjadi string, Anda dapat menggunakan fungsi str():
temperature = 12.34
temperature_string = str(temperature)
Kemudian, Anda dapat menampilkan variabel temperature_string pada OLED menggunakan metode text() dan show():
oled.text(temperature_string, 0, 0)
oled.show()
Baca juga: MicroPython ESP32 & ESP8266 - Cara Menggunakan Sensor BME280 (Tekanan, Suhu, Kelembaban)
Dalam praktik, hasil dan kendala yang ditemui bisa berbeda tergantung perangkat, konfigurasi, versi library, dan sistem yang digunakan.
- Diskusi umum dan tanya jawab praktik: https://t.me/edukasielektronika
- Kendala spesifik dan kasus tertentu: http://bit.ly/Chatarduino















0 on: "Tutorial MicroPython ESP32/ESP8266 - Cara Menggunakan OLED Display (SSD1306)"