ESP32でGoogleカレンダーの予定を表示
みなさんは、今日の予定をスマホのGoogleカレンダーで確認していませんか。
私も、そんなにスケジュールが在るわけではないのですが、ちょっとした予定をGoogleカレンダーに入れています。
ただ、毎回スマホを開いて予定を確認するのは、面倒だなーと思っていました。
そこで、今回はESP32 Wroom32とST7789ディスプレイを使って今日の予定を表示するようなツールを作成しましたので
紹介したいと思います。
Googleカレンダーは日本語表示なのでESP32も日本語表示できるようにします。

・ESP32WROOM32
・ST7789 1.54インチディスプレイ
・ジャンパーコード
・ブレッドボード
【接続図】

今回紹介する内容は、
1.Googleカレンダーを使用するためのスクリプトの作成方法
2.デプロイURLの作成方法
3.ESP32の各ライブラリのインストール方法
・JSON型データを取得するArduinoJsonライブラリ のインストール
・日本語表示用のLovyanGFXライブラリのインストール
4.ESP32のプログラム紹介
5.ArduinoIDEでのコンパイルとESP32への書込み方法
【Googleカレンダーを使用するスクリプト作成】
Googleカレンダーの予定を表示するためには、Google APIを使用する方法とGoogle Apps Scriptを使用する方法がありますが、私のような初心者でも簡単に使えるGoogle Apps Script(GAS)を使用します。
では、まずGASの作成方法を紹介します。
Googleクロームを開いてその中の[Googleアプリ →Google Apps Script ]この画面でスクリプトを作成します。
【Googleカレンダー用スクリプト】
function doGet() {
// 表示したいカレンダーIDを配列に入れる(自分の、共有A、共有B...)
const calendarIds = [
'自分のメールアドレス, //xxxx@gmail.com
'共有しているカレンダーID' //共有があればカレンダーID
];
const now = new Date();
const start = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59);
let allEvents = [];
calendarIds.forEach(id => {
try {
const calendar = CalendarApp.getCalendarById(id);
if (calendar) {
const events = calendar.getEvents(start, end);
events.forEach(event => {
allEvents.push({
title: event.getTitle(),
startTime: event.getStartTime(), // ソート用
start: Utilities.formatDate(event.getStartTime(), "JST", "HH:mm"),
end: Utilities.formatDate(event.getEndTime(), "JST", "HH:mm")
});
});
}
} catch (e) {
console.log('Error access calendar: ' + id);
}
});
// 複数のカレンダーの予定を時間の早い順に並べ替え
allEvents.sort((a, b) => a.startTime - b.startTime);
const days = ['日', '月', '火', '水', '木', '金', '土'];
const result = {
today: (now.getMonth() + 1) + "月" + now.getDate() + "日(" + days[now.getDay()] + ")",
events: allEvents.map(e => ({title: e.title, start: e.start, end: e.end}))
};
return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}
ーーーーーーここまでーーーーーーー
データは、JSON型データで送信します。
JSON(JavaScript Object Notation)は、JavaScriptのオブジェクト表記を基にした、テキストベースのデータ交換フォーマットです。
キーと値のペア{"key": "value"}で構成されシステム間のデータの受け渡しが可能です。
【デプロイURLの作成】
GASの入力が終わったらデプロイのURLを作成します。
この画面で「新しいデプロイ」をクリックしてデプロイのURLを作成していきます。

【ウエブアプリ画面】

この画面からウェブアプリを選択してウェブアプリのURLを作成します。
画面の遷移に沿って進みます。(詳しくは動画を参照ください)
【新しいデプロイ】

ウェブアプリのURLを作成してコピーしておきます。このURLはESP32側で使用します。(詳細は動画を参照してください)
作成したスクリプトは、Googleドライブに保存されます。
【ESP32の各ライブラリのインストール方法】
【Arduinojsonライブラリのインストール】

ArduinoIDEで左側のライブラリメニューからArduiojsonと入力するとライブラリが表示されるのでインストールします。
このライブラリは、GASから送信されたJSON形式のデータをESP32側に取り込むライブラリです。
【LovyanGFXライブラリ のインストール】

