arduinoで有機ELディスプレイ(3)
SSD1306に図形を描画

2022年7月3日

どもです。

今回は、以下の記事の続きです。
arduinoで有機ELディスプレイ(1) – SSD1306の環境構築~サンプルプログラム実行
arduinoで有機ELディスプレイ(2) – SSD1306でHello,WorldとLチカ

これまでは、文字列の表示について書いてきました。
今回は次のステップ(?)として、「図形の描画」を行ってみます。
描画する図形は、円と四角と三角です。

1. 円の描画

SSD1306に円を描画する際には、以下の関数のいずれかを使用します。

  • void drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
  • void fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);

引数の内容と描画される円の対応は、下図の通りです。



この2つの関数の違いは、「塗りつぶし」です。
drawCircle()で描画される円は、中が塗りつぶされていません(線だけが描画されます)。
これに対してfillCircle()で描画される円は、中が塗りつぶされています。
これらの関数を使用する具体的なコードは、以下になります。

void loop() {
	int color = loopCount % 3;

	display.clearDisplay();
	display.setTextSize(1);
	display.setCursor(COL2CURSOR(0), ROW2CURSOR(0));
	if (0 == color) {
		display.println("BLACK");
	} else if (1 == color) {
		display.println("WHITE");
	} else {
		display.println("INVERSE");
	}

	display.drawCircle(SCREEN_WIDTH / 2,  (SCREEN_HEIGHT / 2), (SCREEN_HEIGHT / 16) * 5, color);
	display.fillCircle(SCREEN_WIDTH / 2,  (SCREEN_HEIGHT / 2), (SCREEN_HEIGHT / 16) * 3, color);
	display.display();

	delay(1000);
	loopCount++;
}

このコードを書き込んで実行すると、SSD1306の中心に同心円が描画されます。
内側の円が、塗りつぶされた円になります。

2. 四角形の描画

次に、四角形の描画です。
四角形を描画する際には、以下の関数を使用します。

  • void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  • void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
  • void drawRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);
  • void fillRoundRect(int16_t x0, int16_t y0, int16_t w, int16_t h, int16_t radius, uint16_t color);

引数の内容と描画される円の対応は、下図の通りです。



これらの4つの関数の名前は、描画する四角形と以下のように対応しています。

  • drawXxx→塗りつぶされていない四角形を描画する
  • fillXxx→塗りつぶされている四角形を描画する
  • xxxRect→角に丸みがない四角形を描画する
  • xxxRoundRect→角に丸みがある四角形を描画する

これらの関数を使用する具体的なコードは、以下になります。

void loop() {
	int color = loopCount % 3;

	display.clearDisplay();
	display.setTextSize(1);
	display.setCursor(COL2CURSOR(0), ROW2CURSOR(0));
	if (0 == color) {
		display.println("BLACK");
	} else if (1 == color) {
		display.println("WHITE");
	} else {
		display.println("INVERSE");
	}
	display.drawRect((SCREEN_WIDTH / 8) * 1,      (SCREEN_HEIGHT / 8) * 2,  (SCREEN_WIDTH / 8) * 2, (SCREEN_HEIGHT / 8) * 2,  color);  //2
	display.fillRect((SCREEN_WIDTH / 8) * 5,      (SCREEN_HEIGHT / 8) * 2,  (SCREEN_WIDTH / 8) * 2, (SCREEN_HEIGHT / 8) * 2,  color);  //2
	display.drawRoundRect((SCREEN_WIDTH / 8) * 1, (SCREEN_HEIGHT / 8) * 5,  (SCREEN_WIDTH / 8) * 2, (SCREEN_HEIGHT / 8) * 2,  4,  color);  //1
	display.fillRoundRect((SCREEN_WIDTH / 8) * 5, (SCREEN_HEIGHT / 8) * 5,  (SCREEN_WIDTH / 8) * 2, (SCREEN_HEIGHT / 8) * 2,  4,  color);  //2
	display.display();

	delay(1000);
	loopCount++;
}

このコードを書き込んで実行すると、SSD1306に四角形が4つ表示されます

3. 三角形の描画

次に、三角形です。
三角形を描画する際には、以下の関数を使用します。

  • void drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
  • void fillTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);

引数の関係と描画される三角形の関係は、以下の通りです。



三角形を描画する具体的なコードは、以下になります。

void loop() {
	int color = loopCount % 3;

	display.clearDisplay();
	display.setTextSize(1);
	display.setCursor(COL2CURSOR(0), ROW2CURSOR(0));
	if (0 == color) {
		display.println("BLACK");
	} else if (1 == color) {
		display.println("WHITE");
	} else {
		display.println("INVERSE");
	}
	Serial.println(color);

	display.drawTriangle(
		(SCREEN_WIDTH / 8) * 1,  (SCREEN_HEIGHT / 8) * 2, 
		(SCREEN_WIDTH / 8) * 7,  (SCREEN_HEIGHT / 8) * 4, 
		(SCREEN_WIDTH / 8) * 1,  (SCREEN_HEIGHT / 8) * 6, 
		color);
	display.fillTriangle(
		(SCREEN_WIDTH / 8) * 2,  (SCREEN_HEIGHT / 8) * 3, 
		(SCREEN_WIDTH / 8) * 6,  (SCREEN_HEIGHT / 8) * 4, 
		(SCREEN_WIDTH / 8) * 2,  (SCREEN_HEIGHT / 8) * 5, 
		color);
		display.display();

	delay(1000);
	loopCount++;
}

前出の三角形の図、および上述のコードでは、時計回りに(x0, y0)→(x1, y1)→(x02, y2)と描画/指定していますが、実際には順番は関係ありません。
描画する三角形の3つの頂点の座標が指定できていれば、問題ありません。

4. 色の指定

図形を描画する際には、輪郭/塗りつぶしの色を指定します。
指定可能な色は、「黒」/「白」/「反転」の3つです。
「黒」/「白」を指定した場合は明確なので、説明は省略します。
「反転」を指定すると、文字通り白<->黒が反転されます。
これは、例えば以下のコードを実行することで確認できます。

void loop() {
	display.clearDisplay();

	int radius = 0;
	for (radius = 8; radius < 64; radius += 4) {
		display.fillCircle(SCREEN_WIDTH / 2,  (SCREEN_HEIGHT / 2), radius, INVERSE);
		display.display();
		delay(2000);
	}
}

実行指せてみると、画面中央から水面の波紋のように同心円が広がっていく図が描画されます。
即ち、(n + 1)回目の円を描画すると、n回目の円を描画した際に白であった箇所が黒に、黒であった箇所が白に描画されます。

5. まとめ

今回は、SSD1306に対して、円/四角形/三角形を描画してみました。
前回の文字列の表示と図形の描画を同時に行えば、更に色々な情報を画面上に情報を表示できるようになると思います。

ではっ!

ex. 動画にしてみました

円/四角/三角を動画で書いてみました。
見てみてください。