🎍

【Arduino】TcMenu - OLED対応 組込みグラフィカル開発ツールの紹介

に公開

OLEDにもUI

TcMenuというものが存外便利でした。その一方で日本語の情報が一切見つけられなかったので、使用感など含め紹介しています。

https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/

序:TcMenuの存在意義

組込みシステムや電子工作において、画面の設計・実装は非常に重要な工程であると同時に、非常に骨の折れるものでありましょう。特にOSのない環境(bare metal)を対象にするときは、使える開発手段が大きく制限されます。

電子工作といった趣味の範疇であれば、文字だけの表示で簡単に済ますということもよく行われます。かと言って、文字だけの画面では見栄えが良くありません。また、システムとして色々付け加えていくと、画面としての機能性の無さが気になることもあるでしょう。

そんな悩みを解決する手段は既に幾つか存在します。LVGLSlintなどは、見栄えの良さは勿論、GUIとして充分実用的な機能性を持っています。

https://docs.lvgl.io/master/examples.html

しかしこれらも万能ではありません。どちらも、ある程度大きさのあるタッチスクリーン(あるいは単なる液晶画面)が主な用途となります。OLEDは往々にして0.96インチのものが使われますが、これでは小さすぎます。

LVGLOLEDで動かしている事例自体はあるようですが、おそらく容易でないでしょう。機能としても労力としても、過剰と感じます。

lvgl on oled
OLEDLVGL
引用:https://github.com/UsefulElectronics/esp32-ssd1306-lvgl-monochrome


TcMenuは、そんな比較的小さな画面に適した手段です。

TcMenuの例(OLED)
引用:https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/tcmenu-plugins/u8g2-renderer-plugin/

有機EL画面(OLED)だけでなく、1602Aなどの液晶画面(LCD)にも対応しているそうです。

TcMenuの例(LCD)
よく見えない
引用:https://tcmenu.github.io/documentation/arduino-libraries/tc-menu/tcmenu-plugins/liquidcrystalio-hd44780-renderer-plugin/

タッチスクリーンにも対応しているそうですが、そこまで行くと使途次第になるでしょう。やはり見栄えや機能性ではLVGL等に劣ります。

本題

前置きはこの辺にして、TcMenuを実際に使ってみましょう。

導入手順

複数のものを用意する必要があります。なお、Arduino IDEのインストールなど、基本的な開発環境構築は既に済んでいるものとします。

U8g2

ArduinoOLEDを扱うためには、U8g2を使うのが一般的です。Arduino IDEからダウンロードできます。

U8g2

TcMenuDesigner

https://github.com/TcMenu/tcMenu

このソフトウェアは「デザイナー」であり、TcMenu本体ではありません。

Releases

Releasesとあるところから、インストーラーが手に入ります。

Assets

Assetsの下に並んでいる内、Windowsなら.exe Macなら.dmgUbuntuのようなDebian系のLinuxなら.debとあるものをダウンロードします。その他の環境では、Source codeをダウンロードしてどうにかするしかないようです。

ここでは、Windowsの手順を示します。

インストール手順

規約

インストールするには規約に同意します。

インストール先

インストール先を指定します。私は特に変えていません。

ショートカット

ショートカットを作るかどうか選択します。

確認

確認してインストールします。

完了

初回起動

初回起動時のみ、このようなものが出てきました。

tcMenu

Arduino IDEから、TcMenu本体をダウンロードします。

tcMenuダウンロード

実演

インストールが済んだら、実際に使ってみます。

使用デバイス

私の手元にあるものはこちらです。

OLEDSSD1306(128 \times 64)で、拡張ボードに搭載されています。

拡張ボード
引用:https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/

回路について

XIAO拡張ボードを使っているため配線は一切していません

しかし他の環境については手前で読みかえろというのも非礼と思い、参考程度に、配線図に起こせばこうなるだろうという図を示しておきます。慎重に作図したものですが、誤りがあるかもしれません。この配線の動作確認は一切しておりません。充分な調査なしにそのまま真似することは絶対におやめください。

DO NOT REPLICATE
動作未検証:この配線図をそのまま使用することは絶対におやめください
DO NOT REPLICATE: UNTESTED DESIGN.

回路について詳細

以下の回路図は全てこちらから引いたものです。

https://files.seeedstudio.com/wiki/Seeeduino-XIAO-Expansion-Board/document/Seeeduino XIAO Expansion board_v1.0_SCH_200824.pdf

