1.3" OLED Display with SH1106 Controller

Overview

The 1.3" OLED display with the SH1106 controller is a compact, high-contrast monochrome display ideal for embedded applications. With a resolution of 128x64 pixels and I2C connectivity, it integrates seamlessly with Raspberry Pi-based systems like Andino boards. This guide provides detailed instructions to set up the display, install the luma.oled driver, create a file-to-OLED daemon for persistent text display, and control it via Node-RED. Additionally, it includes steps to run the daemon as a systemd service for reliable operation.

Installation and Configuration Guide

Prerequisites

Step 1: Enable I2C Interface

  1. Open the Raspberry Pi configuration tool:
    sudo raspi-config
  2. Navigate to Interfacing Options > I2C and enable I2C.
  3. Reboot the Raspberry Pi:
    sudo reboot

Step 2: Install I2C Tools and Test the Connection

  1. Install i2c-tools:
    sudo apt-get update
    sudo apt-get install -y i2c-tools
  2. Verify the OLED display is detected (typical address is 0x3C or 0x3D):
    sudo i2cdetect -y 1

    If no address appears, check wiring and ensure I2C is enabled.

Step 3: Install Python and PIP

  1. Ensure Python 3 and pip are installed:
    sudo apt-get install -y python3 python3-pip python3-venv
  2. Verify versions:
    python3 --version
    pip3 --version

Step 4: Install luma.oled Driver

  1. Create a virtual environment to avoid system conflicts:
    python3 -m venv ~/oled_venv
    source ~/oled_venv/bin/activate
  2. Install luma.oled and dependencies:
    pip install --upgrade pip
    pip install luma.oled
    sudo apt-get install -y python3-pil python3-numpy
  3. Test the installation with a simple script:

    # /home/pi/test_oled.py
    from luma.core.interface.serial import i2c
    from luma.oled.device import sh1106
    from luma.core.render import canvas
    
    serial = i2c(port=1, address=0x3C)
    device = sh1106(serial)
    with canvas(device) as draw:
       draw.text((0, 0), "Hello, Andino!", fill="white")
    device.show()
  4. Run the test:
    source ~/oled_venv/bin/activate
    python3 /home/pi/test_oled.py

    The display should show "Hello, Andino!" temporarily.

Step 5: Create the File-to-OLED Daemon

To display text persistently, create a daemon that monitors a text file for updates and displays the content on the OLED.

  1. Create the daemon script:

    # /home/pi/sh1106_luma_display_daemon.py
    import time
    import os
    from luma.core.interface.serial import i2c
    from luma.oled.device import sh1106
    from luma.core.render import canvas
    
    # I2C connection
    serial = i2c(port=1, address=0x3C)
    device = sh1106(serial)
    
    # File for text updates
    TEXT_FILE = "/home/pi/display_text.txt"
    
    # Initial text
    current_text = "Andino OLED Ready"
    
    # Update display function
    def update_display(text):
       with canvas(device) as draw:
           draw.text((0, 0), text, fill="white")
       device.show()
    
    # Initial display
    update_display(current_text)
    
    # Monitor text file
    try:
       while True:
           if os.path.exists(TEXT_FILE):
               with open(TEXT_FILE, "r") as f:
                   new_text = f.read().strip()
               if new_text != current_text:
                   current_text = new_text
                   update_display(current_text)
           time.sleep(0.5)  # Check every 0.5 seconds
    except KeyboardInterrupt:
       device.clear()
       device.hide()
  2. Make the text file writable:
    touch /home/pi/display_text.txt
    chmod 666 /home/pi/display_text.txt
  3. Test the daemon:
    source ~/oled_venv/bin/activate
    python3 /home/pi/sh1106_luma_display_daemon.py &

    The display should show "Andino OLED Ready". Update the text file:

    echo "Test Display" > /home/pi/display_text.txt

    The display should update to "Test Display" and persist.

Step 6: Control the Display via Node-RED

