ESP32-2432S028-Rを23/05月に購入して、そのまま忘れてましたが、ちょっと整理してたら出てきたので、表記のような時計と天気予報の情報を表示するガジェットを作って見たいと思います。
一応、写真を載せておきます。
SDカードがあるのは良いよなぁ。
まぁ、今回使わないけど。
2千円位ですかね。凝るともっと格好良くできるみたいですが、自分は簡単に作る派なので。テキスト表示と言う。。安易なやり方です。ww
準備するもの
ケースが付いてるものがおススメです。板のままだと立て掛けたりできないので。
2.VS Code でPlatformIOを使います。
3.MicroUSBTypeBケーブル(データケーブルのこと、充電ケーブルはダメ)
コード 3種類
platformio.ini
[env:esp32-cyd]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
lovyan03/LovyanGFX@^1.1.8
bblanchon/ArduinoJson@^7.0.0
build_flags =
-D LGFX_USE_V1
board_build.partitions = huge_app.csv
LGFX_CYD.hpp
#pragma once
#define LGFX_USE_V1
#include <LovyanGFX.hpp>
class LGFX : public lgfx::LGFX_Device {
lgfx::Panel_ILI9341 _panel;
lgfx::Bus_SPI _bus;
lgfx::Light_PWM _light;
public:
LGFX(void) {
{ // SPI bus(HSPI を使用)
auto cfg = _bus.config();
cfg.spi_host = HSPI_HOST; // ★ ここを VSPI → HSPI に
cfg.spi_mode = 0;
cfg.freq_write = 40000000;
cfg.freq_read = 16000000;
cfg.spi_3wire = false;
cfg.use_lock = true;
cfg.dma_channel = 1;
// ★ よくある ESP32-2432S028 系の配線パターン
cfg.pin_sclk = 14;
cfg.pin_mosi = 13;
cfg.pin_miso = 12;
cfg.pin_dc = 2;
_bus.config(cfg);
_panel.setBus(&_bus);
}
{ // LCD panel
auto cfg = _panel.config();
cfg.pin_cs = 15;
cfg.pin_rst = 4;
cfg.pin_busy = -1;
cfg.memory_width = 240;
cfg.memory_height = 320;
cfg.panel_width = 240;
cfg.panel_height = 320;
cfg.offset_x = 0;
cfg.offset_y = 0;
_panel.config(cfg);
}
{ // Backlight
auto cfg = _light.config();
cfg.pin_bl = 21;
cfg.invert = false;
cfg.freq = 44100;
cfg.pwm_channel = 7;
_light.config(cfg);
_panel.setLight(&_light);
}
setPanel(&_panel);
}
};
main.cpp
#include <Arduino.h>
#include "LGFX_CYD.hpp"
#include <WiFi.h>
#include "time.h"
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define LCD_BL 38
LGFX lcd;
const char* ssid = "Your-SSID";
const char* password = "Your-password";
unsigned long lastWeatherUpdate = 0;
String fixLabel(String s) {
// 全角スペースを追加して幅を揃える
if (s == "今日") return "今日 ";
if (s == "明日") return "明日 ";
if (s == "明後日") return "明後日 ";
return s + " ";
}
void drawForecast(const JsonDocument& doc) {
lcd.fillRect(0, 80, 320, 160, TFT_WHITE);
for (int i = 0; i < 3; i++) {
int y = 80 + i * 50;
String label = fixLabel(doc["forecasts"][i]["dateLabel"].as<String>());
String telop = doc["forecasts"][i]["telop"].as<String>();
String tmin = doc["forecasts"][i]["temperature"]["min"]["celsius"].isNull()
? ""
: doc["forecasts"][i]["temperature"]["min"]["celsius"].as<String>();
String tmax = doc["forecasts"][i]["temperature"]["max"]["celsius"].isNull()
? ""
: doc["forecasts"][i]["temperature"]["max"]["celsius"].as<String>();
String tempStr = "";
// ★ 最低・最高の両方がある場合
if (tmin != "" && tmax != "") {
tempStr = tmin + "℃/" + tmax + "℃";
}
// ★ 最低が無くて最高だけある場合
else if (tmin == "" && tmax != "") {
tempStr = tmax + "℃";
}
// ★ 両方 null の場合 → tempStr は空のまま(表示しない)
// ★ ラベルの幅を測る
int labelWidth = lcd.textWidth(label);
// --- 表示 ---
lcd.drawString(label, 10, y);
// ★ ラベルの右に少し余白を入れて天気を描く
lcd.drawString(telop, 10 + labelWidth + 10, y);
// 気温は右側に固定(空なら描画しない)
if (tempStr != "") {
lcd.drawString(tempStr, 220, y);
}
}
}
void fetchWeather() {
HTTPClient http;
// ここのリンクがJSONを貰うための物、cityの後ろを変更する。
http.begin("https://weather.tsukumijima.net/api/forecast/city/110020");
int httpCode = http.GET();
if (httpCode == 200) {
String payload = http.getString();
JsonDocument doc;
deserializeJson(doc, payload);
drawForecast(doc);
}
http.end();
}
void setup() {
pinMode(LCD_BL, OUTPUT);
digitalWrite(LCD_BL, HIGH);
lcd.init();
lcd.setRotation(1);
lcd.fillScreen(TFT_WHITE);
lcd.setFont(&fonts::lgfxJapanGothic_20);
lcd.setTextSize(1);
lcd.setTextColor(TFT_BLACK);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(200);
}
configTime(9 * 3600, 0, "ntp.nict.jp", "pool.ntp.org");
fetchWeather();
}
void loop() {
struct tm timeinfo;
if (getLocalTime(&timeinfo)) {
// 時計の描画(あなたの中央寄せ版)
lcd.fillRect(0, 0, 320, 80, TFT_WHITE);
lcd.setFont(&fonts::lgfxJapanGothic_40);
String timeStr =
String(timeinfo.tm_hour) + ":" +
String(timeinfo.tm_min) + ":" +
String(timeinfo.tm_sec);
int x = (320 - lcd.textWidth(timeStr)) / 2;
lcd.drawString(timeStr, x, 10);
lcd.setFont(&fonts::lgfxJapanGothic_20);
}
// ★ 10分ごとに天気を更新(600000ミリ秒)
if (millis() - lastWeatherUpdate > 600000) {
fetchWeather();
lastWeatherUpdate = millis();
}
delay(1000);
}
進め方 PlatformIO
PlatformIOで適当にProject名を決めます。
Boardは「Espressif ESP32 Dev Module」です。
FrameworkはArduinoです。
で、しばらくすると、環境が用意されるので、以下の手順です。
1.platformio.iniに上記のコードを貼り付け
2.srcフォルダにmain.cppがある所に上記LGFX_CYD.hppを貼り付け
3.main.cppに上記のコードを貼り付け
4.Buildします。
5.Uploadします。
Uploadのとき、ESP32のBOOTボタンを押したままでUploadが終わるまで、押し続けます。
下の写真の左のボタンの下にBOOTボタンとありますので、左がBOOTボタン
ESP32ってなんか、良く分からないですが、自分の触ったやつだと、全部、BOOTボタン押しながら、Uploadするって感じですよね。
なんか、Copilot君とかに聞くと、そうじゃないとか言うのですが?
やり方間違ってるのかな?
一応、ちゃんと目的通り動いているので、問題はないと思ってますが、ESP32のUploadに関しては、正しいやり方がわからない。。。という。。。
誰か教えて欲しい。。。です。。

