Friday, September 22, 2023
Google search engine
HometelecomInterface OLED Display with ESP32 using MICROPYTHON

Interface OLED Display with ESP32 using MICROPYTHON

Introduction of OLED Display

The new generation of small, interactive displays is a great way to add user-interactivity and interactivity with your favourite IoT project. The 0.96 inch OLED panel has been growing in popularity because it can be used as an input device or output screen for any application that requires these features such as
Health tracking systems where people wearables might monitor heart rates 24/7 without bothering you while sleeping at night!
Air quality monitoring system.
Tracking Bitcoin
Weather forecasting and many more.
One such oled display module is SSD1306.
Youtube link

Oled display Pins and Specifications

Add image related to pin diagram for oled display>>
  • 3V-5V Supply input Voltage
  • 2ma -24ma current consumption
  • 128 pixel wide and 64 pixel Tall
  • Wide Viewing angle.
  • Oled display will either use I2C or SPI. write about I2C or SPI accordingly.
The OLED display  maps 18×64 pixels into 0 or 1 value. Each pixel is represented by a single bit , this leads to 8192 bits of data being written to the OLED display in single Write operation 8192 bits = 1024 bytes = 1KB. ESP32 with OLED display Connectivity diagram.

Add image>>
Add a fritzing file link.

MicroPython based
Code:
Driver Code: || Src Code.
MicroPython Driver Code:
 
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces
 
from micropython import const
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_IREF_SELECT = const(0xAD)
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)
 
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
    def __init__(self, width, height, external_vcc):
        self.width = width
        self.height = height
        self.external_vcc = external_vcc
        self.pages = self.height // 8
        self.buffer = bytearray(self.pages * self.width)
        super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
        self.init_display()
 
    def init_display(self):
        for cmd in (
            SET_DISP,  # display off
            # address setting
            SET_MEM_ADDR,
            0x00,  # horizontal
            # resolution and layout
            SET_DISP_START_LINE,  # start at line 0
            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.width > 2 * self.height 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
            SET_IREF_SELECT,
            0x30,  # enable internal IREF during display on
            # charge pump
            SET_CHARGE_PUMP,
            0x10 if self.external_vcc else 0x14,
            SET_DISP | 0x01,  # display on
        ):  # on
            self.write_cmd(cmd)
        self.fill(0)
        self.show()
 
    def poweroff(self):

        self.write_cmd(SET_DISP)

 

    def poweron(self):

        self.write_cmd(SET_DISP | 0x01)

 

    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 rotate(self, rotate):

        self.write_cmd(SET_COM_OUT_DIR | ((rotate & 1) << 3))

        self.write_cmd(SET_SEG_REMAP | (rotate & 1))

 

    def show(self):

        x0 = 0

        x1 = self.width – 1

        if self.width != 128:

            # narrow displays use centred columns

            col_offset = (128 – self.width) // 2

            x0 += col_offset

            x1 += col_offset

        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, width, height, 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__(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_data(self, buf):

        self.write_list[1] = buf

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

 

 

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

        import time

 

        self.res(1)

        time.sleep_ms(1)

        self.res(0)

        time.sleep_ms(10)

        self.res(1)

        super().__init__(width, height, 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)

Micropython Src Code

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

# ESP32 Pin assignment
i2c = I2C(-1, scl=Pin(5), sda=Pin(4))
oled_width = 128
oled_height = 64
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c)
oled.text(‘Welcome’, 0, 0)
oled.text(‘OLED Display’, 0, 10)
oled.text(‘welcome to iottrends.tech’, 0, 20)
oled.text(‘I am READY!! When you are?’, 0, 30)
oled.show()

Sample Output.

Welcome

OLED Display

Welcome to iottrends.tech

I am READY!! When you are?

Code Explanation

import ssd1306

This imports the OLED Library that was uploaded previously to the Board.

i2c = I2C(-1, scl=Pin(5), sda=Pin(4))

We are defining the I2C Pins of ESP32 Board here. The ESP32 default I2C pins are GPIO22 (SCL) and GPIO21 (SDA). In case of MakePython ESP32 Board, the GPIO Pins are GPIO5 (SCL) and GPIO4 (SDA)

oled_width = 128

oled_height = 64

This line defines the OLED height and width

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

Then we create an SSD1306_I2C object called oled. This object accepts the OLED width, height, and the I2C pins defined earlier.

oled.text(‘Welcome’, 0, 0)

oled.text(‘OLED Display’, 0, 10)

Using oled we are initializing the OLED display & using the text() function we are write text.
oled.show()

Using this line we call the show() method to update the OLED.

RELATED ARTICLES

2 COMMENTS

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -
Google search engine

Most Popular

ESP32 – MicroSD

ESP32-ESP8266 – DTH11 SENSOR

ESP32-ESP8266 – MOTION SENSOR

Recent Comments