注釈

こんにちは、SunFounder Raspberry Pi & Arduino & ESP32 Enthusiast Community on Facebookへようこそ!他の愛好家と一緒に、Raspberry Pi、Arduino、ESP32の世界により深く入り込みましょう。

参加する理由

  • 専門家サポート: 購入後の問題や技術的な課題を、コミュニティと私たちのチームの助けを借りて解決します。

  • 学習と共有: ヒントやチュートリアルを交換して、スキルを向上させましょう。

  • 限定プレビュー: 新製品の発表や先行プレビューに早期アクセスできます。

  • 特別割引: 最新製品を特別割引でお楽しみいただけます。

  • 季節限定キャンペーンとプレゼント: プレゼント企画やホリデーキャンペーンに参加しましょう。

👉 一緒に発見し、創造する準備はできましたか? [こちら] をクリックして、今すぐ参加しましょう!

1.10 OLEDディスプレイ

はじめに

このプロジェクトでは、Raspberry PiでI2C通信を使用してSSD1306ベースのOLEDディスプレイを接続する方法を学びます。OLED(Organic Light-Emitting Diode)ディスプレイは、高コントラスト、広い視野角、低消費電力という特長を持っています。このプロジェクトでは、ディスプレイの初期化、基本図形の描画、テキストの表示方法を紹介します。


必要なもの

このプロジェクトを行うには、以下のコンポーネントが必要です。

COMPONENT

PURCHASE LINK

OLED Display Module

-

ジャンパーワイヤー

購入

Fusion HAT+

-

Raspberry Pi

-


配線図

以下の手順に従って回路を組み立ててください。

  1. OLEDディスプレイのVCCピンをFusion HAT+の3.3Vに接続します

  2. OLEDディスプレイのGNDピンをFusion HAT+のGNDに接続します

  3. OLEDディスプレイのSCLピンをFusion HAT+のSCL(GPIO 3)に接続します

  4. OLEDディスプレイのSDAピンをFusion HAT+のSDA(GPIO 2)に接続します

../_images/1.10_oled_bb.png

セットアップ手順

  1. SSD1306ドライバライブラリをインストールします:

    このライブラリを使用すると、PythonからSSD1306 OLEDディスプレイと通信できるようになります。

    sudo pip3 install adafruit-circuitpython-ssd1306 --break
    
  2. すべてのサンプルプログラムは ai-lab-kit ディレクトリに含まれています。以下のようにOLEDのサンプルを実行してください。

    cd ~/ai-lab-kit/python/
    sudo python3 1.10_OLED_Display.py
    
  3. サンプルを実行すると、OLED画面には枠線付きのボックスが表示され、その中央に 「Hello World!」 という文字が表示されます。

    これは、ディスプレイがI2C経由で正常に通信しており、テキストやグラフィックスを正しく描画できることを示しています。


コード

以下のPythonコードは、OLEDディスプレイを初期化し、「Hello World!」という文字を描画します。

import board
import digitalio
from PIL import Image, ImageDraw, ImageFont
import adafruit_ssd1306

# Initialize OLED display dimensions
WIDTH = 128
HEIGHT = 64

# Set up I2C communication with the OLED display
i2c = board.I2C()  # Utilizes board's SCL and SDA pins
oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C)

# Clear the OLED display
oled.fill(0)
oled.show()

# Create a new image with 1-bit color for drawing
image = Image.new("1", (oled.width, oled.height))

# Obtain a drawing object to manipulate the image
draw = ImageDraw.Draw(image)

# Draw a filled white rectangle as the background
draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255)

# Define border size for an inner rectangle
BORDER = 5
# Draw a smaller black rectangle inside the larger one
draw.rectangle(
   (BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1),
   outline=0,
   fill=0,
)

# Load the default font for text
font = ImageFont.load_default()

def getfontsize(font, text):
   # Calculate the size of the text in pixels
   left, top, right, bottom = font.getbbox(text)
   return right - left, bottom - top

# Define the text to be displayed
text = "Hello World!"
# Get the width and height of the text in pixels
(font_width, font_height) = getfontsize(font, text)
# Draw the text, centered on the display
draw.text(
   (oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2),
   text,
   font=font,
   fill=255,
)

# Send the image to the OLED display
oled.image(image)
oled.show()

このPythonスクリプトは、SSD1306 OLEDディスプレイに「Hello World!」を表示します。実行すると、次の処理が行われます。

  1. OLEDディスプレイとのI2C通信を初期化します

  2. 描画用の白黒画像バッファを作成します

  3. 白い背景と黒い枠付き長方形を描画します

  4. 「Hello World!」が中央に表示されるようにテキスト位置を計算します

  5. 最終的な画像をOLEDディスプレイに描画します

  6. 電源が切られるか、表示内容が更新されるまでテキストが表示され続けます


