[EN] ESP8266 and OLED

This article is about connecting the ESP8266 to an OLED, which is a two-color graphic LED, where 0 represents blank and 1 represents color dot. It is connected to the microcontroller via the I2C bus. How to use it and its functions are discussed as a guide and reference material for further implementation.

(Figure. 1 OLED usage)

Display controller

There are two types of LED display controllers: sh1106 or ssd1306 ICs. The LED modules are not usually specified, so the user can’t see because it is obscured by the LED module. The OLED (available in blue and white, or some models are assigned some rows to one color and some rows to another) selected in this article is I2C as shown in picture 2 and connected to esp8266 as shown in picture 3.

(Figure. 2 I2C OLED)
(Figure 3. Connecting to the esp8266’s SDA and SCL pins.)

Required library

import sh1106

or

import ssd1306

To run it, you have to see what the results are. If it comes out wrong, go back and choose another one.

Prepare i2c

from machine import I2C, Pin
i2c = I2C(sda=Pin(4), scl=Pin(5))
oled_addr = const(0x3c)
oled = sh1106.SH1106_I2C(128,64,i2c,None,oled_addr)

After running the library for the LED controller, the next step is to enable the I2C bus and create a variable to point to the OLED module.

Show message

oled.text("text", x, y, c=1)

where
c is the color dot, where 1 represents light and 0 represents black.
x,y are the coordinates of the upper-left corner of the initialized text.

Display information on the display

oled.show()

The show( ) command instructs the LED module controller to write data from all buffers to the LED module. Enable the visibility of the results of the commands assigned to the control.

Fill color

oled.fill( 1 )		# เติมสีสว่าง
oled.fill( 0 )		# เติมสีดำ

Color Fill sets the background color of all LED modules to a color 0 or 1 like clearing the screen with a color 0 or 1.

Place the pixels at the position (x,y).

oled.pixel( x, y, c )

where
x,y is the pixel coordinate where x values are in the range [0, 127] and y are in the range [0, 63]. c is the color value of the pixel which has a value of 0 or 1.

Invert the color

oled.invert( True )
oled.invert( False )

Inverting the color causes the dot to be changed to the opposite color, i.e. 0 is changed to 1, and from 1 it becomes 0. Therefore, when a color inversion technique is applied to screen flickers 5 times in 1 second, code is written as follows

for counter in range(5):
		oled.invert(True)
		time.sleep_ms(100)
		old.invert(False)
		time.sleep_ms(100)

Read the color value at the position (x,y)

c = oled.pixel( x, y )

where c is the color value read from the coordinates (x,y).

Draw a straight line horizontally.

oled.hline( x, y, w, c=1 )

where
x,y is the starting position

w is the length of the line c is the color

Draw a straight line vertically.

oled.vline( x, y, h, c=1 )

where
x,y is the starting position h is the length of

 the line c is the color

draw a straight line

oled.line( x1, y1, x2, y2, c=1 )

where
x1,y1 are the initial coordinates of the line.

x2,y2 are the ending coordinates of the line. c is the color

Draw a square

oled.rect( x, y, w, h, c )

where
x,y are the coordinates of the upper left corner of the rectangle.

w is the width of the rectangle

h is the height of the square c is the color

Draw a solid square

oled.fill_rect( x, y, w, h, c )

where
x,y are the coordinates of the upper left corner of the rectangle.

w is the width of the rectangle

h is the height of the square c is the color

Scroll the screen in the x and y axes.

oled.scroll( x, y )

where
x is the shift position in the x-axis.

y is the scroll position in the y-axis. For example, want to scroll down the screen 4 points and move to the left 8 points can be ordered as

oled.scroll( -8, -4 )

Drawing created by pixel art.

Drawing using one data per pixel.

Step 1: Create an image variable, e.g. to display “ก”.

korkai = [
	[ 0, 0, 1, 1, 1, 1, 1, 0 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ],
	[ 0, 0, 1, 0, 0, 0, 0, 1 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ],
	[ 0, 1, 0, 0, 0, 0, 0, 1 ]
]

Step 2 pixel e.g.

for ch_row in range(8):
	for ch_col in range(8):
		oled.pixel( ch_col, ch_row, korkai[ch_row][ch_col] )