To update the display text using Node-RED:

  1. Ensure Node-RED is installed:
    bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
    node-red-start
  2. Open Node-RED in a browser (http://<Raspberry-Pi-IP>:1880).
  3. Create a flow:
    • Add an Inject node:
      • Payload: String, e.g., "Hello from Node-RED".
      • Repeat: Optional, e.g., every 10 seconds for testing.
    • Add a File node:
      • Action: Write file.
      • Filename: /home/pi/display_text.txt.
      • Msg: msg.payload.
    • Connect the nodes and deploy.
  4. Click the Inject node. The display updates with the injected text.

Step 7: Run the Daemon as a Systemd Service

To ensure the daemon starts automatically on boot:

  1. Create a systemd service file:
    sudo nano /etc/systemd/system/oled-daemon.service
  2. Add the following:

    [Unit]
    Description=SH1106 OLED Display Daemon
    After=network.target
    
    [Service]
    ExecStart=/home/pi/oled_venv/bin/python3 /home/pi/sh1106_luma_display_daemon.py
    WorkingDirectory=/home/pi
    StandardOutput=inherit
    StandardError=inherit
    Restart=always
    User=pi
    
    [Install]
    WantedBy=multi-user.target
  3. Enable and start the service:
    sudo systemctl enable oled-daemon.service
    sudo systemctl start oled-daemon.service
  4. Verify the service is running:
    sudo systemctl status oled-daemon.service

    The display should show "Andino OLED Ready" or the last text written to /home/pi/display_text.txt.

Troubleshooting

This setup provides a robust solution for displaying persistent text on the 1.3" OLED display, controlled via Node-RED and running reliably as a systemd service.

1.3" OLED Display with SH1106 Controller

Overview

The 1.3" OLED display with the SH1106 controller is a compact, high-contrast monochrome display ideal for embedded applications. With a resolution of 128x64 pixels and I2C connectivity, it integrates seamlessly with Raspberry Pi-based systems like Andino boards. This guide provides detailed instructions to set up the display, install the luma.oled driver, create a file-to-OLED daemon for persistent text display, and control it via Node-RED. Additionally, it includes steps to run the daemon as a systemd service for reliable operation.

Installation and Configuration Guide

Prerequisites

  • Raspberry Pi (e.g., Andino X1 or compatible) with Raspberry Pi OS (Bullseye or Bookworm recommended).
  • 1.3" OLED display with SH1106 controller connected via I2C:
    • VCC: 3.3V (e.g., Pin 1).
    • GND: Ground (e.g., Pin 6).
    • SDA: I2C Data (Pin 3, GPIO 2).
    • SCL: I2C Clock (Pin 5, GPIO 3).
  • Internet connection for package installation.

Step 1: Enable I2C Interface

  1. Open the Raspberry Pi configuration tool:
    sudo raspi-config
  2. Navigate to Interfacing Options > I2C and enable I2C.
  3. Reboot the Raspberry Pi:
    sudo reboot

Step 2: Install I2C Tools and Test the Connection

  1. Install i2c-tools:
    sudo apt-get update
    sudo apt-get install -y i2c-tools
  2. Verify the OLED display is detected (typical address is 0x3C or 0x3D):
    sudo i2cdetect -y 1

    If no address appears, check wiring and ensure I2C is enabled.

Step 3: Install Python and PIP

  1. Ensure Python 3 and pip are installed:
    sudo apt-get install -y python3 python3-pip python3-venv
  2. Verify versions:
    python3 --version
    pip3 --version

Step 4: Install luma.oled Driver

  1. Create a virtual environment to avoid system conflicts:
    python3 -m venv ~/oled_venv
    source ~/oled_venv/bin/activate
  2. Install luma.oled and dependencies:
    pip install --upgrade pip
    pip install luma.oled
    sudo apt-get install -y python3-pil python3-numpy
  3. Test the installation with a simple script:

    # /home/pi/test_oled.py
    from luma.core.interface.serial import i2c
    from luma.oled.device import sh1106
    from luma.core.render import canvas
    
    serial = i2c(port=1, address=0x3C)
    device = sh1106(serial)
    with canvas(device) as draw:
       draw.text((0, 0), "Hello, Andino!", fill="white")
    device.show()
  4. Run the test:
    source ~/oled_venv/bin/activate
    python3 /home/pi/test_oled.py

    The display should show "Hello, Andino!" temporarily.

Step 5: Create the File-to-OLED Daemon

To display text persistently, create a daemon that monitors a text file for updates and displays the content on the OLED.

  1. Create the daemon script:

    # /home/pi/sh1106_luma_display_daemon.py
    import time
    import os
    from luma.core.interface.serial import i2c
    from luma.oled.device import sh1106
    from luma.core.render import canvas
    
    # I2C connection
    serial = i2c(port=1, address=0x3C)
    device = sh1106(serial)
    
    # File for text updates
    TEXT_FILE = "/home/pi/display_text.txt"
    
    # Initial text
    current_text = "Andino OLED Ready"
    
    # Update display function
    def update_display(text):
       with canvas(device) as draw:
           draw.text((0, 0), text, fill="white")
       device.show()
    
    # Initial display
    update_display(current_text)
    
    # Monitor text file
    try:
       while True:
           if os.path.exists(TEXT_FILE):
               with open(TEXT_FILE, "r") as f:
                   new_text = f.read().strip()
               if new_text != current_text:
                   current_text = new_text
                   update_display(current_text)
           time.sleep(0.5)  # Check every 0.5 seconds
    except KeyboardInterrupt:
       device.clear()
       device.hide()
  2. Make the text file writable:
    touch /home/pi/display_text.txt
    chmod 666 /home/pi/display_text.txt
  3. Test the daemon:
    source ~/oled_venv/bin/activate
    python3 /home/pi/sh1106_luma_display_daemon.py &

    The display should show "Andino OLED Ready". Update the text file:

    echo "Test Display" > /home/pi/display_text.txt

    The display should update to "Test Display" and persist.

Step 6: Control the Display via Node-RED

To update the display text using Node-RED:

  1. Ensure Node-RED is installed:
    bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)
    node-red-start
  2. Open Node-RED in a browser (http://<Raspberry-Pi-IP>:1880).
  3. Create a flow:
    • Add an Inject node:
      • Payload: String, e.g., "Hello from Node-RED".
      • Repeat: Optional, e.g., every 10 seconds for testing.
    • Add a File node:
      • Action: Write file.
      • Filename: /home/pi/display_text.txt.
      • Msg: msg.payload.
    • Connect the nodes and deploy.
  4. Click the Inject node. The display updates with the injected text.

Step 7: Run the Daemon as a Systemd Service

To ensure the daemon starts automatically on boot:

  1. Create a systemd service file:
    sudo nano /etc/systemd/system/oled-daemon.service
  2. Add the following:

    [Unit]
    Description=SH1106 OLED Display Daemon
    After=network.target
    
    [Service]
    ExecStart=/home/pi/oled_venv/bin/python3 /home/pi/sh1106_luma_display_daemon.py
    WorkingDirectory=/home/pi
    StandardOutput=inherit
    StandardError=inherit
    Restart=always
    User=pi
    
    [Install]
    WantedBy=multi-user.target
  3. Enable and start the service:
    sudo systemctl enable oled-daemon.service
    sudo systemctl start oled-daemon.service
  4. Verify the service is running:
    sudo systemctl status oled-daemon.service

    The display should show "Andino OLED Ready" or the last text written to /home/pi/display_text.txt.

Troubleshooting

  • I2C not detected: Re-check wiring and run sudo i2cdetect -y 1. Adjust address=0x3C to 0x3D if needed.
  • Text disappears: Ensure the daemon is running (ps aux | grep sh1106_luma_display_daemon).
  • Node-RED file access: Verify Node-RED runs as the pi user and /home/pi/display_text.txt has 666 permissions.
  • Service fails: Check logs with journalctl -u oled-daemon.service and ensure the virtual environment path is correct.

This setup provides a robust solution for displaying persistent text on the 1.3" OLED display, controlled via Node-RED and running reliably as a systemd service.