電子ペーパー
ESP32

概要

Waveshare社の電子ペーパーを、ESP-WROOM-32から使う実験です。Waveshare社が配布しているデモプログラムを動作させてみました。

Arduino core for the ESP32のインストールのページはこちら

目的

Waveshare社の電子ペーパーを、ESP-WROOM-32から使ってみます。まずは、デモプログラムを動かした後、ライブラリの解析を行いました。

Waveshare社は多くの電子ペーパーを販売しています。今回は、400ドットx300ドット、3色(白、黒、黄)の電子ペーパーモジュールを利用しました。この電子ペーパーモジュールは、ディスプレーのみで基板がついていないものもあります。こちらのほうが値段も安いのですが、扱いが簡単そうな基板に実装されたタイプを利用しました。他にも、白、黒、赤の3色のものもあります。

下の写真は、毎日新聞RSSデータを取得して、FONTXを用いて表示したところです。電源を切っても表示されたままです。

デバイスの仕様

以下に、デバイスの仕様を示します。

項目 内容 その他
電源電圧 3.3V
インターフェイス SPI 3-wire/4-wire
基板サイズ 103.0mm x 78.5mm
ディスプレイサイズ 84.8mm x 63.6mm
ドットピッチ 0.212mm x 0.212mm
解像度 400 x 300
表示色 黄色、黒、白
フルリフレッシュ時間 15秒 結構時間がかかります。
リフレッシュ時消費電力 26.4mW
スタンバイ時消費電力 < 0.017mW

リフレッシュ時間が15秒と長いので、リアルタイムの表示には向きません。技術資料のページには、以下の記載があります(最近見てみたら、下記の記述はありませんでした…)。

Note: The refresh rate of this module is slow, and it will flicker for several times during refreshing (about 15s). Please be patient.

直接ディスプレイにデータを表示するのではなく、いったん、デバイス内蔵のSRAMにデータを書き込んだ後、SRAMのデータをディスプレイにフラッシュする構造のようです。また、SRAMは黒、黄色の2つが分かれて存在し、黒・黄色の順序でSRAMの内容がフラッシュされるようです。同じ座標に黒と黄色の両方のデータがある場合は、黄色が優先(上書き)されました。

ライブラリのインストール

製造元のWaveshre社が様々なプラットフォームに対応したライブラリを配布しています。ダウンロードして、伸長・展開すると、4.2inch-e-paper-module-b-code というディレクトリができあがります。その下には、arduinoとraspberrypi、stm32というディレクトリがあります。さらに、arduinoの下には、epd4in2b-demoというディレクトリと、librariesというディレクトリがあります。以下のような感じです。

  • 4.2inch-e-paper-module-b-code
    • arduino
      • epd4in2b-demo
      • libraries
    • raspberrypi
    • stm32

上記の、libraries配下のファイルを、Arduinoのライブラリとして登録します。私は、以下のディレクトリを作成して、libraries以下のファイルをコピーしました。USERNAMEは自分の環境に合わせて修正してください。Windowsでない場合は、適切に読み替えてください。epaperというディレクトリ名である必要はありません。

C:\Users\USERNAME\Documents\arduino\libraries\epaper

ライブラリの変更

前述のライブラリをESP-WROOM-32から利用するには、いくつかの変更が必要でした。

インクルードファイルの変更

Arduino Unoから利用する場合は、上記のままで問題はありませんが、ESP-WROOM-32から利用する際は、PROGMEMを利用しているため、少し修正が必要です。以下のファイルについて、#include <avr/pgmspace.h>と記載されているところを、#include <pgmspace.h>に変更します。

  • epdpaint.cpp
  • font12.c
  • font16.c
  • font20.c
  • font24.c
  • font8.c

単純にインクルードするファイル名を変更してしまうと、Arduino Unoから利用する際に問題が出てしまうので、以下のように修正しました。ただし、AVRとESP8266とについては、試していないので、うまく動作しないかもしれません。また、Arduino Unoからの利用もしていないので、間違っているかもしれません。

1
2
3
4
5
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(ESP8266) || defined(ESP32)
#include <pgmspace.h>
#endif

ピン番号の変更

