[ ← DEVELOPER PORTAL ] [ USER MANUALS ]
// 01_LUA_ENGINE_REFERENCE

USHER Lua Application Manual

USHER Lua 組み込み開発環境へようこそ。USHER を使うと、スマートフォンから Bluetooth (BLE) 経由で独立した Lua スクリプトを送信し、スマートウォッチのディスプレイ上で Lua ランタイムを直接動かすことができます。

複雑なファームウェアの再コンパイルは不要です。テキストエディタでスクリプトを書き、スマートフォンアプリからデバイスに転送するだけで、瞬時に新しいアプリやウィジェットを実行できます。

主な特長

  • 超軽量・高速実行: ESP32-S3 の PSRAM 上で最適化された Lua インタプリタが動作し、最大 60FPS のスムーズな描画を実現。
  • 豊富な LVGL 9.4 バインディング: ボタン、ラベル、ARC(円形ゲージ)、スライダー、グラフ、アニメーション、カスタムフォントなどを Lua から直接制御。
  • センサー&ハードウェア連携: 6軸加速度/ジャイロセンサー、I2Sデジタルマイク、内蔵RTCクロック、バッテリー残量、画面輝度調整をシンプルな API で操作。
  • BLE 双方向通信: スマートフォンアプリとリアルタイムにデータ送受信(キーボード/マウスHID、メディア制御、データパケット)。
  • セーブ対応ツール: fs(ファイルシステム)と json API を使って、ユーザー設定やゲームのハイスコアを USHER 本体のフラッシュメモリ (LittleFS) に直接保存・読み込みできます。

// CAPABILITIES: 何が作れるのか?

拡充されたバインディング(連携機能)のおかげで、Lua アプリケーションで非常に多彩な表現が可能になっています。

  • アクションゲーム & おもちゃ: 高精度な sys.millis()、ゲームループに使える lv.timer 関数、ハードウェアシードを利用した math.random() にアクセスできます。Pong、避けゲー、サイコロのようなミニゲームが作成可能です!
  • サイバーパンク・ダッシュボード: 円形ゲージ (Arc)、プログレスバー (Bar)、グラフ (Chart) などのウィジェットを使って、SF 映画に出てくるような没入感のあるデータリッチなインターフェースを構築できます。
  • セーブ対応ツール: fs(ファイルシステム)と json API を使って、ユーザー設定やゲームのハイスコアを USHER 本体のフラッシュメモリ (LittleFS) に直接保存・読み込みできます。
  • IoT コントローラー: BLE API にアクセスしてスマートフォン側の USHER アプリにデータを送り返したり、画面の明るさなどハードウェア機能を直接操作できます。

// METADATA: アプリの構成とメタデータ

Lua アプリケーションの挙動や表示を制御するために、main.lua の冒頭(最初の10行以内)にコメント形式でメタデータを記述できます。

  • @icon (アイコンの設定): アプリ一覧画面で表示されるアイコンを指定します(例:-- @icon: Star)。利用可能な名前の一覧は[04. CYBER ICONS] タブを参照してください。
  • @category (カテゴリの設定): アプリの分類を指定します(例:-- @category TOOL)。
  • @home (ホーム画面への登録): true を指定すると、ホーム画面の watch face ループにウィジェットとして登録されます(例:-- @home: true)。

// WIDGET_GUIDE: ホーム画面ウィジェット開発ガイド

USHER では、同じ Lua スクリプトを 「スタンドアロンアプリ」「ホーム画面に埋め込まれるウィジェット」 の2つのモードで動作させることができます。app.is_interactive() を判定することで、状況に合わせてレイアウトや枠線、入力応答性を動的に切り替えることができます。

1. 独立アプリモード (Standalone App)

フルスクリーンの対話型アプリとして単独起動。すべてのタップ操作、カスタムボタン、ジェスチャー、終了操作をサポート。ミニゲームや電卓、本格的なツール開発に最適です。

2. ホームウィジェットモード (Home Widget)

ホーム画面のスライドショーにインラインで埋め込み動作。ボタンタップ等のUI操作を受け付けつつ、左右・上下スワイプ操作は自動で親画面に伝播してスムーズなページ切り替えを実現します。

// CODE_EXAMPLE: アプリ・ウィジェット開発の実装例

以下は、両モードで適切にレイアウトを分岐させ、タッチイベントを処理する標準的な実装パターンです。

// LUA: widget_template.lua
-- 1. Metadata and configuration
-- @name: MyWidget
-- @home: true

-- 2. Fetch screen root & mode
local scr = lv.scr()
local is_app = app.is_interactive()

-- 3. Create styled container
local container = lv.obj_create(scr)
lv.set_size(container, 240, 240)

if is_app then
  lv.set_style_border_width(container, 1, 0)
else
  lv.set_style_border_width(container, 0, 0)
  lv.set_style_bg_opa(container, 0, 0)
end

-- 4. Create and align button
local btn = lv.btn(container, "Tap Me")
lv.align(btn, lv.ALIGN_CENTER, 0, 40)

-- 5. Set up action callback
lv.add_event_cb(btn, function()
  print("Clicked!")
end, lv.EVENT_CLICKED)

