Arduinoの基礎 - OLED
ナビゲーションに移動
検索に移動
概要
ArduinoでOLEDディスプレイを制御するには、まず、適切な通信方式を選択することから始める。
- I2C通信
- 最も一般的な通信方式である。
- I2C通信では、配線がVCC、GND、SDA (データ)、SCL (クロック) の4本だけで済むため、配線ミスが少なく扱いやすいというメリットがある。
- ArduinoでI2C通信を行う場合、SDAはA4ピン、SCLはA5ピンに接続する。
OLEDディスプレイの寸法は、主に128x64ピクセルと128x32ピクセルの2種類が一般的である。
- 128x64ピクセル
- 表示できる情報量が多く、グラフィカルな表現も可能であるが、その分消費電力も大きい。
- 128x32ピクセル
- 省電力であり、シンプルな文字情報の表示に適している。
表示色については、白色表示が最も一般的であり、コストパフォーマンスに優れている。
青色表示は視認性が高く、暗所での使用に適している。
ツートンカラーは2色での表示が可能で、より豊かな表現ができ、情報の区別がつきやすいという特徴があるが、価格は比較的高めである。
SPI通信は高速な通信が可能であり、アニメーション等の動的な表示に適しているが、配線数が6~7本に増えるため、実装の複雑さは増す。
OLED 128x64ディスプレイ (I2C)
Adafruit_SSD1306ライブラリを使用する。
このライブラリは機能が豊富であり、テキスト表示やグラフィックス描画が簡単に実装することが可能である。
また、U8g2ライブラリも、より高度な表現が可能である。
OLED 128x64ディスプレイの接続
テキストの表示
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
// Adafruit SSD1306ディスプレイオブジェクトをI2C通信用に初期化
Adafruit_SSD1306 disp(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
void setup()
{
// 128x64解像度の特定のI2Cアドレス (0x3C) でOLEDディスプレイを開始
if (!disp.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F(「SSD1306 allocation failed」)); // 初期化に失敗した場合はエラーメッセージを表示
while (true); // それ以降の実行を停止するために無限ループ
}
delay(2000); // 初期化するまで待機
disp.clearDisplay(); // ディスプレイをクリア
disp.setTextSize(1); // テキストサイズの設定
disp.setTextColor(WHITE); // テキストカラー
disp.setCursor(0, 10); // 表示位置
disp.println("Hello, World!"); // データを送信
disp.display(); // ディスプレイに表示
}
テキストを垂直方向と水平方向の中央に配置
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
Adafruit_SSD1306 disp(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // I2Cに接続されたSSD1306ディスプレイオブジェクトの作成
void setup()
{
Serial.begin(9600);
// 128x64解像度の特定のI2Cアドレス (0x3C) でOLEDディスプレイを開始
if (!disp.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F(「SSD1306 allocation failed」)); // 初期化に失敗した場合はエラーメッセージを表示
while (true); // それ以降の実行を停止するために無限ループ
}
delay(2000); // 初期化するまで待機
disp.clearDisplay(); // ディスプレイをクリア
disp.setTextSize(2); // テキストサイズの設定
disp.setTextColor(WHITE); // テキストカラー
disp.setCursor(0, 10); // 表示位置
}
void loop()
{
String text = "DIYables"; // テキストデータ
oledDisplayCenter(text); // テキストデータを画面中央に表示
delay(2000); // データが表示されるまで待機
// ディスプレイ番号
int number = 21;
String str = String(number);
oledDisplayCenter(str); // テキストデータを画面中央に表示
delay(2000); // データが表示されるまで待機
}
void oledDisplayCenter(String text)
{
int16_t x1;
int16_t y1;
uint16_t width;
uint16_t height;
// 表示するテキストの描画範囲 (バウンディングボックス) を計算
disp.getTextBounds(text, 0, 0, &x1, &y1, &width, &height);
disp.clearDisplay(); // ディスプレイ内容を消去
// 水平および垂直センター表示
disp.setCursor((SCREEN_WIDTH - width) / 2, (SCREEN_HEIGHT - height) / 2);
disp.println(text); // テキストデータの送信
disp.display(); // テキストデータの表示
}
Adafruit_SSD1306クラスのgetTextBoundsメソッドを使用することにより、テキストのレイアウトを正確に制御することが可能になる。
getTextBoundsメソッドは、以下に示すような用途で使用される。
- テキストを画面の中央に配置したい場合の位置計算
- テキストが画面内に収まるかどうかの事前確認
- テキスト周辺に枠を描画する際の寸法計算
- 第1引数
- 計測する表示テキスト
- 第2引数 (横) / 第3引数 (縦)
- テキストを描画する際の開始位置
- 通常は0, 0を指定する。
- 第4引数 (横) / 第5引数 (縦)
- テキストの左上座標が格納されるポインタ変数
- 第6引数 (横) / 第7引数 (縦)
- 第6引数 (横) は、テキストの幅 (ピクセル数) が格納されるポインタ変数
- 第7引数 (縦) は、テキストの高さ (ピクセル数) が格納されるポインタ変数
int16_t x1,
y1;
uint16_t width,
height;
display.setTextSize(2);
display.getTextBounds("Hello", 0, 0, &x1, &y1, &width, &height);
// テキストを画面中央に配置する場合の座標計算
int16_t x = (SCREEN_WIDTH - width) / 2;
int16_t y = (SCREEN_HEIGHT - height) / 2;
display.setCursor(x, y);
display.print("Hello");
描画の作成
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 disp(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1); // I2Cに接続されたSSD1306ディスプレイオブジェクトの作成
void setup()
{
Serial.begin(9600);
// 128x64解像度の特定のI2Cアドレス (0x3C) でOLEDディスプレイを開始
if (!disp.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F(「SSD1306 allocation failed」)); // 初期化に失敗した場合はエラーメッセージを表示
while (true); // それ以降の実行を停止するために無限ループ
}
delay(2000); // 初期化するまで待機
disp.setCursor(0, 0);
}
void loop()
{
// 四角形を描画
disp.clearDisplay();
disp.drawRect(0, 15, 60, 40, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 四角形を描画 (塗りつぶし)
disp.clearDisplay();
disp.fillRect(0, 15, 60, 40, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 楕円を描画
disp.clearDisplay();
disp.drawRoundRect(0, 15, 60, 40, 8, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 楕円を描画 (塗りつぶし)
disp.clearDisplay();
disp.fillRoundRect(0, 15, 60, 40, 8, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 円を描画
disp.clearDisplay();
disp.drawCircle(20, 35, 20, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 円を描画 (塗りつぶし)
disp.clearDisplay();
disp.fillCircle(20, 35, 20, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 三角形を描画
disp.clearDisplay();
disp.drawTriangle(30, 15, 0, 60, 60, 60, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
// 三角形を描画 (塗りつぶし)
disp.clearDisplay();
disp.fillTriangle(30, 15, 0, 60, 60, 60, WHITE);
disp.display(); // データの表示
delay(2000); // データが表示されるまで待機
}
画像の表示