電子ペーパーモジュールに接続するピン番号が、epdif.hというファイルにハードコーディングされています。ESP-WROOM-32では利用できないピンがあるため、以下のように変更しました。変更したピン番号に特にこだわりはありません。利用できるピンであれば問題はありません。ESP8266については、よくわからないので、対応していません。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// Pin definition
#if defined(__AVR__)
#define RST_PIN         8
#define DC_PIN          9
#define CS_PIN          10
#define BUSY_PIN        7
#elif defined(ESP32)
#define RST_PIN         33  // 8
#define DC_PIN          25  // 9
#define CS_PIN          26  // 10
#define BUSY_PIN        27  // 7
#endif

ESP-WROOM-32との接続

電子ペーパーモジュールとESP-WROOM-32とは、以下のように接続しました。上記の変更と対応しています。電源関連のピンと備考にSPIと記載したピンを除いては、特に制約はありません。SPI関連のピンについても他のピンを利用可能ですが、意味はあまりないと思います。

ESP32のピン 意味 電子ペーパーモジュールのピン 備考
3.3V 電源 3.3V
GND GND GND
23 MOSI DIN SPI
18 SCK CLK SPI
26 CS CS
25 DC DC
33 RST RST
27 BUSY BUSY

デモプログラムの実行

epd4in2b-demo を実行します。こちらの、imagedata.cppでも、pgmspace.hをインクルードしている箇所があるので、上述のライブラリの変更で記載した変更を行います。

実行した結果は、左の写真です。デモプログラム中でコメントアウトされている、epd.DisplayFrame(IMAGE_BLACK, IMAGE_RED); を実行した結果は、中央の写真です。右の写真は、私が作成した簡単なプログラムの実行結果です。直線の描画が少し怪しい気もしますが、詳細までは確認していません。

ライブラリの解析

ライブラリは、大きく、2つのモジュールから構成されています。一つは、電子ペーパーモジュールを制御するためのモジュール(Epdクラス)です。このクラスは、イメージデータを、電子ペーパーモジュール内蔵のSRAMに書き込む機能と、SRAMを電子ペーパーにフラッシュする機能を提供します。

もう一つは、電子ペーパーに表示するデータを操作するモジュール(Paintクラス)です。このクラスは、バッファに、直線や円、文字を描く機能を提供します。

イメージとしては、以下の通りです。少ないメモリでも動作できるように、Paintクラスが操作するバッファは小さくても動作します。

各クラスでは、以下のメソッドが提供されています。

Epdクラス

メソッド名 説明
Epd() コンストラクタ。
~Epd() デストラクタ。
Init() 初期化する。
Reset() デバイスをリセットする。
SetPartialWindow() 電子ペーパー内蔵SRAMの指定した領域のデータを書き換える。
SetPartialWindowBlack() 電子ペーパー内蔵SRAMの指定した領域のデータ(黒色用)を書き換える。
SetPartialWindowRed() 電子ペーパー内蔵SRAMの指定した領域のデータ(赤色用/黄色用)を書き換える。
DisplayFrame() 指定したデータを電子ペーパーに表示する。
ClearFrame() 電子ペーパー内蔵のSRAMのデータをクリアする。
Sleep() ディープスリープモードに移行する。

Epd()

説明

コンストラクタ。

書式

Epd::Epd()

引数

なし。

戻り値

なし。

~Epd()

説明

デストラクタ。

書式

Epd::~Epd()

引数

なし

戻り値

なし

Init()

説明

初期化する。

書式

int Epd::Init(void)

引数

なし

戻り値

成功した場合は0、失敗した場合は-1。

Reset()

説明

デバイスをリセットする。

書式

void Epd::Reset(void)

引数

なし

戻り値

なし

SetPartialWindow()

説明

電子ペーパー内蔵SRAMの指定した領域のデータを書き換える。ただし、SRAM上のデータを書き換えるだけで、表示は変わらない。表示に反映させるためには、DisplayFrame()を利用する。

書式

void Epd::SetPartialWindow(const unsigned char* buffer_black, const unsigned char* buffer_red, int x, int y, int w, int l)

引数

const unsigned char* buffer_black 黒色用バッファ。

const unsigned char* buffer_red 赤色(黄色)用バッファ。

int x 書き換え対象の領域のX座標の開始位置。8の倍数。

int y 書き換え対象の領域のY座標の開始位置。

int w 書き換え対象の領域のX座標の幅。

int l 書き換え対象の領域のY座標の幅。

戻り値

なし。

SetPartialWindowBlack()

説明