// OPTIMIZATION: 省電力 & ウェアラブル最適化 (Auto-Sleep / Flash Write 制限)

デバイスのバッテリーおよび内蔵フラッシュメモリ (LittleFS) 寿命を保護するため、以下の開発パターンに従ってください。

[POWER_SAVING] 無操作自動終了 (Auto-Sleep)

スタンドアロンモードで起動されたアプリは、一定時間(例:30秒)操作がない場合に app.save_settings(state) でデータを書き出して lv.close() で自動終了させます。最後の数秒間は画面にスリープ警告を表示すると親切です。

[STORAGE] フラッシュ書き込み制限

ゲームループやシミュレーション動作中に app.save_settings() を頻繁に実行するとフラッシュメモリが劣化します。通常状態はメモリ上(Luaローカル変数)だけで値を変更し、アプリを終了する瞬間(EXITボタンタップや自動終了時)にのみセーブを実行してください。

// API_REFERENCE: API リファレンス

現在 USHER の Lua 実行環境で利用可能なすべてのモジュールと API の詳細仕様です。

1. sys (システム & ハードウェア)

USHER のハードウェアリソース、センサー、タイミング、電源制御、オーディオ機能への直接アクセスを提供します。

カテゴリ 関数シグネチャ (SIGNATURE) 戻り値 (RETURNS) 機能説明 / 引数仕様 (DESCRIPTION)
時刻 & タイミング
[TIMING]
sys.millis() int 起動からの経過時間(ミリ秒単位)。デルタタイム計算やゲームループに必須。
sys.uptime() int 稼働時間を秒単位で返します。
sys.get_time() hour, min, sec 現在の時 (0-23)、分 (0-59)、秒 (0-59) を3つの整数として返します。時計アプリ向け。
sys.get_date() year, month, day, wday 現在の年月日および曜日 (wday: 1=日, 2=月, ..., 7=土) を返します。
センサー & メモリ
[SENSORS]
sys.get_accel() x, y, z 3軸加速度センサーから現在の X, Y, Z 値(単位: G)を取得。傾き操作向け。
sys.get_battery() int 現在のバッテリー残量をパーセンテージ (0〜100) で返します。
sys.get_temperature() float USHER 内部の温度センサー値(℃)を返します。
sys.heap_free() int 現在利用可能な空き RAM 容量(バイト単位)を返します。
sys.heap_min() int 起動以降に記録された最小空き RAM 容量。メモリリーク監視用。
ハードウェア制御
[HARDWARE]
sys.set_brightness(level) nil 液晶バックライト輝度を設定 (0〜255)。
sys.set_performance_mode(mode) nil CPUクロック周波数を変更 ("low": 80MHz, "medium": 160MHz, "high": 240MHz)。
sys.reset_activity() nil 省電力マネージャーの無操作タイマーをリセットし、スリープ移行を抑止。
sys.sleep() nil デバイスを即座にディープスリープモードへ移行させます。
sys.restart() nil USHER 本体をハードウェア再起動します。
マイク & 音声
[AUDIO]
sys.audio_start() nil I2S デジタルマイクのサンプリングを開始します。
sys.audio_stop() nil マイクのサンプリング処理を停止して省電力化します。
sys.audio_get_level() int 現在のリアルタイム音量レベル (0〜255) を返します。
sys.audio_get_spectrum([bands]) table FFT 周波数スペクトル配列を返します(デフォルト: 8バンド)。ビジュアライザー用。
コールバック & UI
[EVENTS/UI]
sys.on_shake(callback) nil シェイク検知時のコールバック関数を登録(1秒クールダウン)。nil で解除。
sys.on_mic_level(threshold, cb) nil 音量が threshold を超えた際のコールバック関数を登録。500ms クールダウン。
sys.exit_btn() nil 画面下部に標準EXITボタンを自動生成(スタンドアロン時のみ有効、ウィジェット時は自動非表示)。

2. fs (ファイルシステム)

内蔵ストレージ (LittleFS) 上でファイルおよびディレクトリの入出力操作を行います。

関数シグネチャ (SIGNATURE) 戻り値 (RETURNS) 機能説明 / 引数仕様 (DESCRIPTION)
fs.exists(path) bool 指定したパスにファイルまたはディレクトリが存在すれば true
fs.read(path) string / nil ファイル全体を一括で文字列として読み込みます。ファイル不在または失敗時は nil
fs.write(path, content) bool 指定パスに文字列を上書き保存します。成功時 true
fs.remove(path) bool 指定したファイルまたは空ディレクトリを削除します。
fs.mkdir(path) bool 親階層を含めてディレクトリを再帰的に作成します。
fs.list(dir_path) table 指定ディレクトリ内のファイル名一覧を文字列配列テーブルとして返します。

3. json (データ解析)

Lua のテーブル構造と JSON 文字列・ファイル間の相互シリアライズを行います。

関数シグネチャ (SIGNATURE) 戻り値 (RETURNS) 機能説明 / 引数仕様 (DESCRIPTION)
json.load(path) table / nil JSONファイルを読み込み、Luaテーブルにパースして返します。構文エラー時は nil
json.save(path, table) bool LuaテーブルをJSON文字列に変換し、指定パスのファイルへ永続保存します。

4. app (アプリケーション管理)

