電子ペーパーに天気とスケジュールを表示

 

 

今回は、E-paperの紹介です。

皆さんは、E-Paperはご存じだと思いますが、よくスーパーやコンビニなどで使用されていますね。

では、実際自宅でどのような使い方があるか?

私は、Googleカレンダーと天気予報(天気と気温)を表示して毎日確認できたらいいなと思いこのツールを作成しました。

 

E-paperに気象庁の天気情報を利用して今日、明日、明後日の天気と気温を表示し、Googleカレンダーで今日の予定を表示する様にツールを作成しました。
左側には、今月のカレンダーを表示、その下に天気予報、右側にはGoogleカレンダーの今日の予定を表示します。
 

 

 

 

 

【E-paperの仕組み】
では、E-paperの仕組みについて少し紹介します。

左側にあるマイクロカプセル内に、プラスに帯電した白色粒子とマイナスに帯電した黒色粒子があり、電極により+やーでカプセル内の粒子を引き寄せます。
これにより、白黒の模様ができて、文字や図形を表示することができます。


E-Paperの仕組みが分かったところで、実際にカレンダーや天気、Googleカレンダーの予定を表示ツールを紹介します。

【接続図】
MCUにはXiao ESP32S3を使用しています。接続はこのようになります。

リポバッテリーを接続でき、充電も可能で大変重宝します。

Xiao ESP32S3は、GPIOピンとデータピンの番号表記が違っているので注意します。



使用しているE-Paperは、WeActStudio社の4.2インチ白黒モードのE-paperです。
 

 

 

【GXEPD2ライブラリとEfontライブラリを使った日本語表示】

GXEPD2ライブラリでは、日本語を表示できません。そこでefontライブラリを使用します。

 

日本語表示には、色々なfontライブラリがあり、SPIFFSへの登録が必要なものがあります。結構面倒ですね。

その点、efontライブラリはインクルードするだけで日本語を使用できるようにします。

 

#include <GxEPD2_BW.h>      //weact 4.2inch e-paper

#include <efont.h>          // efont16

 

#include <WiFi.h>

#include <HTTPClient.h>     //Googleカレンダー、天気予報

#include <ArduinoJson.h>    //Googleカレンダー、天気予報

 

#include "weather_icons.h" //お天気アイコン画像


 

 

 

今回使った日本語表示用プログラムはこちら

下のプログラムは、efontライブラリの日本語を使ってGXEPD2ライブラリで表示するようにしています。

 

========================================================

/*****************************************

*概要:GxEPD2でefontの日本語を表示する関数

******************************************/

// GxEPD2でefontの日本語を表示する関数(半角・全角混在対応版)

void myPrintEfont(int16_t x, int16_t y, String text, uint16_t color) {

  int16_t cx = x;

  int16_t cy = y;

 

  char* pUTF8 = (char*)text.c_str();

 

  // 文字列の末尾に達するまで1文字ずつループ

  while (*pUTF8 != '\0') {

    uint16_t font_code = 0;

   

    // efontライブラリのUTF-8文字列から1文字を抽出し、UTF-16コードに変換

    pUTF8 = efontUFT8toUTF16(&font_code, pUTF8);

   

    if (font_code == 0) break; // エラー時は終了

   

    // 画面に「描画する幅」を判定(半角8px、全角16px)

    bool is_half = (font_code <= 255);

    int draw_width = is_half ? 8 : 16;

    int height = 16;

   

    // フォントのビットマップデータ(32バイト)を格納する配列

    uint8_t font_data[32] = {0};

   

    // efontライブラリからドットパターンを取得

    getefontData(font_data, font_code);

   

    // 1文字分のドットを走査して画面に描画

    for (int font_y = 0; font_y < height; font_y++) {

      // efont内部は半角・全角問わず「常に横16px(1行あたり2バイト)」の構造でデータが入っています

      for (int font_x = 0; font_x < draw_width; font_x++) {

        // 【重要】バイト位置とビット位置の計算は、常に「横幅16」を基準にします

        int byte_pos = font_y * (16 / 8) + (font_x / 8);

        int bit_pos = 7 - (font_x % 8);

       

        if ((font_data[byte_pos] >> bit_pos) & 0x01) {

          display.drawPixel(cx + font_x, cy + font_y, color);

        }

      }

    }

    cx += draw_width; // 次の文字を描画するために、横の座標を進める(半角8px / 全角16px)

  }

}

=======================================================
efontは、16×16dotのFontが使用できるのでこちらを使用しています。

 

【気象庁の天気予報の取得】
下記のURLでjson形式のデータを取得して、そのデータから今日、明日、明後日の天気と気温を取得します。

 

const char* weatherUrl = "https://www.jma.go.jp/bosai/forecast/data/forecast/140000.json"

                          アップエリアコード

エリアコードを変更することで、各県の情報を取得することができます。

 

【このURLから取得できるデータ】

 

weatherCode:天気コードで今日、明日、明後日の天気を表すコード

       ※最下位のweatherCodeは、1週間分の天気コード