以上で終わりです。
簡単ですね、一日あれば十分かと思います。
ちなみにテキストのみで作成しましたが、pngとかを使ってお天気マークのアイコン化を当初は目論んでいましたが、ちょっと全然ファイルが上手くできないので、諦めて、テキストのみと言うことになってしまいました。
まぁ、見た目も凝ってないし、スッキリ過ぎてナニコレ?状態ですが、半日で出来たので、良いでしょう。ww
注意点
あ、そうそう、予報の所ですが、当初、OpenweatherのAPIを使おうかと思ったのですが、なんか、最近のは拝金主義にまみれてるので、使わずにこちら ↓
https://weather.tsukumijima.net 天気予報 API(livedoor 天気互換)様
このサイトから目的場所のJSONを貰うようにしています。
ESP32だとあまり重い処理はしたくないので、大変、助かりますね。
で、貰ったJSONをちょっと加工してるってわけです。
上記のコードは埼玉の熊谷気象台の情報です。
なので、上記のサイトへ飛んでいただき、目的の気象台のコードに書き換えてもらえれば、出来上がりですね。
気象台のコードはこれ ↓
https://weather.tsukumijima.net/primary_area.xml
今回、この例の怪しい黄色い基板のヤツですが、ようやく使えることを実証できたので、良かったです。
黄色い基板シリーズも大きさが色々あったりするようですし、内部の設定も色々あるみたいです。
そのへんで上手く行かないこともあるようです。
自分もLGFX_CYD.hppはCopilotに教えてもらいましたしね。
てか、全面、コードはCopilot君にサポートしてもらいました。
ホント便利だなぁ。