実行モードの判定およびアプリ個別設定の永続化管理を行います。

関数シグネチャ (SIGNATURE) 戻り値 (RETURNS) 機能説明 / 引数仕様 (DESCRIPTION)
app.is_interactive() bool 独立フルスクリーンアプリ時 true、ホーム画面ウィジェット埋め込み時 false
app.save_settings(table) bool アプリ固有の settings.json にテーブル内容を即時保存します。
app.load_settings() table / nil 保存済みのアプリ固有設定を読み込みます。未保存時は nil

5. ble (Bluetooth & ネットワーク)

スマートフォンアプリとの高速バイナリ通信、および HID キーボード/マウス/メディアコントロールを提供します。

カテゴリ 関数シグネチャ (SIGNATURE) 戻り値 (RETURNS) 機能説明 / 引数仕様 (DESCRIPTION)
通信 & 状態
[NETWORK]
ble.send(text) nil スマホ側アプリへテキストを高速送信 (Fire & Forget)。
ble.send_reliable(text, [timeout]) bool TCPライクなACKハンドシェイク付き高信頼性送信。成功時 true
ble.is_connected() bool BLE デバイスが接続中であれば true
ble.get_status() string 接続状態文字列 ("idle", "advertising", "bonded", "failed" 等)。
ble.set_enabled(enable) nil BLE の無線機能を有効化/無効化します。
ble.get_device_name() string 接続先ホストのデバイス名文字列を取得します。
コールバック
[CALLBACKS]
ble.on_receive(callback) nil スマホからデータ受信時のコールバックを登録。引数に受信文字列。
ble.on_connect(callback) nil BLE 接続が確立された瞬間に呼び出されるコールバック。
ble.on_disconnect(callback) nil BLE 接続が切断された瞬間に呼び出されるコールバック。
HID キーボード
[KEYBOARD]
ble.kbd_stroke(key, [mod]) nil キーを1回タイプ (例: "a", "ENTER", "ESC", mod: 0x01=Ctrl, 0x02=Shift)。
ble.kbd_press(key, [mod]) nil 指定キーを押した状態を維持します。
ble.kbd_release() nil 押されているすべてのキーを解放します。
ble.kbd_macro(name) nil マクロコマンドを実行 ("copy", "paste", "cut", "lock")。
マウス & メディア
[MOUSE/MEDIA]
ble.mouse_move(dx, dy, [w]) nil マウスカーソルを相対座標で移動します (w: ホイールスクロール)。
ble.mouse_click([btn]) nil マウスボタンをクリック (1=左, 2=右, 4=中クリック)。
ble.media_play() / media_next() nil 音楽の再生/一時停止、曲送り/曲戻し。
ble.media_vol_up() / vol_down() nil 接続機器の音量アップ/ダウン、ミュート切替。
画像バッファ
[IMAGE]
ble.get_jacket_image_dsc() lightuserdata BLE 経由で受信したジャケット画像のLVGL記述子を取得(lv.img_set_src 用)。

6. lv (LVGL グラフィック & UIエンジン)

LVGL 9.4.0 ベースの円形ディスプレイ用UIウィジェット、レイアウト、スタイル、アニメーションAPIです。

分類 主要 API 関数 (SIGNATURE) 機能説明 / 用途 (DESCRIPTION)
ウィジェット生成
[CREATION]
lv.scr(), lv.obj_create(parent) 画面ルートオブジェクトの取得、および汎用コンテナボックスの生成。
lv.btn(parent, [text]), lv.label(parent, [text]) タップ可能なボタン、およびテキスト表示用ラベルの生成。
lv.arc_create(parent), lv.bar_create(parent) 円形アークゲージ (Arc)、および直線プログレスバー (Bar) の生成。
lv.slider_create(parent), lv.chart_create(parent) スライダー入力部品、および折れ線・棒グラフ (Chart) の生成。
lv.lottie_create(parent, src, [w], [h])
lv.lottie_set_src(lottie, src)
Lottie ベクターアニメーションウィジェットの生成・更新。
src にはファイルパス("images/foo.json")または直接 JSON文字列 を指定可能。PSRAM描画バッファを自動確保・解放。
配置 & レイアウト
[LAYOUT]
lv.set_size(obj, w, h), lv.set_pos(obj, x, y) オブジェクトの幅・高さ、および X・Y 座標をピクセル単位で直接指定。
lv.align(obj, align_type, x_off, y_off) 親を基準とした位置合わせ (lv.ALIGN_CENTER, lv.ALIGN_TOP_MID 等)。
lv.center(obj), lv.set_flex_flow(obj, flow) 親の中央配置、および Flexbox 自動整列レイアウト (ROW / COLUMN) の設定。
スタイル & 装飾
[STYLING]
lv.set_style_bg_color(obj, color, 0)
lv.set_style_bg_opa(obj, opa, 0)
背景色および不透明度の設定 (opa: lv.OPA_COVER, lv.OPA_TRANSP)。
lv.set_style_text_color(obj, color, 0)
lv.set_style_text_font(obj, font, 0)
文字色およびフォントの設定 (lv.font_cyber() でサイバーフォント適用)。
lv.set_style_border_color / width / radius 枠線の色・線幅・角丸半径 (Radius) を設定。ネオングロー表現に活用。
イベント & タイマー
[EVENTS/ANIM]
lv.add_event_cb(obj, cb, [event_code]) クリック (LV_EVENT_CLICKED) やジェスチャー発生時のコールバック登録。
lv.timer(ms, callback) 指定ミリ秒間隔で定期実行されるゲームループ・更新タイマーの生成。
lv.anim(obj, cb, start, end, dur, rep, [dly]) イージングアニメーションの登録。プロパティを連続的に滑らかに変化。
メモリ & 終了
[SYSTEM]
lv.obj_delete(obj) / lv.obj_clean(obj) 不要になったウィジェットの破棄、または子要素全削除によるメモリ解放。
lv.close() 実行中の Lua アプリを即座に安全終了し、OSのメインメニューへ復帰。