コードの解説

  1. ライブラリのインポート

    ディスプレイ制御と画像処理に必要なライブラリをインポートします。

    import board
    import digitalio
    from PIL import Image, ImageDraw, ImageFont
    import adafruit_ssd1306
    
  2. ディスプレイの初期化

    指定した解像度とI2Cアドレスを使用してOLEDディスプレイを初期化します。

    WIDTH = 128
    HEIGHT = 64
    i2c = board.I2C()
    oled = adafruit_ssd1306.SSD1306_I2C(WIDTH, HEIGHT, i2c, addr=0x3C)
    
  3. ディスプレイのクリア

    画面を0(黒)で塗りつぶして更新し、ディスプレイをクリアします。

    oled.fill(0)
    oled.show()
    
  4. 画像バッファの作成

    描画処理用に1ビットカラーの画像バッファを作成します。

    image = Image.new("1", (oled.width, oled.height))
    draw = ImageDraw.Draw(image)
    
  5. 描画処理

    画像バッファ上に長方形やテキストを描画します。

    # Background rectangle
    draw.rectangle((0, 0, oled.width, oled.height), outline=255, fill=255)
    # Inner bordered rectangle
    draw.rectangle((BORDER, BORDER, oled.width - BORDER - 1, oled.height - BORDER - 1), outline=0, fill=0)
    
  6. テキストの描画

    フォント情報を利用して、テキストをディスプレイの中央に配置します。

    font = ImageFont.load_default()
    (font_width, font_height) = getfontsize(font, text)
    draw.text((oled.width // 2 - font_width // 2, oled.height // 2 - font_height // 2), text, font=font, fill=255)
    
  7. ディスプレイの更新

    最終的な画像をOLEDディスプレイに送信して表示します。

    oled.image(image)
    oled.show()
    

トラブルシューティング

  1. ディスプレイに何も表示されない

    • 原因: I2Cアドレスが正しくない、配線に問題がある、またはI2Cが有効になっていない可能性があります。

    • 対処方法: I2Cアドレス(0x3Cまたは0x3D)を確認し、すべての接続をチェックしてください。また、Raspberry Piの設定(sudo raspi-config)でI2Cを有効にしてください。

  2. I2C通信エラー

    • 原因: I2Cバスに問題がある、またはデバイスが検出されていない可能性があります。

    • 対処方法: i2cdetect -y 1 コマンドを使ってデバイスが検出されるか確認してください。また、I2Cバス上で他のデバイスと競合していないことを確認してください。

  3. テキストやグラフィックスが正しく表示されない

    • 原因: 色の値や座標の設定が正しくない可能性があります。

    • 対処方法: 1ビットカラーモードでは、0が黒、255が白であることを確認してください。また、座標がディスプレイの範囲内(幅0~127、高さ0~63)に収まっていることを確認してください。

  4. ライブラリのインポートエラー

    • 原因: 依存ライブラリが不足している、またはインストールが正しく行われていない可能性があります。

    • 対処方法: 必要なライブラリが正しい環境にインストールされていることを確認し、権限の問題がある場合は sudo を付けて実行してください。


拡張アイデア

  1. システム情報の表示

    CPU使用率、メモリ使用率、温度をリアルタイムで表示するシステムモニターを作成できます。

    import psutil
    import time
    
    while True:
        # Clear and redraw
        draw.rectangle((0, 0, oled.width, oled.height), fill=0)
    
        # Get system info
        cpu_percent = psutil.cpu_percent()
        memory = psutil.virtual_memory()
        temp = psutil.sensors_temperatures()['cpu_thermal'][0].current
    
        # Display info
        draw.text((0, 0), f"CPU: {cpu_percent}%", font=font, fill=255)
        draw.text((0, 16), f"RAM: {memory.percent}%", font=font, fill=255)
        draw.text((0, 32), f"Temp: {temp}C", font=font, fill=255)
    
        oled.image(image)
        oled.show()
        time.sleep(2)
    
  2. スクロールテキスト

    長いメッセージを表示するためのスクロールテキスト効果を作成できます。

    text = "This is a scrolling text message!"
    text_width = getfontsize(font, text)[0]
    
    for x in range(oled.width, -text_width, -1):
        draw.rectangle((0, 0, oled.width, oled.height), fill=0)
        draw.text((x, oled.height//2), text, font=font, fill=255)
        oled.image(image)
        oled.show()
        time.sleep(0.05)
    
  3. アニメーション表示

    基本図形を使ってシンプルなアニメーションを作成できます。

    for i in range(0, oled.width-10, 5):
        draw.rectangle((0, 0, oled.width, oled.height), fill=0)
        draw.rectangle((i, 20, i+10, 30), fill=255)  # Moving rectangle
        oled.image(image)
        oled.show()
        time.sleep(0.1)
    
  4. 複数ページ表示

    ボタン操作でページを切り替えるマルチページ表示を作成できます。

    pages = ["Page 1: Info", "Page 2: Stats", "Page 3: Graph"]
    current_page = 0
    
    # Use buttons to change pages
    def next_page():
        global current_page
        current_page = (current_page + 1) % len(pages)
        update_display()
    
  5. カスタムフォント

    見た目をより魅力的にするために、さまざまなフォントを使用できます。

    # Load custom font (requires font file)
    try:
        custom_font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 12)
    except:
        custom_font = ImageFont.load_default()
    
  6. グラフとチャート

    シンプルな棒グラフやチャートを表示できます。

    data = [10, 25, 45, 30, 60, 15]
    for i, value in enumerate(data):
        x = i * 20 + 5
        height = int(value / 100 * oled.height)
        draw.rectangle((x, oled.height-height, x+15, oled.height), fill=255)
    

まとめ

このプロジェクトでは、Raspberry PiでI2C通信を使用してSSD1306 OLEDディスプレイを接続する方法を紹介しました。OLEDディスプレイは、システムモニタリング、ユーザーインターフェース、情報表示など、さまざまな用途に適した鮮明で高コントラストな表示を提供します。テキスト、図形、グラフィックスを組み合わせることで、情報量が多く視覚的にも魅力的な表示を作成できます。ここで学んだ内容は、より高度なユーザーインターフェース、データ可視化、リアルタイム監視システムの構築にも応用できます。