temps:今日の最高気温、明日の最高気温、明日の最低気温

tempsMin:1週間の最低気温

tempsMax:1週間の最高気温

 

気象庁の天気予報は、時間によって取得できるデータが違ってきます。

その点を考慮してjsonデータを分割する必要があります。

 

 

【天気画像の作成】

E-paperに表示するための天気画像の作成について紹介します。

今回電子ペーパーに表示しているお天気画像は、32×32ドットの画像です。

この画像を作成するためにお絵かきソフトで画像を作成します。

私の場合、パワーポイントで作成しました。

ネットでは、無料のお天気アイコンもあるのでそちらを利用する方法もありますね。

 

 

作成した画像は32×32pixelで保存します。

私は、作成した画像をMicroSoftのペイントで画像縮小して保存しています。

 

保存した画像をESP32に取り込めるようにビットマップデータに変換します。

今回使用したのはimage2lcd.exeというソフトです。

このツールはE-paperを販売しているWaveshare社のWebからダウンロードできます。

 

このツールを使うと、画像をBitmapデータとしてコードを作成してくれます。

「保存」ボタンを押すと下のようなデータを表示します。こちらを使用してESP32へ読み込ませます。

 

下のデータをweather_icons.hに画像データとして保存しています。

 

// 32x32ドット = 各アイコン128バイト (1行4バイト×32行)

// 1が黒、0が白として描画される形式(Adafruit_GFX / GxEPD準拠)

const unsigned char epd_bitmap_sunny[] PROGMEM = {

0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X01,0X00,0X00,0X00,0X01,0X80,0X00,

0X00,0X01,0X80,0X00,0X00,0X01,0X80,0X00,0X06,0X01,0X80,0X40,0X03,0X01,0X00,0XC0,

0X01,0X80,0X03,0X80,0X00,0XC0,0X03,0X00,0X00,0X43,0XC2,0X00,0X00,0X0F,0XF0,0X00,

0X00,0X1F,0XF8,0X00,0X00,0X3F,0XF8,0X00,0X00,0X3F,0XFC,0X00,0X00,0X3F,0XFC,0X00,

0X7E,0X3F,0XFC,0XFC,0X00,0X3F,0XFC,0X00,0X00,0X3F,0XFC,0X00,0X00,0X3F,0XF8,0X00,

0X00,0X1F,0XF0,0X00,0X00,0X0F,0XE0,0X00,0X00,0XC0,0X06,0X00,0X01,0XC0,0X03,0X00,

0X03,0X80,0X01,0X80,0X07,0X01,0X80,0XC0,0X02,0X01,0X80,0X40,0X00,0X01,0X80,0X00,

0X00,0X01,0X80,0X00,0X00,0X01,0X80,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,0X00,

};

 

下のプログラムで、気象庁のweatherCodeからどの画像を表示するかを選択します。

使用するのは、#include "weather_icons.h" //お天気アイコン画像の中身

インクルードしたweather_icons.hから取得します。

 

/***************************************

*概要:天気コードから天気の画像名を返す

*引数:気象庁より取得した天気コード

*戻値:天気コードより天気画像のzzBitmap画像名を返す

**************************************/

const unsigned char* codeToText(int code) {

  if (code >= 100 && code < 110) return epd_bitmap_sunny;           // 晴れ

  if (code >= 110 && code < 200)  return epd_bitmap_partly_cloudy;  // 晴れ時々曇り

  if (code >= 200 && code < 202)  return epd_bitmap_cloudy;         // 曇り

  if (code >= 202 && code < 300)  return epd_bitmap_kumoriame;      // 曇りのち一時雨

  if (code >= 300 && code < 400)  return epd_bitmap_rainy;          // 雨

  if (code >= 400 && code < 450)  return epd_bitmap_snow;           // 雪

  return epd_bitmap_sunny;

}

 

気象庁から取得するWeatherCodeは、かなり種類が多いです。快晴:100、晴れ時々曇り:110等々。

ある程度コードを絞って画像を貼り付ける必要があると思います。

 

 

【Googleカレンダーの予定表表示】

Googleカレンダーの予定を表示するためには、GAS(Google Apps Script)を作成して、今日の予定を読込みます。

 

GASの作成方法は、こちらを参照してください。

 

こちらのGASを使用して、タイトルと、時間を取得し、E-Paperの右側に表示するようにしています。

私は、自分のスケジュールと家族共有のスケジュールの両方を表示するようにしています。

 

 

【電子ペーパーで天気・予定を表示】

 

 

【まとめ】

今回の電子ペーパーは、2時間に1回、Googleカレンダーの予定と、気象庁データを取得して表示しています。接続図には記載していませんが、Xaio ESP32S3ではリポバッテリーの残量を取得できるように分圧抵抗を設置して、バッテリー残量を表示しています。実際稼働させてみると1.5~2週間程度電池は持つようです。バッテリーが残り少なくなったらType-Cで充電しています。

 

今後は、もう少し違ったメニューも表示可能にしたいと考えています。