// LOTTIE VECTOR ANIMATION

USHER は Lottie (.json) ベクターアニメーションをネイティブサポートしています。ファイルパス(LittleFS)からのロードに加え、インラインの JSON文字列データ を直接渡して再生することも可能です。

-- パターン1: LittleFS 内の JSON ファイルを指定
local lottie = lv.lottie_create(scr, "images/cyber_ring.json", 200, 200)
lv.align(lottie, lv.ALIGN_CENTER, 0, 0)

-- パターン2: インライン JSON 文字列データを直接渡す
local json_str = '{"v":"5.5.7","fr":30,"ip":0,"op":60,"w":100,"h":100,"layers":[...]}'
local lottie_inline = lv.lottie_create(scr, json_str, 100, 100)

-- アニメーションの動的差し替え
lv.lottie_set_src(lottie, "images/warning.json")
[パフォーマンス & バッテリー推奨事項]
Lottie は毎フレーム CPU でベクターラスタライズを行うため、常時ループ再生よりも「タップ時や通知時の 1〜2 秒間のサイバー演出」としての利用が最適です。また、30fps("fr": 30)のアニメーションを使用すると消費電力を抑えられます。PSRAM 描画バッファはウィジェット削除時に自動解放されます。

7. require & 定数一覧

Lua 標準の require(modname) による分割ファイル読み込み、およびシステム定数一覧です。

定数グループ 定義済み定数名
アラインメント (Align) lv.ALIGN_CENTER, lv.ALIGN_TOP_MID, lv.ALIGN_BOTTOM_MID, lv.ALIGN_LEFT_MID, lv.ALIGN_RIGHT_MID, lv.ALIGN_TOP_LEFT, lv.ALIGN_BOTTOM_RIGHT
イベントコード (Event) lv.EVENT_CLICKED, lv.EVENT_PRESSED, lv.EVENT_RELEASED, lv.EVENT_VALUE_CHANGED, lv.EVENT_GESTURE, lv.EVENT_DELETE
スワイプ方向 (Direction) lv.DIR_LEFT, lv.DIR_RIGHT, lv.DIR_TOP, lv.DIR_BOTTOM, lv.DIR_ALL
オブジェクトフラグ (Flag) lv.OBJ_FLAG_HIDDEN, lv.OBJ_FLAG_CLICKABLE, lv.OBJ_FLAG_SCROLLABLE
カラーヘルパー (Color) lv.color_hex(0x00FF88), lv.color_white(), lv.color_black(), lv.palette(idx)

[ICONS] 8. カスタムアイコン (Cyber Icons)

USHER には、12px に最適化された豊富なカスタム・テクニカルアイコンが組み込まれています。これらはフォントとして実装されているため、テキストと同様に色を変えたり、サイズを調整したりできます。

[LIST] アイコン一覧と UTF-8 文字列

Lua スクリプト内でアイコンを表示するには、以下の UTF-8 文字列(エスケープシーケンス)を使用します。

アイコン名 Unicode Lua での記述 (UTF-8)
BluetoothU+E001"\xEE\x80\x81"
BatteryU+E003"\xEE\x80\x83"
SettingsU+E004"\xEE\x80\x84"
WarningU+E006"\xEE\x80\x86"
Sun (晴れ)U+E013"\xEE\x80\x93"
MusicU+E016"\xEE\x80\x96"
Check (OK)U+E020"\xEE\x80\xA0"

※ 利用可能な全アイコン一覧およびカラーコード生成ツールは [ 04. CYBER ICONS ] タブ を参照してください。

[EXAMPLE] 使用例 (Lua)

// LUA: icon_usage.lua
-- ラベルに Bluetooth アイコンを表示
local label = lv.label(lv.scr())
lv.set_text(label, "\xEE\x80\x81 Bluetooth Active")
lv.set_style_text_color(label, lv.color_hex(0x00FFFF), 0) -- ネオンシアン
lv.center(label)

Welcome to the USHER Lua development environment. USHER allows you to execute standalone Lua scripts on the round smartwatch display, transmitted wirelessly over Bluetooth LE from your phone.

This document serves as the complete technical reference for Lua capabilities, lifecycle management, and API bindings.

// CAPABILITIES

  • Games & Interactive Toys: High-precision sys.millis(), lv.timer, and hardware-seeded math.random() for building mini-games.
  • Cyberpunk Dashboards: Circular arcs, bar gauges, and line charts for data-rich wearable interfaces.
  • State Storage: fs and json APIs write persistently to LittleFS on SPI flash.
  • IoT & BLE Control: Stream sensor telemetry back to smartphones or trigger phone controls via BLE HID commands.

