秋月の OLED モジュールを使ってミニ電光掲示板を作る
はじめに
ちょっとしたメモを画面外にキーボードから書きとめておきたいという場合,案外いい方法がありません.スマホに通知を飛ばすとアプリに注意力を取られますし,画面にメモをフローティングさせておくのはマウスポインタの動作に気を使ってしまうという欠点があります.こうした欠点を解決するため,秋月電子通商で買える OLED キャラクタディスプレイモジュールを使ってメモ表示デバイスを作ってみます.
今回は HTML/JS/CSS は最低限とし,大学の古い Web サイトとかにありそうな感じをめざしていきます.昔はそうしたサイトがよく検索に引っかかったものです.ときに緊張感と疲れをもたらす隅々まできっちりと作り込まれたデザインをやめてみませんか. This is ZEN. (?)
動作の様子
完成したUI.OLEDに表示できない部分を赤地で表示している
要件
- タイプした文字を OLED ディスプレイに反映したい
- 反映はリアルタイムでなくてよいが,文字数オーバーのフィードバックはリアルタイムにしてほしい
- スマホから Web UI で更新したい
- とにかく単純に作りたい
以上のことを考えた結果, Raspberry Pi Zero の上で Flask を動かすことにしました.たいした分量でもないので,特に React 等は使わず(なぜならこの週末は React とかキラキラしたもののことを考えたくなかったので)素の Javascript を書いています.
ハードウェア
単に Raspberry Pi と秋月の OLED モジュールを結合しただけです.このモジュールは通常の I2C で通信するモジュールと異なり,出力ピンと入力ピンを両方まとめて SDA
に接続する必要があります.プルアップ抵抗は基板に内蔵されていないので,自前で用意する必要があります.[1]
そのうち無骨な板金ケースとかに入れたいですね.
ソフトウェア
構成
以下のような構成です.複数人が同時に接続して書き換えるようなケースでは WebSocket とかで状態をリアルタイムに反映するとおしゃれではありますが,今のところそうした機能が便利な場面は思いつかず,また面倒なので状態を更新するためにはページを更新すればよいということにしました.
ソースコード
ソースコードは GitHub にアップロードしてあります.
以下では,筆者がハマった部分について書きます.
エディタ部分
エディタ部分には contenteditable
を設定した div
を使いました.当初はこの div の中身に直接色をつけるつもりでしたが,カーソルの移動や IME の扱いで挫折した結果,編集可能な div と全く同じ位置に色付け用の div
を表示することで解決しました.色付け用の div
には編集用と全く同じ内容の文字が入っていますが,文字を透明にすることで背景色だけが見えます.以下2つの div
に寸法が同じになるようなスタイルを設定し,両者を CSS の position:absolute
を利用して重ねています.
エディタの構成
.editor-input
に display: inline-block
を設定したのは contenteditable
を設定した div で改行をしたときに内部に新たな div
が作られるのを防ぐためです(参考).正当な解決方法ではなさそうですが,動くのでとりあえずよしとしました.
<div class="input-wrapper">
<div class="editor-preview" id="oled-preview"></div>
<div class="editor-input" id="oled-input" contenteditable="true"></div>
</div>
.input-wrapper {
position: relative;
}
.editor-input, .editor-preview {
width: 20em;
height: 4em;
padding: 0.25em;
display: inline-block; /* FIXME hacky solution. To prevent Chrome from adding div on newline */
font-size: 1em;
line-height: 1.2em;
overflow-wrap: normal;
font-family: 'Menlo', 'DejaVu Sans Mono', 'Consolas', 'Lucida Console', monospace;
}
.editor-preview {
position: absolute;
z-index: -1;
top: 0;
left: 0;
border: 1px solid black;
border-radius: 4px;
color: rgba(0,0,0,0);
}
サーバサイド
Flask
と SMBus2
(I2Cを操作するライブラリ)をグルーコードでくっつけただけですが, SMBus2
はハードウェアを操作するライブラリなので手元の Mac ではうまく動きません. Raspberry Pi Zero に一々ファイルを rsync
で同期して,などとやっていると動作が遅くてしょうがないので, SMBus2
のダミークラスを用意して SMBus2
のない環境では単に引数を print するようにしました.
今後やるべきこと
まず,ブレッドボードの配線は信頼性が低いのでユニバーサル基板等で配線をする必要があります.同時に,ケースに入れるべきでしょう.壁掛けできる薄型にすべきか,そのへんにポン置きできる箱型にすべきかはこれから考える予定です.さらに,現状は通信が失敗した場合のエラー処理をしていないので,フロントエンドで通信結果を表示したいところです.
-
写真ではわかりづらいですが,10kの抵抗はチップ抵抗をピンヘッダにはんだづけして使っています.たまたま手元にあったのでそうしましたが,面倒なうえに特に利点もないので,リード線形抵抗器を買ったほうがよいでしょう. ↩︎
Discussion