RaspberryPiで有機ELディスプレイ(2)
SSD1306でドットを描画する

どもです。

前回のエントリで、RaspberryPiで有機ELディスプレイSSD1306を動かして見ました。
このエントリの中でSSD1306に表示した内容は、0~255までの値をバッファに設定してみる、という内容でした。
この時の表示の処理から、バッファに設定した値と表示される図形(?)の関係について記載しています。

今回のエントリでは、これを少し発展させて、ディスプレイ上にドット(点)を描画してみます。

1. 開発環境

今回のエントリは、以下の環境で開発を行っています。

開発/実行環境
項目 内容
OS Windows10 Pro(1909)
CPU i7-8700
メモリ 16GB
IDE Eclipse
Ver.2019-06(4.12.0)
Build id 20190614-1200

また、RaspebrryPi/pigpioの環境は以下の通りです。

RaspberryPi
項目 内容
HW RaspberryPi3 model B
OS Raspbian GNU/Linux
buster
ライブラリ pigpio Version 71
(gpioVersion()関数で確認)

SSD1306は、以下のように設定します。


2. ドットを描画する

前回のエントリでも書いていますが、ドットを描画するためには、データバッファ中の対応するビットをONすることで設定できます。
そのためドットの描画は、以下の処理が必要になります。

  1. 描画対象のデータバッファ(バイト)のインデックスを算出する。
  2. 描画対象のデータバッファ中の何ビット目かを算出する。
  3. 描画対象のデータバッファ中の対象ビットをONにする。

2.1. コード

それでは、具体的なコードを見てみます。
ココでは、画面上の座標(x, y)にドットを描画する場合の処理です。

//描画対象のデータバッファ(バイト)のインデックスを算出
uint8_t		yIndex = y / 8;
uint8_t*	target = displayBuffer[x + yIndex * DISPLAY_WSIZE];

//描画対象のデータバッファ中の何ビット目かを算出
uint8_t		yOffset = yIndex % 8;

//描画対象のデータバッファ中の対象ビットをON
*target |= 1 << yOffset

2.2. コードの解説(1)

それでは、コードを解説します。
まず、「描画対象のデータバッファ(バイト)のインデックスを算出」部分です。

//描画対象のデータバッファ(バイト)のインデックスを算出
uint8_t		yIndex = y / 8;
uint8_t*	target = displayBuffer[x + yIndex * DISPLAY_WSIZE];

SSD1306では、1024バイトのデータを128バイトを1ページ、計8ページのデータに分割して管理します。
そのため、入力されたx、y座標から「何ページ目の何バイト目」という情報を算出する必要があります。
x座標については、入力された値が「何バイト目か」に対応します。
y座標については、入力された値を8で割ることにより、「何ページ目か(yIndex)」を算出できます。
この値に対して、

「x + yIndex * 128」(DISPLAY_WSIZE)

を計算することで、バッファ上のインデックスが算出されます。

2.2. コードの解説(2)

次に、「何ビット目か」の算出です。
これは簡単で、ページの各データ内の「下から何ビット目か」の値が対応します。
そのため、「y座標を8で割った余り」が対応します。

2.3. コードの解説(3)

最後に、特定のビットをONする処理です。
これは実に簡単です。
事前に計算しておいた「何ビット目か」の値だけ、「1」を左ビットシフトした値と、「描画対象のデータバッファ(バイト)」の論理和を取ります。
これにより、目的のビットをONできます。

2.4. 図にしてみた

これまでの解説を簡単な図にすると、以下のようになります。


3. ドットを実際に描画してみた

前述のコードを用いて実際にドットを描画してみました。
今回は、xとyの値を0から63まで変化させみました。
結果として、「y = x」の直線が描画されます。


4. まとめ

今回は、RaspberryPiに接続したSSD1306に対してドットを描画しました。
ディスプレイ上の任意の位置に、ドットを描画できるようになりました。
さらにこの機能を使用して、直線も描画してみました。
これにより、ドットが描画できれば、SSD1306上に様々な情報を描画できることが分かります。

今後は、直線や円、四角などの図を描画していきます。

ではっ!