arduinoで有機ELディスプレイ(2)
SSD1306でHello,WorldとLチカ

どもです。

前回の投稿で、有機ELディスプレイの「SSD1306」の開発環境のセットアップと、そのサンプルプログラムの動作確認を行いました。
このサンプルプログラムを動かすと、文字や色々な図形の表示ができることが分かります。
そこで今回は、SSD1306への文字/文字列の表示を行ってみてた結果と、その中で気が付いたことについて書きます。

開発環境は、前回から変更ありません。
詳細を知りたい方は、前回の投稿を参照してください。

1. Hello,world

まず基本的な表示である、「Hello, world」を表示させます。
具体的なコードは、以下です。

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

//画面のサイズの設定
#define SCREEN_WIDTH    (128)
#define SCREEN_HEIGHT   (64)

//画面のサイズ(データシートから)
#define SCREEN_ADDRESS  (0x3C)

int loopCount = 0;

// ディスプレイ変数の宣言
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

void setup() {
	Serial.begin(115200);

	//Setup SSD1306
	if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
	Serial.println(F("SSD1306 can not allocate memory!"));
	return;
	}

	//Clear display.
	display.clearDisplay();

	display.setTextSize(1);
	display.setTextColor(WHITE);
	display.setCursor(0, 0);
	display.println("Hello, OLED SSD1306");
	display.print("Text Size = 1");
	display.display();

	delay(1000);
}

void loop() {
}

コードについて、簡単ですが解説します。

1.1. オブジェクトの生成

まず、SSD1306を制御するオブジェクトです。
これは、15行目の以下のコードで宣言しています。

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire);

SSD1306を使用する場合、コンストラクタで画面のサイズを指定します。
今夏のプログラムでは、画面のサイズに併せて幅128、高さ64で指定しています。

1.2. 使用開始

SSD1306の制御を開始する前に、Adafruit_SSD1306オブジェクトのbegin()を実行する必要があります。
この関数の呼び出し方は、基本的に定型です。
ただ、SSD1306への供給電圧によって、第1引数は変更する必要があります。
供給電圧が3.3vの場合には「SSD1306_SWITCHCAPVCC」を、それ以外の場合には「SSD1306_EXTERNALVCC」とする必要があります。
今回は3.3v電源供給なので、「SSD1306_SWITCHCAPVCC」を指定します。

1.3. 画面の消去

画面の表示を全てクリアするために、clearDisplay()メソッドを使用します。
このメソッドを実行することで、画面の表示を全てクリアできます。

1.4. フォントの設定

文字列の表示については、以下の項目が設定可能です。
設定可能な項目を、それを設定するためのSSD1306オブジェクトのメソッドの対応は、下表の通りです。

設定項目 メソッド 設定値
フォントのサイズ setTextSize 1または2
1→フォント小
2→フォント大
フォントの色 setTextColor BLACK(0)
WHITE(1)
INVERSE(2)
表示開始位置 setCursor 第1引数→横位置
第2引数→縦位置

ココで、「フォントのサイズ」と「表示開始位置」の関係について、少し書きます。
「フォントのサイズ」に「1」を指定した場合、1つの文字の高さは「8」になります。
ある文字の真下に、重なることなく別の文字を表示する場合、setCursor()の第2引数には「現在のカーソル位置」に「8」以上の値を加えた値を設定する必要があります。
同様に、1つの文字の幅は「6」になります。
ある文字の真横(ココでは右隣)に、重なることなく別の文字を表示する場合、setCursor()の第1引数には、「現在のカーソル位置」に「6」以上の値を加えた値を設定する必要があります。

1.5. 文字列の表示

文字列の表示は、「print」「println」のいずれかを使用します。
この関数は、ArduinoのSerial.print()/Serial.println()と同じです。
なので、ココではこれ以上は書きません。

1.6. 描画の実行

「print」「println」で指定した文字/文字列ですが、それだけでは画面に表示されません。
表示するためには、「display」メソッドを実行する必要があります。

1.7. 文字列の表示の際の注意点

setTextSize()メソッドで「1」を指定した場合、1文字の幅が「8」、高さが「6」になっていると書きました。
このことから、画面のサイズを128×64に設定した場合、画面1行に表示できる文字数は21文字、表示可能な行数が8行であることが算出できます。
ココで気になるのが、文字数が「22文字」以上の文字列を指定した場合の「print」「println」の動作です。
結論からいうと、

行末で折り返される

となります。
「println」では、この折り返した先に改行が付与されます。
そのため、目的の文字列を表示するために、期待する以上の行数を要してしまう場合があり、注意が必要です。
試しに、前述のコードのloop()メソッドに以下のコードを実装して動作させた結果を載せます。

void loop() {
	display.clearDisplay();

	display.setTextSize(1);
	display.setCursor(0, 0);
	display.println("Hello, OLED SSD1306");     //文字数:範囲内
	display.println("0123456789012345678901"); //文字数:範囲外
	display.print("Hello, OLED SSD1306");       //文字数:範囲内
	display.print("0123456789012345678901");   //文字数:範囲外
	display.display();
}



2. Lチカ

次に、「Lチカ」をしてみます。
…と言っても、ここでのLチカはLEDをチカチカさせることではありません。
画面上の「L」の表示を「大→小→大→…」と繰り返し表示することです。
実際のコードは、以下です。

//前半は、前述のコードと同じなので省略します。

//行/列のサイズ
#define   ROW_HEIGHT        (8)
#define   COL_WIDTH         (6)
#define   ROW2CURSOR(r)     ((r) * ROW_HEIGHT)
#define   COL2CURSOR(c)     ((c) * COL_WIDTH)

int loopCount = 0;

void loop() {
	display.clearDisplay();
  
	display.setTextSize(1);
	display.setCursor(COL2CURSOR(0), ROW2CURSOR(0));
	display.println("Hello, OLED SSD1306");
	display.setCursor(COL2CURSOR(10), ROW2CURSOR(4));
	display.setTextSize((loopCount % 2) + 1);
	display.println("L");
	display.display();
  
	delay(1000);
	loopCount++;
}

このコードをボードに書き込んで実行すると、画面の中央付近で「L」が「大→小→大→…」と繰り返し表示されます。
ココで注目するのは、setTextSize()の実行です。
1度の表示の中で、setTextSize()でのフォントを複数回指定できます。
そのため、表示する内容によっては、その文字/文字列のみを大き句表示する、ということが可能です。

3. 動画にしてみました

これまで書いてきた動作を確認する動画を、1つ作成してみました。
見てみてください。

3. まとめ

今回は、SSD1306に対して文字列を表示してみました。
基本的には、print()/println()メソッドのみで文字列の表示は十分だと思います。
しかし、setTextSize()メソッドやsetCursor()メソッドを使いこなすことができれば、より自由自在に文字列を表示できると思います。

ではっ!