[PYTHON] Control Akizuki's I2C-connected OLED display from Raspberry Pi

Let's control the SO1602A series of organic EL character displays sold in Akizuki using Raspberry Pi and Python. Organic EL character display module 16x2 lines white I used white this time, but green and yellow are also sold at the same price.

wiring

The connection between RasPi and SO1602A is very easy, and there are a total of 4 I2C SCL and SDA on the power supply (3.3V) and GND. In addition, wiring is required in several places on the SO1602 side.

Pin number function
1 GND
2 VDD (3.3V)
3 /CS (Chip Select, Low)
4 SA0 (Slave Address)
5, 6 No Connect
7 SCL
8 SDA_in
9 SDA_out
10-14 No Connect

The above table is an excerpt from p.7 of the data sheet. The points to note when wiring are as follows.

Preparing RasPi

Preparations for using I2C on RasPi are omitted here. [This article](http://make.bcde.jp/raspberry-pi/i2c%E3%82%92%E4%BD%BF%E3%81%86%EF%BC%88%E8%A8% Set by referring to AD% E5% AE% 9A% E7% B7% A8% EF% BC% 89 /).

Python preparation

Use SMBus to operate I2C from Python. You can install it with apt-get.

$ sudo apt-get install python-smbus

Display control

Connection and initialization

The slave address of SO1602A is either 0x3C (SA0 = Low) or 0x3D (SA0 = High). This time I wrote the constructor as follows. SA0 can now select Low / High and the cursor display state in the initial state.

class SO1602A():
    def __init__(self, sa0 = 0, cursor = False, blink = False):
        self.bus = smbus.SMBus(1)
        if (sa0 == 0):
            self.addr = 0x3c
        else:
            self.addr = 0x3d
        self.clearDisplay()
        self.returnHome()
        self.displayOn(cursor, blink)
        self.clearDisplay()

Command execution

The SO1602A has several commands. ClearDisplay and returnHome in the above constructor are methods corresponding to those commands. To execute the command,

  1. Send the data (0x00) that says "I'm going to send a command".
  2. Send a command.

It is necessary to take the procedure. When I write this in Python, it looks like the following.

    def clearDisplay(self):
        self.bus.write_byte_data(self.addr, 0x00, 0x01)
    
    def returnHome(self):
        self.bus.write_byte_data(self.addr, 0x00, 0x02)

    def displayOn(self, cursor = False, blink = False):
        cmd = 0x0c
        if (cursor):
            cmd += 0x02
        if (blink):
            cmd += 0x01
        self.bus.write_byte_data(self.addr, 0x00, cmd)

    def displayOff(self):
        self.bus.write_byte_data(self.addr, 0x00, 0x08)

There are various other command options, but for the time being, you can operate it as a display.

Send a string

Finally, let's display the characters on the display. To send a string

  1. Use the command to move the cursor position to any location
  2. Send the data (0x40) that says "I'm going to send a character string".
  3. Send the string.

It is necessary to take the procedure. Similarly, when I wrote it in Python, it looked like the following.

def writeLine(self, str = '', line = 0, align = 'left'):
    #If the string is less than 16 characters, fill it with spaces
    while (len(str) < 16):
        if (align == 'right'):
            str = ' ' + str
        else:
            str = str + ' '

    #Align the cursor position
    if (line == 1):
        self.bus.write_byte_data(self.addr, 0x00, (0x80 + 0x20))
    else:
        self.bus.write_byte_data(self.addr, 0x00, 0x80)

    #Send one character at a time
    for i in range(len(str)):
        self.bus.write_byte_data(self.addr, 0x40, ord(str[i]))

Since the character string is written in the form of overwriting the memory block by block, If you write "ABC" in the place where "Hello" was displayed, the display will be "ABClo". This is why if the string is less than 16 characters, it is padded with spaces.

It is also a command to move the cursor position, This is done by sending 0x80 plus the value of the address counter. The value of the address counter is 0x00 at the beginning of the first line, followed by 0x01, 0x02 ,,, 0x0F. The beginning of the second line is 0x20, then 0x21, and so on. Here, writeLine is implemented as a method that completely rewrites the first or second line.

After that, the ASCII code of the characters will be sent in order. There seems to be a method called write_block_data that sends data all at once, For some reason it didn't work, so I'm sending one character at a time with write_byte_data.

IMG_0749.jpg

So, I was able to display the characters on the display safely. The organic EL display has very good color development and very high visibility. The viewing angle is not as narrow as the LCD. The breadboard in the photo has other switches connected, so the wiring is messed up, but if you only want to move the display, you only need four.

IMG_0750.jpg

You can also display the character string by selecting right-justified or left-justified. The'g'is a little clunky, but it's a cute character display.

at the end

I uploaded the code I wrote this time to gist. Since Python is a beginner, it may be unsightly, but please forgive me.

Recommended Posts

Control Akizuki's I2C-connected OLED display from Raspberry Pi
[Raspberry Pi] Stepping motor control with Raspberry Pi
Servo motor control with Raspberry Pi
Operate an I2C-connected display from Python
Output from Raspberry Pi to Line
Send data from Raspberry Pi using AWS IOT
Display CPU temperature every 5 seconds on Raspberry Pi 4
Raspberry Pi backup
From setting up Raspberry Pi to installing Python environment
Display images taken with the Raspberry Pi camera module
Control brushless motors with GPIOs on Raspberry Pi Zero
Face detection from images taken with Raspberry Pi camera
Control power on / off of USB port of Raspberry Pi
Install pyenv on Raspberry Pi and version control Python
Display USB camera video with Python OpenCV with Raspberry Pi
Control the display of RGB LED matirix electric bulletin board freely with Raspberry Pi 3B +