単色OLEDモジュールを使う(SSD1306 / I2C)

コンピュータ、組み込み

RP2040(Raspberry Pi pico)のI2C接続、ESP32(BananaPi PicoW)のI2C接続での表示をします。
Raspberry Pi PicoでのDual Monitor と I2Cを2系統使用した表示をします。

紹介するもの

OLED SSD1306

特徴

同じSSD1306を使用しますが通信方式には4線式I2Cと、7線のSPI接続の方式があります。
購入時にはどちらかの通信方式を使用するか確認してください。
本記事ではI2C単色表示について記載します。

製品情報
サイズ0.4 ~ 2.4inch
代表(0.49, 0.91, 0.92, 1.54, 2.42inch)
解像度(X, Y)0.49inch : 128, 64 (有効表示エリアは64, 32)
0.91inch : 128, 32
0.92inch : 128, 64 (本記事では こちらを紹介)
1.54inch : 128, 64
2.42inch : 128, 64
表示色白、青、黄、黄+青
黄+青の場合、それぞれのエリアが決まっていて、
色の変更はできないようです。
電源電圧3.3 – 5.0V
通信方式I2C(アドレスは 0x3c, または0x3dのどちらかを選択)
SPI
ドライバSSD1306
入手電子部品ショップ、ネットショップ
入手性は非常に良く、安く大量買いする場合はAli Express
外観(I2C)

前面

背面

使用感

I2Cでの接続による制御は少ない配線で表示ができるため作業が楽です。
I2Cではアドレスが違うモジュールをチェーンできます。
OLEDは0x3cと0x3dをサポートしているので、1つのI2Cラインには2個のOLEDを繋げることができます。(後半にサンプルソースがあります)

Adafruit製のライブラリを使用していますが、命令がシンプルで使いやすいと思います。
簡単な命令と配線で表示ができるので、解像度の低いゲームやメニューに使用するほか、プログラムのデバッグや結果の表示などに重宝します。
各種モジュールの中では使用頻度は高い部類になるので、1つは持っておきたいモジュールです。

SSD1306は画面のサイズが豊富にありますが、解像度は128, 64です。
(画面縦横比の違うものなど一部の機種は、128,64のうちの「どこか」を表示しています)
画面サイズが違っても1ドット(pixel)のサイズが違うだけなので、画面が大きくても表現が豊かにはなりません。

準備

OLEDのI2Cアドレス確認

OLEDモジュールの裏面を確認して、現在のI2Cアドレスの設定を確認します。
デフォルトでは0x03cです。

使用するモジュールのアドレスは、0x3cまたは0x3dのどちらかを選択できます。
今回は両方のアドレスの使い方を紹介しますが、はんだ作業が必要となるので自信のない方は現在の設定のまま使用することをお勧めします。

I2Cアドレスを設定する抵抗を外した
I2Cアドレスを0x3dになるように取り付けた

ライブラリ

ライブラリは以下2つのライブラリを使用します。

ライブラリAdafruit SSD1306 by Adafruit Ver2.5.1
Adafruit GFX Library Ver 1.11.1
※Verは 記事編集時 2022/6/19 のバージョンです。
赤太字箇所をライブラリマネージャの検索欄に入力することで検索できます。

使い方

I2Cによる表示(RP2040系 Raspberry Pi Pico)

I2C0を使ったOLEDの表示です。
一番多く使われると思います。

配線

RP2040 picoワイヤ色SSD1306(0x3c)
3.3VVCC
GNDGND
GP0SDA
GP1SCL
()はI2Cアドレス

スケッチ

//Programing by たまねぎ
//【スケッチの説明】
//RP2040 CPU搭載基板で使用できます。
//OLED画面に "TAMANEGI"
//使用しているI2CラインとI2Cアドレスを表示させます。
//
//【準備】
//・RP2040 pico側
//本スケッチでは SDA に GP0, SCL に GP1 を使用します。
//・SSD1306 OLED側
////I2Cアドレスは 0x3c 
//
//【バージョン情報】
// 2022/6/19 : 新規

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
                                        //表示制御にはAdafruit製 SSD1306を使用する。
                                        //初期化時には I2C0を使用する (Wire)
                                        
void setup() {
  
  Wire.setSDA(0);                       //I2C0で使用するGPは SDA = 0, SCL = 1
  Wire.setSCL(1);

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 10);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(10, 30);
  display.print(F("I2C0 0x3c"));

  display.display();                    //バッファ転送(表示)
}

void loop() {
}

結果

I2Cによる表示(ESP32系 ESP32-S3 BananaPi PicoW)