// METADATA ANNOTATIONS

Configure app attributes in the first 10 lines of main.lua:

  • -- @icon: <IconName>: Assigns app list icon (e.g. -- @icon: Dice).
  • -- @category: <Category>: Categorizes app in library (e.g. -- @category: GAME).
  • -- @home: true: Registers app as a swipeable home widget carousel item.

// API_REFERENCE: LUA API SPECIFICATIONS

Comprehensive reference for all standard modules available in the USHER Lua runtime environment.

1. sys (System & Hardware)

Direct low-level access to USHER hardware resources, onboard sensors, timers, power states, and audio processing.

GROUP SIGNATURE RETURNS DESCRIPTION
Timing & Clock
[TIMING]
sys.millis() int System uptime in milliseconds. Essential for delta-time and game loops.
sys.uptime() int Uptime in whole seconds.
sys.get_time() hour, min, sec Returns 3 integers for current hours, minutes, seconds.
sys.get_date() year, month, day, wday Returns calendar date and weekday (1=Sun, ..., 7=Sat).
Sensors & Heap
[SENSORS]
sys.get_accel() x, y, z 3-axis accelerometer readings in Gs. Ideal for tilt gestures.
sys.get_battery() int Battery level percentage (0 to 100).
sys.get_temperature() float Internal USHER device temperature (in deg C).
sys.heap_free() int Currently available free RAM heap in bytes.
sys.heap_min() int Minimum lifetime free heap recorded (useful for memory leak detection).
Power & Control
[HARDWARE]
sys.set_brightness(level) nil Sets LCD backlight brightness level (0 to 255).
sys.set_performance_mode(mode) nil Sets CPU clock speed ("low": 80MHz, "medium": 160MHz, "high": 240MHz).
sys.reset_activity() nil Resets idle timer to prevent auto-sleep during active loops.
sys.sleep() nil Immediately transitions device into deep sleep mode.
sys.restart() nil Performs hardware reboot of the USHER device.
Microphone & Audio
[AUDIO]
sys.audio_start() nil Starts background DMA sampling of I2S digital microphone.
sys.audio_stop() nil Stops microphone sampling to save power.
sys.audio_get_level() int Returns current realtime microphone amplitude (0 to 255).
sys.audio_get_spectrum([bands]) table Returns FFT frequency band amplitudes array (default 8 bands).

2. fs (File System)

Read, write, and manage persistent files and directories stored on LittleFS flash partition.

SIGNATURE RETURNS DESCRIPTION
fs.exists(path) bool Returns true if target file or directory exists.
fs.read(path) string / nil Reads entire file contents into string. Returns nil on error.
fs.write(path, content) bool Overwrites file with string content. Returns true on success.
fs.remove(path) bool Deletes target file or empty directory.
fs.mkdir(path) bool Creates directory recursively.
fs.list(dir_path) table Returns an array of file name strings within the target folder.

3. json (Data Serialization)

Bridge Lua dictionary tables and JSON files effortlessly.

SIGNATURE RETURNS DESCRIPTION
json.load(path) table / nil Loads and parses a JSON file into a Lua table.
json.save(path, table) bool Serializes Lua table to JSON and persists to flash file.

4. app & ble (App Lifecycle & Bluetooth)

MODULE SIGNATURE RETURNS DESCRIPTION
app app.is_interactive() bool true for standalone full app, false for home widget.
app.save_settings(tbl) bool Saves table into app-specific settings.json.
app.load_settings() table / nil Loads app-specific persistent settings table.
ble ble.send(text) nil Sends text packet over BLE (Fire & Forget).
ble.send_reliable(text) bool Sends text with ACK flow control handshake.
ble.is_connected() bool Returns true if BLE connection is active.
ble.on_receive(callback) nil Registers handler for incoming messages from host phone.
ble.kbd_stroke(key, [mod]) nil Emulates HID keyboard keystroke.
ble.media_play() / next() nil Sends Consumer HID media playback command.
← 開発者ポータルへ ← Back to Dev Portal
// 02_PROTOCOL_INTEGRATION

App Integration & BLE Guide

USHER (スマートペンダントデバイス) とスマートフォンコンパニオンアプリ (Flutter) 間のデータ連携、および組み込み Lua アプリを活用した新規機能(マイク・音声・データ同期など)の開発ガイドラインです。

[01] システム連携アーキテクチャ

エコシステムは以下の3レイヤー構造で相互通信を行っています。

// HUD_SYSTEM_TOPOLOGY // 3-TIER ARCHITECTURE
LIVE_TOPOLOGY
LAYER 01: スマホアプリ (Flutter Engine)
HOST / CONTROLLER
> UI / ネットワーク / 録音 / 高速演算
> アプリ内 Lua VM エミュレータ (lua_emulator.dart)
⇅ BLE (Custom GATT / ACK Protocol) & USB Serial
LAYER 02: USHER ファームウェア (Core Runtime)
HARDWARE / OS
> LVGL 9.4.0 (240x240 円形ディスプレイ)
> I2S デジタルマイク & オーディオサンプリング
> C++ 固有バインディング (lua_core_bindings.cpp)
⇅ LittleFS I/O & Dynamic VM Execution
LAYER 03: 組み込み Lua アプリ (LittleFS Storage)
USER APP / WIDGET
> UI描画 (lv.btn, lv.lottie_create 等)
> マイク・センサー検知 (sys.on_mic_level 等)
> BLE / スマホ双方向通信イベント