LovyanGFXライブラリこちらもインストールします。
こちらのライブラリは、ST7789ディスプレイに日本語を表示させるためのライブラリです。
【ESP32のプログラム】
ESP32のプログラムです。
このプログラムは、Google Apps Scriptから取得した1日分の予定データをST7789に日本語で表示するプログラムです。
/*****************************************
*概要 ESP32 WROOM32とST7789ディスプレイを使用して
* Googleカレンダーの当日の予定を表示する
* ディスプレイ表示は日本語表示とする。
*********************************************/
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <LovyanGFX.hpp>
const char* ssid = "XXXXXXX"; //自宅のWiFiのSSID
const char* password = "XXXXXXXXX"; //自宅のWiFiパスワード
// GASのウェブアプリURL(https://google.com)
const String gas_url = "https://script.google.com/macros/XXXXXXXXXXXX"; //デプロイで作成したウェブアプリのURLをコピー
int cnt = 20; // 表示開始位置(グローバルなどで定義)
//日本語表示のためのLovyanGFXのクラス定義
class LGFX : public lgfx::LGFX_Device
{
lgfx::Panel_ST7789 _panel_instance;
lgfx::Bus_SPI _bus_instance;
public:
LGFX(void)
{
{ // SPIバスの設定
auto cfg = _bus_instance.config();
cfg.spi_host = VSPI_HOST; // ESP32のVSPI
cfg.spi_mode = 0;
cfg.freq_write = 40000000; // 40MHz
cfg.freq_read = 16000000;
cfg.pin_sclk = 18; // ESP32のSCLKピン
cfg.pin_mosi = 23; // ESP32のMOSIピン
cfg.pin_miso = -1; // ESP32のMISOピン(使用しない)
cfg.pin_dc = 2; // ESP32のDCピン
_bus_instance.config(cfg);
_panel_instance.setBus(&_bus_instance);
}
{ // パネル設定
auto cfg = _panel_instance.config();
cfg.pin_cs = 5; // ESP32のCSピン
cfg.pin_rst = 4; // ESP32のRSTピン
cfg.pin_busy = -1;
cfg.panel_width = 240; //displayの表示サイズ
cfg.panel_height = 240; //displayの表示サイズ
cfg.offset_x = 0;
cfg.offset_y = 0;
cfg.invert = true; // ST7789は反転が必要な場合が多い
_panel_instance.config(cfg);
}
setPanel(&_panel_instance);
}
};
LGFX lcd;
/**********************************
* void setup()
*********************************/
void setup() {
Serial.begin(115200);
//WiFiの接続
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi Connected");
//ディスプレイの初期化
lcd.init();
lcd.setRotation(1); // 画面の向き
lcd.fillScreen(TFT_BLACK);
}
/**********************************
* void loop()
*概要:Googleカレンダーの当日データを読込んで
* ディスプレイに表示する処理(1時間に1回)
*********************************/
void loop() {
getCalendarData(); //Googleカレンダーデータの読み込み処理
delay(30000); // 試験用で30秒に1回データを更新。実際は( 1時間(3600000)で更新するようにする)
}
/**********************************
*void getCalendarData()
*概要:自宅WiFiからGoogleカレンダーにアクセスして、
* 今日の日付とかレーダーの予定を取得する
*********************************/
void getCalendarData() {
cnt = 20;
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.begin(gas_url);
int httpCode = http.GET();
if (httpCode > 0) {
String payload = http.getString();
DynamicJsonDocument doc(4096); // 容量を少し増やしています
deserializeJson(doc, payload);
// 日付の取得と表示
const char* today = doc["today"];
Serial.print("【日付】: ");
Serial.println(today);
// 予定リストの取得と表示
JsonArray events = doc["events"].as<JsonArray>();
Serial.println("--- 今日の予定 ---");
lcd.fillRect(0, 0, 239, 239, TFT_BLACK); //画面を消去
// 日本語フォントの設定(標準搭載フォントを使用)
lcd.setFont(&fonts::lgfxJapanGothic_20);
// テキストの表示
lcd.setTextColor(TFT_WHITE);
lcd.setCursor(0, 0);
lcd.print(" 今日の予定 ");
lcd.println(today);
Serial.println(events.size()); //データが何個あるかを表示
if (events.size() > 0 ){
for (JsonObject obj : events) {
const char* title = obj["title"];
const char* start = obj["start"];
const char* end = obj["end"];
Serial.printf("[%s - %s] %s\n", start, end, title);
calendar_data(start, end, title); //ディスプレイに表示する処理
}
} else { //今日の予定がない場合
lcd.setFont(&fonts::lgfxJapanGothic_16);
lcd.setTextColor(TFT_WHITE);
lcd.setCursor(0, 40);
lcd.print("● 今日の予定はありません!!");
}
}
http.end();
}
}
/**********************************
*void calendar_data( String starttime,String endtime,String titledata)
*概要:Googleカレンダーの予定データをディスプレイに表示する
*引数:today:今日の字付け starttime:予定開始時間 endtime:予定終了時間 titledata:予定内容
*********************************/
void calendar_data(String starttime,String endtime,String titledata){
cnt += 20;
lcd.setFont(&fonts::lgfxJapanGothic_16);
lcd.setTextColor(TFT_WHITE);
lcd.setCursor(0, cnt);
lcd.print(starttime);
lcd.print(" - ");
lcd.setCursor(60, cnt);
lcd.print(endtime);
cnt += 20;
lcd.drawString("●", 0, cnt);
lcd.drawString(titledata, 20, cnt);
}
プログラムは以上です。
【ArduinoIDEでのコンパイルとESP32への書込み方法】
ArduinoIDEで、このプログラムをコンパイルすると容量不足と出てしまいます。
そこでArduinoIDEの「ツール → partition Scheme → Huge APP (3MB No OTA/1MB SPIFFS)」を選択します。

これでコンパイルができ、ESP32へ書込み可能になります。
【まとめ】
ESP32とST7789ディスプレイを使ってGoogleカレンダーの予定を表示されるためには
まず、Googleカレンダー用のスクリプトを用意する。
次にArduinoIDEでArduinojsonライブラリとST77789ディスプレイに日本語を表示できるLovyanGFXライブラリをインストールする。
ESP32用のスケッチをコンパイルする時は、 partition Scheme をHuge APP (3MB No OTA/1MB SPIFFS)に変更する。
今後の課題ですが、このプログラムは、スケジュールが多いと表示があふれて最後まで表示ができない点です。今後はスクロールするなどの工夫が必要ですね。