XIAOのピンについて

XIAO pinout
XIAOのピン
引用:https://wiki.seeedstudio.com/Seeeduino-XIAO/

XIAO 「主な」接続先
D1 NC Tact Switch
SDA SDA(SSD1306)
SCL SCK(SSD1306)
3V3 VDD(SSD1306)
GND GND(SSD1306)
NC Tact Switch
スイッチは常時閉でプルアップ

スイッチの箇所

ここにある通り、使用されているスイッチはTS-1111Aです。

https://www.jbl-ec.com/ts-1111a-normally-closed-tactile-switch-smt-63-8mm-product/

上のページを見ると次のようにあり、Normally Closed、即ち「常時閉」であることが分かります。

TS-1111A Normally Closed Tactile Switch SMT 63.8mm
Short Description:
Normally Closed NC Tact Switch SMD 6
3.8mm SPST Surface Mount

そしてこのスイッチは、次のサンプルにもある通り、プルアップで使用します。

https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/#led-control-by-user-button

const int buttonPin = 1;     // the number of the pushbutton pin

void setup() {
  // initialize the LED pin as an output:
  pinMode(LED_BUILTIN, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT_PULLUP);

}

実際の挙動はこのようになります。

スイッチ 入力
押す HIGH
押さない LOW

これが再現できればよいものと思います。

SSD1306との接続

OLEDの箇所
VDDの箇所にVDD_3V3_OLEDとあることからも電源電圧は3.3Vと分かる

先述の通り、XIAOSDA及びSCLピンの電圧は3.3Vです。同様に、VDD3.3Vとなっています。

VDD_3V3_OLEDとあるのは、XIAO3V3のことです。

VDD_3V3_OLED

SYS_3V3
図右上、123V3

VDD_3V3_OLEDSYS_3V3と、SYS_3V33V3と繋がっています。

抵抗

内部抵抗は4.7K

D4_SDAD5_SCL、そのどちらも4.7Kとある抵抗器と繋がっていることが記されています。先のOLEDの箇所に直接の記載はありませんでしたが、確かに抵抗器が使用されていることが分かります。

TcMenuDesignerでの作業

デザイナー側では、Arduinoスケッチを作ることから始めます。

新規プロジェクト作成

起動直後はそれらしい画面が出てきますが、無視して新しく始めるのが明快でした。

New Project
New Projectを選択

I want to create ...とある方を選択して、フォルダーごと新しく作ります。Project NameArduinoスケッチとしての名前を入力します。Namespaceはどこに使われているのかよくわかりませんでした。

プロジェクト設定

PlatformArduino 32bit ARMとしているのは、「XIAO SAMD21CPUARMかつ32bitであるため」です。使用するデバイスによって適切なものを選択しなければなりません。

対応プラットフォーム一覧
対応プラットフォーム一覧

この画面に到達したら、ほぼ完了です。

プロジェクト作成完了

Source file Locationsとある箇所をAll files in current folderにしておきます。

Arduinoスケッチが作られた

Arduinoスケッチでは、フォルダー名と.inoファイル名とが一致していなければなりません。ここではどちらもHelloTcMenuになっています。変にsrcフォルダーが作られると、Arduino IDEで開けなくなります。

UI設計

Add menu item

+マークのボタンで要素を追加します。

整数要素

Integer and Decimal...とあるものを選択すると、整数値を表示・カウントする要素を追加します。
文字列の要素を追加するときはText, IP address...とあるものを選択します。

設定一覧

要素1

要素2

要素3

要素4

実際の表示がどのようになるのか、プレビューで確認することもできます。

Show preview Window
Show Preview Windowを選択する

プレビュー画面
実際の表示ままとは限らない

プログラム出力

UI設計を終えたら、プログラムとして出力します。これに際して、ハードウェアを考慮する必要があります。

Generate Code
Generate Codeを選択

  1. 入力デバイス

入力デバイスとはマウスやキーボードなどの、画面を操作するものを指します。ここでは、XIAO拡張ボードに一つだけあるボタンを使っています。

入力デバイス

ピン設定

The button that will control the menuの下に、ボタンと接続したピン番号を記載します。

ここでは、ボタンがXIAOD1に繋がっているため、1と入れています。

拡張ボードPinout
Button(D1)とある
引用:https://wiki.seeedstudio.com/Seeeduino-XIAO-Expansion-Board/

  1. ディスプレイ