[02] BLE 通信プロトコル仕様

デバイス側とスマホ側はカスタムGATTサービス経由で相互通信を行います。

機能 / チャンネル 通信方式 用途
ファイル転送 Custom GATT Service Luaスクリプト、画像(.rgb565)、音声データの高速パケット転送
コマンド制御 Custom GATT Service アプリ切り替え、設定変更、マイク機能の開始/停止コントロール
データ通知 Custom GATT Service リアルタイムセンサー、マイク音量レベル、バッテリー通知

[CRITICAL] 通信プロトコルの同期ルール

データ構造やコマンドIDを変更する場合は、必ず USHER デバイス側 (C++) と Flutter Dart 側の双方を更新し、バージョン番号をインクリメントしてください。

[03] マイク・音声連携アプリの開発パターン

マイクや音声機能を統合した連携アプリを開発する場合、2つのアプローチが選択可能です。

パターン A: スマホ主導型 (推奨)

スマホの高性能なマイクと音声処理・AIエンジン(文字起こしや音声解析)を活用し、USHER画面をリモートインジケーターとして活用する構成です。

  • スマホアプリ: 音声を高音質録音・解析し、結果や音量波形データをBLEでUSHERへ送信。
  • USHER (Lua): 受信データから画面にリアルタイム波形描画を行い、タッチ操作で録音の開始/停止コマンドをスマホへ送信。

パターン B: USHER デバイス主導型

USHER本体のI2Sデジタルマイクを直接駆動する構成です。

  • 音量検知 (利用可能): sys.on_mic_level(threshold, callback) による閾値音量検知とイベント発動。
  • ストリーミング・録音 (拡張可能): 取得したPCMデータをバッファリングし、BLE経由でスマホへ転送してWAV形式保存。

[04] Luaバインディングとエミュレータの同期

新しいLuaバインディングを追加する際は、実機 (C++) とスマホアプリ内エミュレータ (Dart) の双方に同様のロジック/モックを実装し、エミュレータ上でも完全動作するように維持します。

This technical guide details the integration guidelines between USHER Device and the Smartphone Companion App (Flutter), as well as extending Lua applications with audio/microphone and data sync capabilities.

[01] System Integration Architecture

The ecosystem leverages a 3-tier system architecture for inter-process communication between mobile apps, firmware, and embedded Lua scripts.

// HUD_SYSTEM_TOPOLOGY // 3-TIER ARCHITECTURE
LIVE_TOPOLOGY
LAYER 01: Smartphone App (Flutter Engine)
HOST / CONTROLLER
> UI / Networking / Audio Recording / Computations
> In-App Lua VM Emulator (lua_emulator.dart)
⇅ BLE (Custom GATT / ACK Protocol) & USB Serial
LAYER 02: USHER Firmware (Core Runtime)
HARDWARE / OS
> LVGL 9.4.0 (240x240 Circular Display)
> I2S Digital Mic & Audio Sampling
> C++ Native Bindings (lua_core_bindings.cpp)
⇅ LittleFS Storage & Dynamic VM Execution
LAYER 03: Embedded Lua Apps (LittleFS Storage)
USER APP / WIDGET
> UI Rendering (lv.btn, lv.lottie_create etc.)
> Microphone & Sensors (sys.on_mic_level etc.)
> BLE / Smartphone Bi-directional Events

[02] BLE Protocol Specifications

Data packets and control commands are streamed through custom GATT services over Bluetooth LE using custom ACK handshake mechanisms.

[03] Microphone & Audio Integration Patterns

Supports both smartphone-centric high-quality recording and onboard I2S digital mic level detection with real-time spectrum visualizers.

[04] Firmware & Emulator Sync

Ensure any new C++ Lua bindings are mirrored in the Flutter-side Dart VM emulator for seamless prototyping.

// 03_HARDWARE_BLUEPRINTS

USHER Hacker's Hardware Guide

USHER オープンソースエコシステムへようこそ!このドキュメントは、カスタムファームウェアの構築、自作のスマホアプリの開発、またはハードウェアクローンの作成に必要な低レベルの技術仕様を提供します。

[01] ハードウェア仕様 & ピンマップ

USHER は ESP32-S3-WROOM-1U-N16R8 モジュールを採用しています。自作のファームウェア(Arduino や ESP-IDF 等)を書き込んでデバイスをカスタマイズしたい開発者のために、USHERの各周辺機器のPIN配置(GPIOマッピング)を以下に開示します。

