はじめに
構造体が正しく、イベントが正しい順番で届き、レジスタへ正しい値を書けたとしても、それだけで装置が使いやすくなるとは限りません。
4行LCDを持つ機器では、ユーザーの指、UI内部、専用ハードウェア、LCDが、それぞれ異なる速度で動きます。
まず、この記事で最終的に扱う画面を示します。コンボボックス、スピンボタン、実行ボタンを持つ4行LCD画面を、ユーザーが待たされていると感じにくい操作へ整えていきます。
私が実機調整で苦労したのは、期限を保証するリアルタイム制御ではありませんでした。異なる速度で動くものを、ユーザーから見て一貫した操作に感じられるよう整えることでした。
この記事では、Spinの長押しで表示値と実動作がずれた経験と、画面切り替え時に旧表示が残って見えた経験をもとに、小型LCD機器の操作感をどう詰めたかを整理します。
本文で扱う経験の範囲
本文は当時の経験を一般化したものです。具体的な周期、通信仕様、装置固有の値は掲載していません。
この記事でいう「リアルタイム」
ここで扱うのは、RTOSやハードリアルタイム制御における期限保証ではありません。
たとえば「キー入力から必ず何マイクロ秒以内に処理する」という話ではなく、押した結果が自然に表示され、実際の装置動作との関係をユーザーが信頼できるか、というUXの話です。
次の四つは、同じ速度では動きません。
| 対象 | 起きていること |
|---|---|
| ユーザー | キーを押す、長押しする、離す |
| UI内部 | 候補値を計算し、編集状態を更新する |
| ハードウェア制御 | コマンドを受け取り、実際の状態へ反映する |
| LCD | 文字データを受け取り、表示を書き換える |
Spinの表示値と実動作がずれた
実機では、電圧レベルのように分解能の細かい数値をSpinで操作する場面がありました。
短押しで1段階ずつ調整する分には問題ありません。しかし、長押し中のすべての変化を同じ間隔でハードウェアへ反映しようとすると、制御側の処理が追いつかず、LCDに表示した数値と実際の動作が一時的にずれることがありました。
表示だけが先へ進むと、ユーザーは現在どの値が装置へ反映されているのか判断しにくくなります。逆に、ハードウェアの完了を毎回待ってから表示すると、今度はキー操作が重く感じられます。
単純に更新周期を短くするだけでは解決しませんでした。UI側で、操作の段階と反映の粒度を整理する必要がありました。
長押しを段階的に加速する
そこで、長押し中の変化量を段階的に切り替えました。
| 操作の段階 | UI上の動き | 装置への反映 |
|---|---|---|
| 押し始め | 1ずつ変更 | 微調整できる範囲で反映 |
| 長押し前半 | リピートを徐々に速くする | 候補値の変化へ追従 |
| 長押し後半 | 5送り、10送りへ切り替える | 不要な中間値を減らす |
| キーを離す | 最後の候補値を確定する | 最終値を反映 |
最初から10送りにすると微調整しにくく、最後まで1送りでは目的の値へたどり着くまで時間がかかります。長押し時間に応じて段階を変えることで、同じ物理キーで微調整と大きな移動を両立させました。
重要なのは、「5送り、10送り」が普遍的な正解ではないことです。値の範囲、分解能、装置の応答、ユーザーが期待する調整の細かさによって変わります。
KeyDown、KeyPress、KeyUpを分けておく
第3回で、キーイベントを三つに分けました。
-
KeyDown: 押した瞬間 -
KeyPress: 押し続けている間 -
KeyUp: 離した瞬間
この分離が、長押し調整で効きました。
KeyDownでは最初の1段階を動かし、KeyPressでは継続時間に応じてリピート間隔や送り量を変えます。そしてKeyUpで最後の候補値を確定します。
物理キー走査、UI上の候補値、ハードウェアへの最終適用を一つの関数へ詰め込むと、加速条件と装置制御が絡み合います。イベントを分けておけば、入力層は「どの段階の操作か」を通知し、画面側は「候補値をどう扱うか」を決められます。
ChangeとSubmitも同じではない
編集中の値には、少なくとも三つの状態があります。
| 状態 | 意味 |
|---|---|
value |
確定済みの値 |
editing |
操作中の候補値 |
original |
編集を始めた時点の値 |
長押し中はeditingを動かします。装置が十分追従できる範囲ではChangeとしてプレビューし、最後のKeyUpまたはEnterでSubmitします。取消された場合はoriginalへ戻します。
ただし、すべての設定を操作中にプレビューするわけではありません。ネットワーク設定や再起動を伴う値などは、候補値を画面内だけで動かし、確定時に初めて装置へ渡す方が安全です。
「変更」と「確定」を分けておくと、装置の性質に応じて反映方針を変えられます。
途中の値を全部処理する必要はない
ユーザーが長押しで大きく値を動かしているとき、通過したすべての中間値が同じ重要度を持つとは限りません。
装置制御がUIより遅い場合は、未処理の中間要求を無制限に積み上げると、キーを離した後も装置だけが過去の値を追いかける状態になります。
そのため、設計時には次を決めます。
- すべての中間値を順番に適用する必要があるか
- 最新の候補値だけを残せるか
- 操作中はプレビューせず、最後だけ確定できるか
- 装置側の処理中に次の要求を受け取れるか
- 失敗したとき、LCDへどの値を表示するか
今回のような調整値では、最終的にユーザーが選んだ値が重要です。一方、操作の途中そのものに意味がある制御では、省略できません。UI側だけで決めず、装置機能の意味と合わせて判断します。
LCDの画面切り替えにも時間が必要だった
遅れるのは専用ハードウェアだけではありません。LCDも、一度に多くの文字を書き換えると表示更新に時間がかかります。
画面全体を素早く切り替えたとき、旧画面の一部が一時的に残り、残像のように見えることがありました。
この装置では、画面遷移の途中へごく短い待ち時間を入れ、旧表示の消去と新しい表示のタイミングを実機で調整しました。
長すぎれば操作が重く感じられ、短すぎれば表示の違和感が残ります。数値だけで決めるのではなく、ユーザー体験を壊さない境界を探る作業でした。
待ち時間を入れること自体が一般解ではありません。
LCDコントローラ、接続方式、書き換える文字数によって条件は変わります。差分描画、転送完了の確認、表示バッファの切り替えが使えるなら、そちらを優先します。待ち時間による調整は、当時の実機と制約の中で選んだ方法です。
仕様書だけでは決められなかった
コード上の値が正しくても、LCDの数値と装置の反応がばらばらに見えれば、ユーザーは操作を信頼できません。
逆に、内部では少し遅れて処理していても、表示と反応の関係が一貫していれば、自然な操作として受け取られます。
当時は社内でもかなり長い時間この装置を触り込みました。
- 長押しを開始するまでの間
- リピートを速くする段階
- 1送りから5送り、10送りへ変える境界
- キーを離したときの最終確定
- 画面を切り替えるときの間合い
実機を何度も操作し、微調整したいときに飛びすぎないか、大きく移動したいときに遅すぎないか、表示と実動作が別々に見えないかを確認しました。
これはハードウェアの遅延を隠すためだけの小細工ではありません。UIとハードウェアの責務を分けたうえで、異なる速度を持つ処理をユーザーへどう見せるかまで設計する仕事です。
実機調整を属人化させないために
操作感には人の感覚が関わりますが、「触って何となく決めた」で終わらせないよう、少なくとも次を残します。
- どの操作で違和感が出たか
- LCD表示と装置状態のどちらが先行したか
- どのイベントで候補値と確定値を分けたか
- 加速段階を変更した理由
- LCD更新方法と待ち時間を選んだ理由
- 対象機種や通信方式が変わったとき、再調整が必要な項目
具体値を機種依存のポリシーとして分離しておけば、別機種で同じ値を盲目的に流用せず、調整すべき場所を見つけやすくなります。
まとめ
小型LCD機器の操作感は、キー入力だけでもLCD描画だけでも決まりません。
- ユーザー、UI、ハードウェア、LCDは異なる速度で動く
- 長押しは、微調整と大きな移動を両立するよう段階的に加速する
-
KeyDown/KeyPress/KeyUpを分け、最後の値を確定できるようにする - ChangeとSubmitを分け、装置に応じてプレビュー方針を選ぶ
- LCDの切り替えは差分描画や完了確認を優先し、必要なら実機で間合いを調整する
- 正しい処理を、ユーザーから見て一貫した操作として届ける
4行しかないLCDでも、そこには確かにユーザー体験があります。社内で誰よりも装置を触り、細かな違和感を一つずつ調整した経験は、構造体の定義と同じくらい、このUI基盤を形作った要素でした。
関連リンク(4行LCDから考える、組み込み機器のUI設計)
- 【4行LCD GUI設計・第1回】4行LCDでもUI設計は必要だった
- 【4行LCD GUI設計・第2回】C言語でWidgetと継承風設計を作る
- 【4行LCD GUI設計・第3回】mallocなしでイベント駆動GUIを組み立てる
- 【4行LCD GUI設計・第4回】物理ボタンから4行LCDのUIを設計する
- 【4行LCD GUI設計・第5回】UIイベントと専用ハードウェアを分離する
- 【4行LCD GUI設計・第6回】リアルタイムではない装置を、リアルタイムに感じさせる(この記事)