電子ペーパー内蔵SRAMの指定した領域のデータ(黒色用)を書き換える。ただし、SRAM上のデータを書き換えるだけで、表示は変わらない。表示に反映させるためには、DisplayFrame()を利用する。

書式

void Epd::SetPartialWindowBlack(const unsigned char* buffer_black, int x, int y, int w, int l)

引数

const unsigned char* buffer_black 黒色用バッファ。

int x 書き換え対象の領域のX座標の開始位置。8の倍数。

int y 書き換え対象の領域のY座標の開始位置。

int w 書き換え対象の領域のX座標の幅。

int l 書き換え対象の領域のY座標の幅。

戻り値

なし。

SetPartialWindowRed()

説明

電子ペーパー内蔵SRAMの指定した領域のデータ(赤色用/黄色用)を書き換える。ただし、SRAM上のデータを書き換えるだけで、表示は変わらない。表示に反映させるためには、DisplayFrame()を利用する。

書式

void Epd::SetPartialWindowRed(const unsigned char* buffer_red, int x, int y, int w, int l)

引数

const unsigned char* buffer_black 赤色(黄色)用バッファ。

int x 書き換え対象の領域のX座標の開始位置。8の倍数。

int y 書き換え対象の領域のY座標の開始位置。

int w 書き換え対象の領域のX座標の幅。

int l 書き換え対象の領域のY座標の幅。

戻り値

なし。

DisplayFrame()

説明

指定したデータを電子ペーパーに表示する。

引数を省略した場合は、電子ペーパー内蔵のSRAM上のデータを電子ペーパーに表示する。

書式

void DisplayFrame(const unsigned char* frame_black, const unsigned char* frame_red)

引数

frame_black 黒色用データ。

frame_red 赤色(黄色)用データ。

戻り値

なし。

ClearFrame()

説明

電子ペーパー内蔵のSRAMのデータをクリアする。ただし、SRAM上のデータを書き換えるだけで、表示は変わらない。表示に反映させるためには、DisplayFrame()を利用する。

書式

void Epd::ClearFrame(void)

引数

なし。

戻り値

なし。

Sleep()

説明

ディープスリープモードに移行する。ディープスリープモードから復帰するには、Reset()を行い、その後、Init()する。

書式

void Epd::Sleep()

引数

なし。

戻り値

なし。

Paintクラス

メソッド名 説明
Paint() コンストラクタ。
~Paint() デストラクタ。
Clear() バッファをクリアする。
GetImage() イメージ用バッファの先頭へのポインタを返す。
GetWidth() バッファの幅を取得する。
SetWidth() バッファの幅を設定する。
GetHeight() バッファの高さを取得する。
SetHeight() バッファの高さを設定する。
GetRotate() ディスプレイの回転を取得する。
SetRotate() バッファの回転を設定する。
DrawAbsolutePixel() 指定した絶対座標に点を描く。
DrawPixel() 指定した座標に点を描く。
DrawCharAt() 指定した座標に文字を書く。
DrawStringAt() 指定した座標に文字列を書く。
DrawLine() 直線を描く。
DrawHorizontalLine() 水平の直線を描く。
DrawVerticalLine() 垂直の直線を描く。
DrawRectangle() 長方形を描く。
DrawFilledRectangle() 塗りつぶした長方形を描く。
DrawCircle() 円を描く。
DrawFilledCircle() 塗りつぶした円を描く。

Paint()

説明

コンストラクタ。

書式

Paint::Paint(unsigned char* image, int width, int height)

引数

unsigned char* image イメージ用バッファ。このコンストラクタではバッファは確保しないので、確保したバッファを渡す必要がある。

int width バッファの幅。8の倍数。

int height バッファの高さ。

戻り値

なし。

~Paint()

説明

デストラクタ。

書式

Paint::~Paint()

引数

なし。

戻り値

なし。

Clear()

説明

バッファをクリアする。coloredが0のときは、全ての値が0になり、coloredが0以外のときは、全ての値が1になる。

書式

void Paint::Clear(int colored)

引数

int colored 0のときは、すべての値が0になり、0以外のときは、すべての値が1になる。

戻り値

なし。

GetImage()

説明

イメージ用バッファの先頭へのポインタを返す。

書式

unsigned char* Paint::GetImage(void)

引数

なし。

戻り値

イメージ用バッファの先頭へのポインタ。

GetWidth()

説明

バッファの幅を取得する。

書式

int Paint::GetWidth(void)

引数

なし。

