choshi0926

https://docs.google.com/spreadsheets/d/1rc22YcvpJLZSAQ9Uq4ken8M5tr9V5M237831FitHcqw/edit?gid=32629693#gid=32629693

↓クイズ

https://docs.google.com/spreadsheets/d/1OxDrQqjk-h2o4S0xEXuTegtohuwycm84ELpLFjxENBs/edit?gid=1351842619#gid=1351842619

テンプレ

https://docs.google.com/presentation/d/1EIIS9EO-MFh0kmYdwbnb7rjLhux3UuLw/edit?usp=sharing&ouid=109027287420363004306&rtpof=true&sd=true

https://drive.google.com/drive/folders/1x27YxvRz-KoNb9ajokHzZMCg61figONN?usp=sharing

no_ota_8MB.csv

# Name,   Type, SubType, Offset,  Size, Flags
nvs,      data, nvs,     ,        0x4000,
otadata,  data, ota,     ,        0x2000,
phy_init, data, phy,     ,        0x1000,
factory,  app,  factory, ,        0x700000,
storage,  data, spiffs,  ,        0x90000,

main.cpp

#include <M5Unified.h>
#include <ESP32Time.h>
#include <ArduinoJson.h>

ESP32Time rtc; // 時刻管理用
int displayMode = 0; // 0:時計, 1:デバイス情報, 2:JSONデモ
const int maxMode = 3;

// 画面更新用の関数
void drawHeader(const char* title) {
    M5.Display.fillScreen(BLACK);
    M5.Display.setFont(&fonts::efontJA_16);
    M5.Display.setTextColor(CYAN);
    M5.Display.setCursor(5, 5);
    M5.Display.print(title);
    M5.Display.drawFastHLine(0, 25, 160, WHITE);
}

void setup() {
    auto cfg = M5.config();
    M5.begin(cfg);

    M5.Display.setRotation(1); // 横向き
    M5.Display.setBrightness(100);

    // 初期時刻を設定 (2026年3月13日 18:00:00)
    // ワークショップでは後にNTPで同期する処理を追加できます
    rtc.setTime(0, 0, 18, 13, 3, 2026); 

    Serial.println("M5StickS3 Demo Started");
}

void loop() {
    M5.update(); // ボタン状態の更新

    // ボタンA(正面)でモード切り替え
    if (M5.BtnA.wasPressed()) {
        displayMode = (displayMode + 1) % maxMode;
        M5.Display.fillScreen(BLACK); // モード切替時に画面クリア
    }

    switch (displayMode) {
        case 0: // 時計モード
            drawHeader("時刻と挨拶");
            M5.Display.setFont(&fonts::efontJA_24_b); // 太字日本語
            M5.Display.setTextColor(WHITE);
            M5.Display.setCursor(10, 45);
            M5.Display.print(rtc.getTime("%H:%M:%S")); // 現在時刻

            M5.Display.setFont(&fonts::efontJA_16);
            M5.Display.setCursor(10, 90);
            M5.Display.print("こんにちは、世界!");
            break;

        case 1: // デバイス情報モード
            drawHeader("S3 ステータス");
            M5.Display.setFont(&fonts::efontJA_12);
            M5.Display.setTextColor(YELLOW);
            M5.Display.setCursor(10, 40);
            M5.Display.printf("バッテリー: %d%%", M5.Power.getBatteryLevel());
            M5.Display.setCursor(10, 65);
            M5.Display.printf("CPU温度: %.1f C", tempSensorRead());
            M5.Display.setCursor(10, 90);
            M5.Display.print("メモリ: 8MB Flash / PSRAM有効");
            break;

        case 2: // JSONデモモード(API連携のシミュレーション)
            drawHeader("JSON解析デモ");
            
            // 擬似的なAPIレスポンス
            char json[] = "{\"weather\":\"晴れ\",\"temp\":24}";
            JsonDocument doc;
            deserializeJson(doc, json);
            const char* weather = doc["weather"];
            int temp = doc["temp"];

            M5.Display.setFont(&fonts::efontJA_16);
            M5.Display.setTextColor(ORANGE);
            M5.Display.setCursor(10, 50);
            M5.Display.printf("天気: %s", weather);
            M5.Display.setCursor(10, 80);
            M5.Display.printf("気温: %d度", temp);
            break;
    }

    delay(100); // 描画負荷軽減
}

micropython

import M5
from M5 import *
import time
import json
import machine
import esp32  # チップ温度取得のために必要

# --- 初期設定 ---
M5.begin()
M5.Lcd.setRotation(1)

# RTCの設定(2026年3月13日 22:30:00)
rtc = machine.RTC()
rtc.datetime((2026, 3, 13, 4, 22, 30, 0, 0))

mode = 0
max_mode = 3

# 見つかった日本語フォントを指定
SELECTED_FONT = M5.Lcd.FONTS.EFontJA24 

def draw_header(title):
    """ヘッダーを日本語で描画"""
    M5.Lcd.fillScreen(0x000000)
    M5.Lcd.setFont(SELECTED_FONT) 
    M5.Lcd.setTextColor(0x00FFFF) # シアン
    M5.Lcd.setCursor(5, 5)
    M5.Lcd.print(title)
    M5.Lcd.drawLine(0, 32, 160, 32, 0xFFFFFF)

# 初回のヘッダー描画
draw_header("時刻と挨拶")

while True:
    M5.update()
    
    # 正面のボタンAでモード切替
    if M5.BtnA.wasPressed():
        mode = (mode + 1) % max_mode
        if mode == 0: draw_header("時刻と挨拶")
        elif mode == 1: draw_header("S3 ステータス")
        elif mode == 2: draw_header("JSON解析デモ")

    if mode == 0:
        # --- モード0: 時計 ---
        t = rtc.datetime()
        M5.Lcd.setFont(SELECTED_FONT)
        M5.Lcd.setTextColor(0xFFFFFF)
        M5.Lcd.setCursor(15, 50)
        M5.Lcd.print("{:02d}:{:02d}:{:02d}".format(t[4], t[5], t[6]))
        
        M5.Lcd.setCursor(10, 90)
        M5.Lcd.print("こんにちは世界!")

    elif mode == 1:
        # --- モード1: バッテリーとCPU温度 ---
        M5.Lcd.setFont(SELECTED_FONT)
        M5.Lcd.setTextColor(0xFFFF00)
        
        bat = Power.getBatteryLevel()
        M5.Lcd.setCursor(10, 45)
        M5.Lcd.print("電池残量: {}%".format(bat))
        
        # 修正ポイント: esp32モジュールから温度を取得
        temp = esp32.mcu_temperature()
        M5.Lcd.setCursor(10, 85)
        M5.Lcd.print("CPU温度: {:.1f}度".format(temp))

    elif mode == 2:
        # --- モード2: JSON解析 ---
        json_str = '{"weather":"晴れ", "temp":24}'
        data = json.loads(json_str)
        
        M5.Lcd.setFont(SELECTED_FONT)
        M5.Lcd.setTextColor(0xFFA500)
        M5.Lcd.setCursor(10, 45)
        M5.Lcd.print("天気: {}".format(data['weather']))
        M5.Lcd.setCursor(10, 85)
        M5.Lcd.print("気温: {}度".format(data['temp']))

    time.sleep(0.1)