ESP32系でのI2Cを使ったOLEDの表示です。
リンク先の記事で同じサンプルを掲載しています。

配線

BananaPi PicoWワイヤ色SSD1306(0x3c)
3.3VVCC
GNDGND
GPIO8SDA
GPIO9SCL
()はI2Cアドレス

スケッチ

/**********************************************************************
【ライセンスについて】
Copyright(c) 2022 by tamanegi
Released under the MIT license
'http://tamanegi.digick.jp/about-licence/

【マイコン基板】
BananaPi PicoWで利用できます。

【スケッチの説明】
SSD1306 OLEDの制御をします。
デフォルトのピンで動作させますが、任意の位置に設定するサンプルも記載します。

【ライブラリ】
esp32 > ESP32S3 Dev Module
Adafruit SSD1306 by Adafruit
Adafruit GFX Library by Adafruit

【準備】
マイコン基板 <-> SSD1306
3V3         <-> VCC
GND         <-> GND
GPIO8(SDA)  <-> SDA
GPIO9(SCL)  <-> SCL
BananaPi PicoWの I2Cでは、 Wire.setPins()により任意の位置にI2CのSDA, SCLを設定することができます。

【バージョン情報】
2022/11/30 : 新規
**********************************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
                                        //表示制御にはAdafruit製 SSD1306を使用する。

//任意の位置にピン設定する場合の定義
#define PIN_SDA 8
#define PIN_SCL 9                                   

void setup()
{
//  任意のピンをI2Cに設定する場合コメントの解除
//  Wire.setPins(PIN_SDA, PIN_SCL);

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 5);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(20, 25);
  display.print(F("BananaPI"));
  display.setCursor(35, 45);
  display.print(F("PicoW"));

  display.display();                    //バッファ転送(表示)
}

void loop()
{
}

結果

I2C0を使ったコピーモニタ<非推奨>

I2C0ライン上に同じI2Cアドレスを持ったモジュールを配線することで、コピーモニタになります。
※I2Cではマスタからスレーブにデータを送信するときに、スレーブからACK/NACKを受け取ります。
同じアドレスが重複するとどちらの返答かわからなくて不具合の原因となるため、推奨できません

配線

RP2040 picoワイヤ色SSD1306(0x3c)SSD1306(0x3c)
3.3VVCCVCC
GNDGNDGND
GP0SDASDA
GP1SCLSCL
()はI2Cアドレス

スケッチ

I2Cによる表示と同じスケッチを使用します。

結果

I2C0を使ったデュアルモニタ

同じI2C0 ライン上には異なるI2Cアドレスのモジュールを配線します。
スケッチにはそれぞれのアドレスに対して個別の表示ができます。

配線

RP2040 picoワイヤ色SSD1306(0x3c)SSD1306(0x3d)
3.3VVCCVCC
GNDGNDGND
GP0SDASDA
GP1SCLSCL
()はI2Cアドレス

スケッチ

//Programing by たまねぎ
//【スケッチの説明】
//RP2040 CPU搭載基板で使用できます。
//I2Cアドレスの違うOLED画面を2つ使用し、個別に表示します。
//それぞれのOLED画面に "TAMANEGI"
//使用しているI2CラインとI2Cアドレスを表示させます。
//
//【準備】
//・RP2040 pico側
//本スケッチでは SDA に GP0, SCL に GP1 を使用します。
//・SSD1306 OLED側
// I2Cアドレスは 0x3c と 0x0dを設定します。
//
//【バージョン情報】
// 2022/6/19 : 新規

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS_M1 0x3C          //OLED 1のI2Cアドレスは0x3C
#define SCREEN_ADDRESS_M2 0x3D          //OLED 2のI2Cアドレスは0x3d

//それぞれを個別制御するためにそれぞれのオブジェクトを用意します。
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


void setup() {
  
  Wire.setSDA(0);                       //I2C0で使用するGPは SDA = 0, SCL = 1
  Wire.setSCL(1);

  if(!display1.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS_M1)) {
    for(;;);
  }
  if(!display2.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS_M2)) {
    for(;;);
  }

  //ここは OLED1の表示処理
  display1.clearDisplay();

  display1.setTextSize(2);
  display1.setTextColor(SSD1306_WHITE);
  display1.setCursor(20, 10);
  display1.print(F("TAMANEGI"));
  display1.setCursor(10, 30);
  display1.print(F("I2C0 0x3c"));

  display1.display();

  //ここから OLED2の表示処理
  display2.clearDisplay();

  display2.setTextSize(2);
  display2.setTextColor(SSD1306_WHITE);
  display2.setCursor(20, 10);
  display2.print(F("TAMANEGI"));
  display2.setCursor(10, 30);
  display2.print(F("I2C0 0x3d"));

  display2.display();

}

void loop() {
}

結果

I2C1による表示

RP2040 pico にはI2CのラインがI2C0 と I2C1 の2本あります。
I2C1を使った表示について記載します。

配線

RP2040 picoワイヤ色SSD1306(0x3c)
3.3VVCC
GNDGND
GP2SDA
GP3SCL
()はI2Cアドレス

スケッチ

//Programing by たまねぎ
//【スケッチの説明】
//RP2040 CPU搭載基板で使用できます。
//OLED画面に "TAMANEGI BLOG"と表示させます。
//
//【準備】
//・RP2040 pico側
//本スケッチでは SDA に GP2, SCL に GP3 を使用します。
//・SSD1306 OLED側
////I2Cアドレスは 0x3c 
//
//【バージョン情報】
// 2022/6/19 : 新規

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);
                                        //表示制御にはAdafruit製 SSD1306を使用する。
                                        //初期化時には I2C1を使用する (Wire)
                                        
void setup() {
  
  Wire1.setSDA(2);                       //I2C1で使用するGPは SDA = 2, SCL = 3
  Wire1.setSCL(3);

  if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  display.clearDisplay();               //何か表示されている場合に備えて表示クリア

  display.setTextSize(2);               //フォントサイズは2(番目に小さい)
  display.setTextColor(SSD1306_WHITE);  //色指定はできないが必要
  display.setCursor(20, 10);            //テキストの表示開始位置
  display.print(F("TAMANEGI"));         //表示文字列
  display.setCursor(10, 30);
  display.print(F("I2C1 0x3c"));

  display.display();                    //バッファ転送(表示)
}

void loop() {
}

結果

I2Cを2ライン使ったデュアルモニタ

同じI2CアドレスのOLEDを、別ラインのI2Cに配線します。
同じI2Cアドレスであっても、別のラインのため干渉しないで個別の表示ができます。

配線

RP2040 picoワイヤ色SSD1306(0x3c)SSD1306(0x3c)
3.3VVCCVCC
GNDGNDGND
GP0SDA
GP1SCL
GP2SDA
GP3SCL
()はI2Cアドレス

スケッチ

//Programing by たまねぎ
//【スケッチの説明】
//RP2040 CPU搭載基板で使用できます。
//同じI2CアドレスのOLED画面を2つ使用し、個別に表示します。
//それぞれのOLED画面に "TAMANEGI"
//使用しているI2CラインとI2Cアドレスを表示させます。
//
//【準備】
//・RP2040 pico側
//本スケッチでは I2C0 には SDA に GP0, SCL に GP1 を使用します。
//I2C1 には SDA に GP2, SCL に GP3 を使用します。
//・SSD1306 OLED側
// I2Cアドレス2個ともに 0x3c。
//
//【バージョン情報】
// 2022/6/19 : 新規

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128                //解像度 128 x 64 で使用します。
#define SCREEN_HEIGHT 64                //SCREEN_HEIGHTは 32 に設定することができます。

#define OLED_RESET     -1               //使用しないので -1を設定する。
#define SCREEN_ADDRESS 0x3C             //I2Cアドレスは0x3C

//それぞれを個別制御するためにそれぞれのオブジェクトを用意します。
Adafruit_SSD1306 display1(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
Adafruit_SSD1306 display2(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire1, OLED_RESET);


void setup() {
  
  Wire.setSDA(0);                       //I2C0で使用するGPは SDA = 0, SCL = 1
  Wire.setSCL(1);

  Wire1.setSDA(2);                       //I2C1で使用するGPは SDA = 2, SCL = 3
  Wire1.setSCL(3);

  if(!display1.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }
  if(!display2.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    for(;;);
  }

  //ここは OLED1の表示処理
  display1.clearDisplay();

  display1.setTextSize(2);
  display1.setTextColor(SSD1306_WHITE);
  display1.setCursor(20, 10);
  display1.print(F("TAMANEGI"));
  display1.setCursor(10, 30);
  display1.print(F("I2C0 0x3c"));

  display1.display();

  //ここから OLED2の表示処理
  display2.clearDisplay();

  display2.setTextSize(2);
  display2.setTextColor(SSD1306_WHITE);
  display2.setCursor(20, 10);
  display2.print(F("TAMANEGI"));
  display2.setCursor(10, 30);
  display2.print(F("I2C1 0x3c"));

  display2.display();

}

void loop() {
}

結果

コメント

タイトルとURLをコピーしました