UIFlowで動かすM5ATOM Matrix: 文字スクロール
今回はUIFlowで文字のスクロールを作ってみます。
完成コードはGitHubに上げています。
実行は自己責任でお願いします。
コーディング
処理は大まかに以下の3つです。
- フォント作成
- 表示パターンの作成
- 表示
フォント作成
例えばアルファベットの「M」を以下のように表示させるとします。
「0」が消灯、「1」が点灯で、右の数字は行ごとにこの数字を並べたものです。
コードにすると以下のイメージです。25個の要素としたバージョンと、2進数で1行を1数値にまとめたバージョンです。
char_M1 = [ 1,0,0,0,1, 1,1,0,1,1, 1,0,1,0,1, 1,0,0,0,1, 1,0,0,0,1 ] char_M2 = [0b10001,0b11011,0b10101,0b10001,0b10001]
どっちのパターンで作っても、ブロックでたくさんの文字分用意のは大変すぎるので、1文字1数値で持たせることにします。
5つの2進数を全部連結させて「1000111011101011000110001」として保持します。
char_M3 = 0b1000111011101011000110001
数値ブロックに2進数を入力する際は、先頭に「0b」を付けて入力すれば自動的に10進数にしてくれました。
ちなみに16進数の入力も同じように先頭に「0x」を付ければ行けそうです。
管理しやすいようにMapで定義しました。
がんばってアルファベット大文字小文字、数字、記号を作ってみました。(バッククォートとバックスラッシュは訳あって外しました)
表示領域が5x5しかないのでフォント幅は基本的に3ピクセルで作っています。「M」など厳しいものは5ピクセルまで使ってます。
メモリ使用量がちょっと気になるので、確認する方法があるといいんですが。
表示パターン作成
スクロール用の上記のフォントを並べたリストを作成します。
「M」と「N」を並べると以下のイメージです。間に1列分のスペースを入れています。
image = [ [ 1,0,0,0,1, 0, 1,0,0,0,1 ], # 1行目のリスト [ 1,1,0,1,1, 0, 1,1,0,0,1 ], # 2行目のリスト [ 1,0,1,0,1, 0, 1,0,1,0,1 ], # 3行目のリスト [ 1,0,0,0,1, 0, 1,0,0,1,1 ], # 4行目のリスト [ 1,0,0,0,1, 0, 1,0,0,0,1 ] # 5行目のリスト ]
LEDの1行分を1リストとして、5行分作ったものをさらに1リストにまとめています。
表示させる文字の分だけフォントを連結させます。「A」を追加すると、
image = [ [ 1,0,0,0,1, 0, 1,0,0,0,1, 0, 0,1,0 ], # 1行目のリスト [ 1,1,0,1,1, 0, 1,1,0,0,1, 0, 1,0,1 ], # 2行目のリスト [ 1,0,1,0,1, 0, 1,0,1,0,1, 0, 1,1,1 ], # 3行目のリスト [ 1,0,0,0,1, 0, 1,0,0,1,1, 0, 1,0,1 ], # 4行目のリスト [ 1,0,0,0,1, 0, 1,0,0,0,1, 0, 1,0,1 ] # 5行目のリスト ]
幅の狭い文字は先頭の余分な列を削除して追加します。例えば「A」は幅が3なので3列のみ追加します。
リスト作成のコードはこんな感じです。変数のスコープを理解せずに作っていたので、微妙なとこがぽつぽつあります。。
スクショがちょっと小さくなってしまいましたが、詳細をご覧になりたい方はGitHubからDLしてみてください。
左上の「generate_image」関数に表示させたい文字列を送り、戻り値としてリストを返しています。
マップに存在しない漢字などが指定されたら三本線を表示させることにします。
初期リストの作り方ですが、以下の2パターンだと意味が変わってくるんですかね?
下のパターンだとエラーになってしまいます。
表示
リストができたら、これをちょっとずつずらしながら表示させればスクロール完成です。
最初は1~5要素目を表示し、次は2~6要素目をという感じです。
LED点灯用ブロックは1つずつ表示させるものしかないですが、ループでこれを使うと若干表示が遅くなってしまいました。
なのでpythonコードを直接入れて対応します。「rgb.set_screen()」は25要素のリストを渡すとそのパターンで一瞬で表示してくれます。
要素には色の値を設定するようです。例えば赤画面にする場合は以下のイメージです。
image = [0xFF0000, 0xFF0000, 0xFF0000, ... , 0xFF0000] rgb.set_screen(image)
スクロールのコードはこんな感じです。
リストの作成は若干時間がかかるので1度だけ作って変数化しました。
表示色を設定する関数も追加しました。この作りではスクロール前に「set_color」を実行しないと変数未定義エラーになってしまいます。
ここで設定した色を先ほどの「rgb.set_screen()」に渡しています。
実行
コーディングはこれで完了なので実行してみます。
OKですね。
カスタムその1 加速度センサーでスクロール
加速度センサーが付いてるので、傾けたらスクロールされるようにしてみました。
撮影がへたっぴですみません。。ぶれててちょっと見にくいですね。
角度によって速度を2段階に変えてます。「scroll」関数のみ変更しました。
カスタムその2 ATOM2台で連携
UARTでATOM2台を連携させることもできました。
ブレッドボード用のジャンパー線2本でつなげています。
GRANDも接続しないとまずいのかもですが、その辺はあまりわかってません。。
電源もGPIOから取ってプログラムも本体に書き込めばUSBは1本で済みそうです。
両方ともG19とG22を使ってます。
2台目に表示させるパターンをフォントと同じ要領で1つの数値にして送っています。
以下は送信側のコードです。
色の情報は「set_color」関数で負の値にしてUART送信しました。
なので受け側のATOMを先に起動しておかないと色情報が送られません。
受け取り側は数値を分解して表示させています。
連携方法としてESP-Nowでも試してみましたが、動きがカクカクになってしまうので諦めました。
UARTでもスクロール速度が早すぎると受け側が正しく受け取れなくなることがあります。
カスタムその3 停止処理
スクロールはループなので一度実行すると途中で止められません。
なので、停止フラグを追加してボタンを押したらループを抜けられるようにしてみました。
ボタンを押すと先頭に戻ります。
この処理はブラウザ版UIFlowのv1.7.6では動きますが、デスクトップ版のv1.7.5では止まるときと止まらない時があります。
ループ処理中にボタンイベントが効かなくなってるようですが、最新バージョンでは修正されてるんですかね?
まとめ
UIFlowで文字のスクロール処理を作ってみました。
つくりを変えたらもう少しシンプルになりそうですが、とりあえず動かせたので今回はこれで良しとします。