周辺機器 (PERIPHERAL) 信号名 (SIGNAL) GPIO ピン 機能 & 仕様 (DESCRIPTION)
ディスプレイ
GC9A01 (SPI)
D_DC GPIO 38 データ / コマンド切替
D_CS GPIO 39 SPI チップセレクト
D_SCL GPIO 40 SPI クロック (SCL)
D_SDA GPIO 41 SPI MOSI (データ送信)
D_RESET GPIO 42 ディスプレイハードウェアリセット
D_LEDA GPIO 2 バックライト輝度制御 (PWM)
タッチパネル
CST816D (I2C)
TP_SDA GPIO 47 I2C データ (IMUと共有)
TP_SCL GPIO 48 I2C クロック (IMUと共有)
TP_RST GPIO 14 タッチコントローラリセット
TP_INT GPIO 13 タッチ検知 外部割込
モーションセンサー
6軸 IMU (I2C)
IMU_SDA GPIO 47 I2C データ (TPと共有)
IMU_SCL GPIO 48 I2C クロック (TPと共有)
DOUBLE_TAP GPIO 9 ダブルタップ検知 外部割込
デジタルマイク
I2S Digital Mic
MIC_BCLK GPIO 5 I2S ビットクロック
MIC_WS GPIO 6 I2S ワードセレクト (L/R)
MIC_DIN GPIO 7 I2S オーディオデータ入力
電源管理
Power & Battery
BAT_VOLT GPIO 15 バッテリー電圧監視 (ADC)
内部予約ピン
※外部利用不可
PSRAM_BUS GPIO 35, 36, 37 ESP32-S3 内部 8MB PSRAM (SPIRAM) 専用バス

[WARNING] Wi-Fi制限と電波曝露(SAR)警告

本製品の公式ハードウェアは、出荷段階でWi-Fi機能を無効化し、極低出力なBLE(Bluetooth Low Energy)接続のみを有効化することで、人体近接時の安全基準であるSAR(比吸収率)の許容値基準を満たしています。自作ファームウェアにおいてWi-Fi機能を有効化した場合、SARの安全基準値を超過するリスクがあり、すべて開発者の完全な自己責任となります。

[02] パーティションマップとメモリレイアウト (重要)

OTAアップデートをサポートし、ファイルシステムを保護するため、USHER は固有のパーティション構成を使用します。自作のカスタムファームウェアを書き込む場合は、ビルド時の partitions.csv が以下のレイアウトと完全に一致している必要があります。これを守らないとOTA機能が文鎮化(破壊)します。

// CONFIG: partitions.csv
# Name,   Type, SubType, Offset,  Size,     Flags
nvs,      data, nvs,     0x9000,  0x4000,
otadata,  data, ota,     0xd000,  0x2000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 0x220000,
ota_0,    app,  ota_0,   0x230000,0x220000,
littlefs, data, spiffs,  0x450000,0xBB0000,

(注: サブタイプは spiffs になっていますが、実際のコード内ではウェアレベリングとディレクトリ対応のために LittleFS としてマウントされます。)

マウントポイント

  • LittleFS マウント先: /littlefs
  • Lua アプリの保存先: /littlefs/apps/
  • システムアセット: /littlefs/assets/

[03] Bluetooth LE (GATT) プロトコル

Luaスクリプト、アセット画像、またはカスタムファームウェア(OTA)をワイヤレスでデバイスに送信するには、USHER のBLEサーバーに接続します。

  • Command Characteristic (Write): 転送の開始コマンドなどに使用(例: START_OTA, START_FILE_TRANSFER:/apps/my_app/init.lua)。
  • Data Characteristic (Write without Response): 実際のバイナリデータやテキストチャンクをストリーミング送信するために使用。USHERのPSRAMを活かしたPing-Pongバッファ方式を採用し、高速転送を実現しています。
  • Notify Characteristic (Read/Notify): デバイスからスマホに対して、ACK(例: ACK:128KB)やエラーメッセージを返します。

カスタムファームウェアのOTAアップデート手順

  1. スマホが Command Characteristic に START_OTA:<file_size> を送信する。
  2. デバイスが esp_ota_ops API の準備を行い、Notify で応答する。
  3. スマホが .bin ファームウェアファイルを MTU サイズのチャンクに分割し、Data Characteristic へストリーミングする。
  4. デバイスは 128KB 受信するごとに ACK を返す。
  5. 送信完了後、スマホが END_OTA を送信する。
  6. デバイスが新しいブートパーティションを設定し、自動的に再起動する!

高信頼性 BLEデータ転送 (TCPライクなACK制御)

BLEはMTUサイズやパケットロスの問題から、大容量ファイル(GIFやファームウェアなど)の転送ではタイムアウトしやすく不安定になりがちです。
この問題を解決するため、USHER はBLE上で TCPのようなACK(確認応答)システム を独自実装しています。

  1. スマホからは「Write Without Response」を用いて、待機時間ゼロでパケットを高速ストリーミングします。
  2. USHER本体は、内蔵するPSRAMを巨大なバッファとして使い、データを受け止めます。
  3. 128KB受信するごとに、デバイスからスマホへ確実にACKを通知(Notify)します。
  4. スマホ側はACKの遅延や消失を検知すると転送を一時停止し、バッファ溢れやBLEのタイムアウトを未然に防ぎます。
    このハンドシェイクにより、Wi-Fiを一切使わず、BLE単体で超巨大ファイルの安定転送を実現しています!

[04] 公式コンパニオンスマホアプリ