戻り値

バッファの幅。

SetWidth()

説明

バッファの幅を設定する。

書式

void Paint::SetWidth(int width)

引数

int width バッファの幅。8の倍数。

戻り値

なし。

GetHeight()

説明

バッファの高さを取得する。

書式

int Paint::GetHeight(void)

引数

なし。

戻り値

バッファの高さ。

SetHeight()

説明

バッファの高さを設定する。

書式

void Paint::SetHeight(int height)

引数

int height バッファの高さ。

戻り値

なし。

GetRotate()

説明

ディスプレイの回転を取得する。回転できるのは、0度、90度、180度、270度。通常(=0度)左上が原点だが、例えば90度回転すると、右上が原点となる。あくまで、このオブジェクトの高さと幅を基準に回転操作が行われるため、注意が必要。

書式

int Paint::GetRotate(void)

引数

なし。

戻り値

回転角度。ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270のいずれか。

SetRotate()

説明

バッファの回転を設定する。

書式

void Paint::SetRotate(int rotate)

引数

int rotate 回転角度。ROTATE_0、ROTATE_90、ROTATE_180、ROTATE_270のいずれか。

戻り値

なし。

DrawAbsolutePixel()

説明

指定した絶対座標に点を描く。座標の回転には影響されない。

書式

void Paint::DrawAbsolutePixel(int x, int y, int colored)

引数

int x バッファのX座標。

int y バッファのY座標。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawPixel()

説明

指定した座標に点を描く。座標の回転に影響される。

書式

void Paint::DrawPixel(int x, int y, int colored)

引数

int x バッファのX座標。

int y バッファのY座標。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawCharAt()

説明

指定した座標に文字を書く。座標の回転に影響される。

書式

void Paint::DrawCharAt(int x, int y, char ascii_char, sFONT* font, int colored)

引数

int x バッファのX座標。

int y バッファのY座標。

char ascii_char 文字。

sFont *font デフォルトでは、Font8、Font12、Font16、Font20、Font24を指定可能。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawStringAt()

説明

指定した座標に文字列を書く。座標の回転に影響される。

書式

void Paint::DrawStringAt(int x, int y, const char* text, sFONT* font, int colored)

引数

int x バッファのX座標。

int y バッファのY座標。

char char *text 文字列。

sFont *font デフォルトでは、Font8、Font12、Font16、Font20、Font24を指定可能。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawLine()

説明

直線を描く。

書式

void Paint::DrawLine(int x0, int y0, int x1, int y1, int colored)

引数

int x0 直線の開始座標。

int y0 直線の開始座標。

int x1 直線の終了座標。

int y1 直線の終了座標。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawHorizontalLine()

説明

水平の直線を描く。

書式

void Paint::DrawHorizontalLine(int x, int y, int line_width, int colored)

引数

int x 直線の開始座標。

int y 直線の開始座標。

int line_width 直線の長さ。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawVerticalLine()

説明

垂直の直線を描く。

書式

void Paint::DrawVerticalLine(int x, int y, int line_height, int colored)

引数

int x 直線の開始座標。

int y 直線の開始座標。

int line_height 直線の高さ。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawRectangle()

説明

長方形を描く。

書式

void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored)

引数

int x0 長方形の開始座標。

int y0 長方形の開始座標。

int x1 長方形の終了座標。

int y1 長方形の終了座標。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawFilledRectangle()

説明

塗りつぶした長方形を描く。

書式

void Paint::DrawRectangle(int x0, int y0, int x1, int y1, int colored)

引数

int x0 長方形の開始座標。

int y0 長方形の開始座標。

int x1 長方形の終了座標。

int y1 長方形の終了座標。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawCircle()

説明

円を描く。

書式

void Paint::DrawCircle(int x, int y, int radius, int colored)

引数

int x 円の中心座標。

int y 円の中心座標。

int radius 円の半径。

int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

DrawFilledCircle()

説明

塗りつぶした円を描く。

書式

void Paint::DrawCircle(int x, int y, int radius, int colored)

引数

int x 円の中心座標。

int y 円の中心座標。

int radius 円の半径。 int colored 0以外のとき、座標に対するバッファの値を1にする。0のとき、0にする。

戻り値

なし。

バージョン

Hardware:ESP-WROOM-32
Software:Arduino 1.8.4/Arduino core for the ESP32

最終更新日

November 1, 2022

inserted by FC2 system