TcMenuは複数のディスプレイに対応しています。ここではOLEDを使っているため、U8G2 display quick start, ...とあるものを選択します。

ディスプレイ種選択

U8G2設定

ここでは次のように設定しています。Display Variableは変数名なので、他の変数と同名にならないものを適当に設定します。

設定 XIAOの場合
Display variable type SSD1306 128x64 HW I2C
Display Rotation U8G2_R0
Clock Pin SCL
Data Pin SDA
Optional Reset Pin U8X8_PIN_NONE

SCLSDAは、XIAOについてvariant.hにて定義されたものです。デバイスや配線によって適切なピンを記載します。

variant.h

これらの設定は、出力されたプログラム中に斯うして現れます。

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE, SCL, SDA);
  1. テーマ

それっぽいものがあったので適当に選びました。

テーマ

  1. 遠隔操作

よくわかっていませんが、遠隔操作するつもりは特にないので何も選んでいません。

remote capabilities

Arduino IDEでの作業

プログラム出力後

今、Arduinoスケッチはこのようになっています。

HelloTcMenu_menu.hHelloTcMenu_menu.cppに、デザイナーで設計した内容が記述されています。例えばヘッダーファイルの方を見ると、各要素を指す変数が確認できます。

HelloTcMenu_menu.h

// Global Menu Item exports
extern TextMenuItem menuTextNewYear;
extern TextMenuItem menuTextU8G2;
extern TextMenuItem menuTextHello;
extern AnalogMenuItem menuAnalogItem1;

今回は特に追記するようなこともないため、XIAOに書き込んで動作確認します。

動作の様子

幅に対して文字数が多かったようで、TextHelloの箇所が潰れています。

それ以外では表示に何の問題もなさそうでした。ボタンによるカーソル移動もできます。

動作1

その他の様子

動作2
ボタンを長押しするとカーソルが切り替わる

動作3
この状態でボタンを押すと数値が増える

動作4
Read Onlyと設定した項目ではカーソルが切り替わらない

動作5
カーソルが下に行くと画面全体がスクロールされる

動作6

動作7

所感

極めて主観的ではありますが、幾つか感じた利点、不満点があります。

プレビューについて

これはPythonGluonix Designer(v2.6当時)と比較した感想ですが、プレビューとそうでないウィンドウを一画面に並べることができます。追加した要素がプレビューでどのように映っているか、確認しながらデザインできます。しかしTcMenuが見やすいというよりは、並べにくいあちらが特段見づらかっただけかもしれません。

入力デバイスと画面との間を定義しなくてよい

これはLVGLと比較した感想です。今回、入力デバイスの設定でControl menu with a single buttonを選んだだけで、何の問題もなく画面を操作することができました。非常に簡単で感動しました。

ほぼローコード開発?

本記事では入力欄を幾つか記載しただけで、一切プログラムを書いていません。Arduinoを使用していて、こんなことは(多分)初めてです。

実際にはプログラムを出力した後、内部処理(コールバックやタスクなど)を自分で追加していく工程も必要ですので、完全なノーコードとはなりませんが、それでも最小限に済むと言えるのではないでしょうか。


コールバックの使い方がまだ分からない

当然ですが、最初から使い方が分かるわけありませんので、始めの方はチュートリアル動画を見ながら試行錯誤していました。

https://youtu.be/ucFqpzMss-4?si=8woGxtHczAI3pPiN

この動画を見ると、プログラム出力後、タスクとコールバックを.inoに追記しています。タスクの方は、乱数を使用して画面に動きをつけていることが分かるのですが、コールバックは動いている様子がありませんでした。

ドキュメントを読めと言われたらその通りですが、なかなか読解に苦労しそうなページが出てきます。

https://tcmenu.github.io/documentation/ref-docs/tcmenu/html/index.html

追記:何となくわかりました。

https://zenn.dev/amenaruya/articles/fca72087e87e62

起動できない不具合

時折、起動に失敗することがありました。

error

アプリの閉じ方が悪いと、画面だけ消えた後も裏で動き続けてしまうようです。タスクマネージャーで都度終了する必要がありました。そのうち改善されるでしょう。

ほんの端緒に過ぎないものではありますが、TcMenuについて紹介致しました。一人でも関心を持つ方があればこれ幸いと存じます。

私としても、今度はLCDで試したいところです。

Discussion