Flutterで構築されたコンパニオンアプリ(smartphone_app/内)が完全に統合されました。

主な機能

  • 高信頼性 BLE 同期: USHER デバイスと自動接続し、カスタム RGB ファイルの転送や OTA ファームウェアアップデートを独自の TCP ライクな ACK ハンドシェイクプロトコルで実行します。
  • 組み込み Lua エミュレータ: 円形ベゼルプレビュー、Google Fonts、UTF-8 アイコンマッピング、モック設定永続化ストレージに対応した Lua 5.3 仮想マシンを搭載しています。
  • GIPHY 検索 & ダウンローダ: クイック検索とスクロール可能なカテゴリー分け、動画クリップエディタへの直接連携が可能です。
  • 再設計された作成済みファイルギャラリー: 自作の RGB プレイヤーを内蔵したグリッドレイアウトで、BLE 圧縮ファイルを直接再生可能です。
  • アプリテーマカスタマイザ: 設定内からアクセス可能なインタラクティブなテーマエンジンを搭載しています。

詳細なユーザー操作方法については、Companion App Manual を参照してください。

Welcome to the USHER Open-Source ecosystem! This document provides the low-level technical specifications necessary to build custom firmware, develop your own companion smartphone apps, or create hardware clones.

[01] Hardware Specifications & Pinout

USHER is built around the ESP32-S3-WROOM-1U-N16R8 module. For developers wishing to flash custom firmware (Arduino, ESP-IDF, etc.) and customize the hardware behaviors, we disclose the exact GPIO pin mapping for all onboard peripherals below:

PERIPHERAL SIGNAL GPIO PIN DESCRIPTION
Display
GC9A01 (SPI)
D_DC GPIO 38 Data / Command Select
D_CS GPIO 39 SPI Chip Select
D_SCL GPIO 40 SPI Clock (SCL)
D_SDA GPIO 41 SPI MOSI (Data Output)
D_RESET GPIO 42 Hardware Reset
D_LEDA GPIO 2 Backlight PWM Brightness Control
Touch Panel
CST816D (I2C)
TP_SDA GPIO 47 I2C Data (Shared with IMU)
TP_SCL GPIO 48 I2C Clock (Shared with IMU)
TP_RST GPIO 14 Touch Controller Reset
TP_INT GPIO 13 Touch Interrupt Input
Motion Sensor
6-Axis IMU (I2C)
IMU_SDA GPIO 47 I2C Data (Shared with TP)
IMU_SCL GPIO 48 I2C Clock (Shared with TP)
DOUBLE_TAP GPIO 9 Double-Tap Interrupt
Digital Mic
I2S Digital Mic
MIC_BCLK GPIO 5 I2S Bit Clock
MIC_WS GPIO 6 I2S Word Select (L/R)
MIC_DIN GPIO 7 I2S Audio Data Input
Power & Battery
Power Management
BAT_VOLT GPIO 15 Battery Voltage Monitor (ADC)
Reserved Pins
※NC / Unusable
PSRAM_BUS GPIO 35, 36, 37 ESP32-S3 8MB Octal PSRAM Dedicated Bus

[WARNING] Wi-Fi RF Exposure & SAR Compliance Warning

The official hardware is designed and pre-certified for Bluetooth Low Energy (BLE) only, completely disabling Wi-Fi to meet Specific Absorption Rate (SAR) limits for body-worn devices. If you write custom firmware that enables Wi-Fi, you may exceed Specific Absorption Rate (SAR) limits. Enabling Wi-Fi on this hardware is strictly at your own risk.

[02] Partition Map & Memory Layout

To support OTA updates and protect the file system, USHER uses a specific partition layout. If you are flashing custom firmware, you MUST ensure your partitions.csv matches this layout.

// CONFIG: partitions.csv
# Name,   Type, SubType, Offset,  Size,     Flags
nvs,      data, nvs,     0x9000,  0x4000,
otadata,  data, ota,     0xd000,  0x2000,
phy_init, data, phy,     0xf000,  0x1000,
factory,  app,  factory, 0x10000, 0x220000,
ota_0,    app,  ota_0,   0x230000,0x220000,
littlefs, data, spiffs,  0x450000,0xBB0000,

[03] Bluetooth LE (GATT) Protocol

Streaming over custom GATT characteristics with ping-pong buffering and ACK flow control.

[04] Official Companion Smartphone App

Full-featured Flutter companion app with live Lua emulator and BLE sync. See Companion App Manual for details.

// 04_ICON_LIBRARY

CYBER ICONS HUD LIBRARY

ファームウェアに組み込まれた 12x12 ピクセルのドットアイコンライブラリ。
リアルタイムにアイコン色・背景色をカスタマイズしてプレビュー可能。UTF-8リテラル文字列や、選択色を反映した LVGL Lua スタイルコード をワンクリックでクリップボードへコピーできます。

Firmware-embedded 12x12 technical pixel icon library.
Customize colors and backgrounds with live interactive rendering. Copy UTF-8 escape sequences, @icon annotations, and pre-styled LVGL Lua snippet blocks with one click.

// ICON COLOR:
#00FF88
// BG COLOR:
#000000
開発者ポータルへ戻る → Back to Developer Portal →
COPIED TO CLIPBOARD!