Step 3 display

oled.show( )

Drawing using 1 bit of data per pixel.

Step 1: Create an image variable, e.g. to display “ก”.

korkai = [
	0b00111110,
	0b01000001,
	0b00100001,
	0b01000001,
	0b01000001,
	0b01000001,
	0b01000001,
	0b01000001
]

Step 2 pixel e.g.

for ch_row in range(8):
	bit = 0x80
	for ch_col in range(8):
		cl = korkai[ch_row]&bit
		oled.pixel( ch_col, ch_row, cl)
		bit >>= 1

Step 3 Display

oled.show( )

Drawing in bits and making it bold.

Modify Step 2 to draw two adjacent pixels instead of just one.

for ch_row in range(8):
	bit = 0x80
	for ch_col in range(8):
		cl = korkai[ch_row]&bit
		oled.pixel( ch_col*2, ch_row, cl)
		oled.pixel( ch_col*2+1, ch_row, cl)
		bit >>= 1

Drawing in bits and giving it 2 times the size.

Modify Step 2 to draw a 2×2 filled square instead of pixels.

for ch_row in range(8):
	bit = 0x80
	for ch_col in range(8):
		cl = korkai[ch_row]&bit
		oled.fill_rect( ch_col*2, ch_row*2, 2, 2, cl)
		bit >>= 1

Transparent drawing

Drawing transparent or translucent is to check the color data in the drawing, that is, if it is 1, it will plot the color, but if it is 0, it will not plot the color. It will not overlaid with 0 colors. For example, the transparent check and drawing is as follows.

for ch_row in range(8):
	bit = 0x80
	for ch_col in range(8):
		cl = korkai[ch_row]&bit
		if cl:
			oled.pixel( ch_col, ch_row, 1)
		bit >>= 1

Store the bitmap as a bytearray.

Step 1: Create an image variable, for example, want to represent “ก”, this method guarantees the size of each dataset is 1 byte.

korkai = bytearray(
	[0b00111110,
	0b01000001,
	0b00100001,
	0b01000001,
	0b01000001,
	0b01000001,
	0b01000001,
	0b01000001]
)

Step 2 pixel e.g.

for ch_row in range(8):
	bit = 0x80
	for ch_col in range(8):
		cl = korkai[ch_row]&bit
		oled.pixel( ch_col, ch_row, cl)
		bit >>= 1

Step 3 Display

oled.show( )

Adjust brightness

oled.contrast( cn )

where cn is the brightness level in the range 0 to 255.

Blit

Blit is a technique of sending a WxH size buffer to the display buffer. Results in better transmission efficiency than displaying WxH pixels by looping W*H times.

The data format applied to the blitz must be a bytearray and the format of the command is as follows.

oled.blit( buf, x, y )

โดย

where
buf is a FrameBuffer data type that stores image data. x,y are the coordinates of the top-left corner of the LED module used to initialize the image.

The process of creating a framebuffer data is as follows:

import  framebuf
data = bytearray([data])
buf = framebuf.FrameBuffer( data, width, height, framebuf.MONO_HLSB)

Example of drawing “ก” with a blit

Step 1: Create an image variable, e.g. to display “ก”.

korkai = bytearray(
	[0b00111110,
	 0b01000001,
	 0b00100001,
	 0b01000001,
	 0b01000001,
	 0b01000001,
	 0b01000001,
	 0b01000001]
)

Step 2 create FrameBuffer

buf = framebuf.FrameBuffer( korkai, 8, 8, framebuf.MONO_HLSB)

Step 3. Blot the image at the position (x, y).

oled.blit(buf, x, y )

Step 4 Display

oled.show( )

Conclusion

From this article, we can operate the OLED module display via the I2C bus using only 2 signal wires, sda and scl, and learn the commands and examples of how to use it. Finally, we hope this article will be helpful to you and have fun with programming.

If you want to discuss or share with us, please leave comments below!

References

  1. SH1106 โดย robert-hh
  2. ssd1306 โดย randomnerdtutorials.com

(C) 2020-2021, By Jarut Busarathid and Danai Jedsadathitikul
Updated 2021-10-05