NextionのHMI表示器を使ってみました。
RaspberryPi Picoから制御できる簡単なGUIプロジェクトの作り方と、GUIデータの更新方法を使ってみた内容を記事にしました。
記事の内容
この記事ではマイコン(RaspberryPi Pico)を使ってNextionのHMI を制御する内容を記載します。
マイコンを使って手軽にリッチな表示画面を作成したい方にお勧めです。
記事の内容
・Nextion NX3224T024で作ったもの
・NextionHMIを使うための準備
・GUIプロジェクトの簡単な作り方
今回のアイテム
HMI表示器とは
ユーザとデバイスの中継をするもので、ユーザからの入力情報をデバイス伝えたり、デバイス側からの情報をユーザに伝えたりするものです。
あらかじめ画像データやGUIデータをモジュールに保存し、マイコン側と簡単な電文を使って表示の切り替えやタッチ操作の伝達をします。
今回はNextionのNX3224T024をマイコンから使ってみた内容を記事にします。
主な仕様
Nextionの販売するHMIはたくさんの画面サイズがあり、予算や用途に応じて選べるシリーズも豊富。
今回は最も安価な「Basic」モデルの最小2.4inchを使いました。
モデル名 | NX3224T024 |
シリーズ | Basic |
画面サイズ | 2.4inch |
解像度(W, H) | 320, 240 |
タッチパネル | Resistive (感圧式抵抗膜) |
通信 | UART |
Nextionホームページのリンクはこちら: https://nextion.tech/
◆その他のLCD
外観


ILI9341 LCDモジュール 2.4inch(画像右)と外観を比べてみました。
基板を含めた設置面積はLCDモジュールと同等です。
UARTコネクタに厚みがあるので、組み込む際には干渉しないように注意が必要。

マイクロSDカードモジュールがついていますが、GUIデータ更新用なので動作中にデータの保存や読み取りには使用できません。
使ってみる
NextionHMIは専用のInstructionCodeを組み合わせることで簡単なプログラムを実行できます。
マイコンが使わなくても簡単なゲームやアプリケーションを完成させることもできます。
NX3224T024単体で動作する簡単ゲームを作りました。
これは学生の時に作ったゲームをリメイクしたものです。
地球の引力により落下する月をタップすることで上昇させて阻止します。
ゲームの世界観は無視して、こういったものがHMI単体で実現できるという例です。
今回LEDの点灯消灯コントローラを作ってみます。
簡単なものですが、マイコンとILI9341 LCDモジュールで同じものを作ろうと思うと工数は数倍かかります。
HMIの場合(1時間くらい)
LCDモジュールの場合(3~5時間くらい)

GUIデータの更新は作画ソフトのUART、マイクロSDカード、マイコンからのUARTと豊富にあり、開発から運用のフェーズまで使い分けることができます。
更新方法はこの後の記事で紹介します。
GOOD
・作画ソフトは直感的で操作が良い
・GUIに使用できるコントロールパーツが豊富
・シミュレータの動作が実機に近く、実機確認も手早くできる。
・GUIの更新方法が豊富にあり、開発、量産、フィールドメンテナンスすべて対応できる
・画面のサイズとタッチ方式が豊富で、安価に購入できる
・軽量コンパクトなので、組み込み時の部品干渉も少ない
BAD
作画ソフトのプロジェクト管理が増える。
そのほか
仕事の関係で国内、国外様々なHMIの評価をしてきました。
個人的にはNextionのHMIの作画ソフトの使い勝手、HMI本体の設置性、購入価格が最も優れていると感じています。
HMIを使った開発では作画ソフトの使い勝手次第で開発速度は上がり、時間的な余裕によって成果物の完成度を上げる期待ができます。
シミュレータの再現度も高く、画面操作や通信制御からの動作確認が手軽に行うことができました。
また、HMIから送信されるイベント電文もシミュレータのログに出力されるのでマイコン側への組み込みをスムーズに行えます。
LCDモジュールとしては高価な部類になりますが、HMIとしては最も安価です。
ILI9341と比べても厚みや重さの差異が少ないので組み込み時に部品の干渉が少ないと思います。
HMIの特性上、GUIプロジェクトの管理が増えてしまいます。
機能が豊富なだけにHMIモジュール側で実施する機能と、マイコンプログラムで制御する機能の作業範囲の分配が難しい。
HMIモジュールにプログラムを書きすぎてしまううと、プログラムを複数管理するような複雑なプロジェクトになってしまうので慎重な設計が必要です。
マイコンで記述すると面倒なエフェクトセットはHMIに任せるくらいが管理しやすいと思います。
準備
材料と工具
材料 | 用途 | 細かい情報 |
---|---|---|
HMI表示器 | 表示やタッチ制御 | Nextion HMI NX3224T024 今回の主役です |
マイコン基板 | 画面の表示の指示や、タッチ入力時の処理 | RaspberryPi Pico |
UART変換モジュール | パソコンとHMIをUARTで通信します 必須ではありません | FT232RL |
ブレッドボード | マイコンとLED類を配置します | 400穴以上 |
ジャンパワイヤ | 配線します | オスーオス 10本程度 |
LED | 光らせます | 保護抵抗に200Ωを使います |
Arduino環境の準備
Arduino環境でRaspberryPi Picoを使用します。
Arduino環境の準備はこちらの記事で紹介しています。
NextionEditorの準備
NextionEditorとはHMIに保存するGUI情報を作成する作画ソフトのことです。
HMIは画像データや画面のレイアウトをあらかじめモジュールに保存します。
HMIを使ったプロジェクトではモジュール本体の性能よりも作画ソフトの使いやすさが重要と思います。
NextionEditorの準備は次の2ステップで行います。
1.NextionサイトからNextionEditorをダウンロードする
2.パソコンにNextionEditorをインストールする
1.NextionサイトからNextionEditorをダウンロードする
Nextionダウンロードのページはこちら
https://nextion.tech/

2.パソコンにNextionEditorをインストールする
ダウンロード(Zip)したファイルを任意のフォルダに展開します。
このアプリケーションはインストール作業不要で実行ファイルから起動できます。
展開したファイルに”NextionEditor.exe”があるので起動します。
※注意
起動時にセキュリティーメッセージが表示されることがあります。
実行の可否は自己責任で判断してください。

GUIデータの更新
NextionのHMIではGUIデータを更新するための方法が3種類あります。
この記事ではそのうち2種類を紹介します。
3種類目はマイコンのUARTから更新しますが、試して成功したら記事にします。
1.NextionEditorからの更新
NextionEditorからの更新ではUARTを使い更新します。
USB-UART変換モジュールにはFT232RLを使用しました。(電圧設定のジャンパは5V)

Nextion Editorの「Upload」をクリックすると「Upload to Nextion Device」ウインドウが表示されます。
接続したCOMポート番号を選択し、「Go」をクリックすることで更新できます。

2.マイクロSDカードからの更新
マイクロSDカードにコンパイル済みのGUIデータを保存し、本体の更新機能を使用します。
電源は必要ですが、パソコンを使わなくても更新できるため量産時に手早く作業できます。
5Vの電源(付属のUSBから電源を取り出す基板)とマイクロSDカード(FAT32フォーマット)が必要です。
Nextion Editorの「Compile」ボタンをクリックするとコンパイルが開始され、結果が「Output Pane」に出力されます。
File-> Open build folderをクリックすると更新ファイルを作成したフォルダを表示されます。

更新ファイルをマイクロSDカード(FAT32フォーマット)に保存します。
NextionモジュールのTFカードリーダに挿入し電源を投入すると更新が開始されます。
更新が完了したらマイクロSDカードを抜き取り電源を再投入することで起動します。

作業
説明
マイコンとHMIを連動させた簡単なアプリケーションを作成します。
・起動時オープニングタイトル(たまねぎ)を表示する。
・3秒後に操作画面へ遷移。
・LED「ON」ボタンを押すと実物LEDが点灯し、画面の絵を点灯の絵に変更します。
・LED「OFF」ボタンを押すと実物のLEDが消灯し、画面を絵を消灯の絵に変更します。
作業時間の目安は1時間程度です。
Nextion HMIの機能でオープニング画面を自動で遷移することもできます。
個人的な設計の概念では、HMIが自動で制御する箇所が増えると結果的にプログラムを2つ管理することと同じになると考えています。
マイコン側とHMI側の作業範囲の分配は難しいテーマです。
配線

作業
1.プロジェクトの作成
File->New をクリックします。
ダイアログでプロジェクト名を入力し「保存」をクリックします。
Settingダイアログでは、HMIのモデルとLCDサイズを選択します。
今回はBasicとNX3224T024_011を選択します。
「DISPLAY」タブでは表示の回転角を選択し「OK」をクリックします。

2.リソースの登録
HMIでは表示する画像データをモジュールに保存します。
NextionEditorの「Picture Resource Pane」の「+」をクリックします。
ダイアログから登録する画像データを選択し「開く」をクリックします。
(ファイルは複数選択でまとめて登録することができます。)

今回使用した画像はこちらです。



3.フォント(字体)の登録
HMIモジュールで使用するフォントを作成し登録します。
HMIモジュールの躓きポイントです。
文字や数字の表示をする場合に作成と登録が必要です。
フォントの種類以外に装飾や文字のサイズもそれぞれ作成が必要です。
今回は操作画面で「LED」や「OFF」「ON」といったキャプションに使います。
初めにNextionで使用するフォントファイルを作成し、作成したファイルを登録します。
Tools->Font Generatorをクリックします。
「Font Creator」で文字サイズ、フォント(字体)を選択します。
「Font Name」を入力し、「Generate font」をクリックします。
ダイアログから保存するファイル名を入力します。

「Fonts」タブの「+」をクリックし、作成したフォントファイルを選択します。

4.起動画面を作る
今回起動画面と操作画面の2画面を作ります。
起動画面では画面全体に画像を表示します。
「ToolBox Pane」から「Picture」を選択し「Display Pane」に配置します。
「Picture」が選択されている状態の「Attribute Pane」で「pic」の空白をクリックし「Select Picture」から「2.リソースの登録」で登録した画像を選択します。

5.操作画面を作る
「Page Pane」から画面を追加します。
先頭にあるページが一番最初に表示されます。

以下のオブジェクトをページ上の適当な位置に配置します。
座標とサイズ以外のAttributeの変更値を記載します。
※プロジェクトの起動直後はLEDは消灯状態にします。
Pictureは消灯状態の絵が最前面になる設定をします。
※フォントはデフォルトで0で最初に登録したフォントが使用されます。
変更する場合は任意の値を設定します。
tool | objname | Attribute | Send Componet ID | User Code |
---|---|---|---|---|
Text | t0 | txt = LED | – | – |
Button | BTN_OFF | txt = OFF | On | vis LED_OFF,1 vis LED_ON,0 |
Button | BTN_ON | txt = ON | On | vis LED_OFF,0 vis LED_ON,1 |
Picture | LED_OFF | pic = LED消灯状態の絵 | – | – |
Picture | LED_ON | pic = LED点灯状態の絵 | – | – |

下の画像はPage1(操作画面)のGUI配置の完了状態です。
ボタンを押すことでマイコン側へタッチの通知をする「Send Component ID」にチェックがあり、
LEDの状態をインジケートするための「User Code」も入力しています。

6.動作確認(シミュレータ)
「Debug」ボタンを押すことでシミュレータが起動します。
最初の画像はpage0に設定した画像です。
「Instruction Input Area」にページ遷移命令”Page 1″を入力することで、Page1へ遷移します。
Page1の「ON」ボタンをクリックすることで、LEDの絵が点灯状態に変化し、「Simulator Return」にはUART経由でマイコンに通知する電文が表示されます。
「OFF」ボタンもクリックし、LEDの絵の変化と電文の通知がされることを確認します。
「Instruction Input Area」で使用する命令や、「Simulator Return」の電文をマイコン側のプログラムに組み込むことで効率的な開発ができます。

スケッチ
#include <string.h>
#define UART1_TX (0)
#define UART1_RX (1)
#define LED_PIN (15)
#define DELIMITER_LEN (3)
#define LDOFF_LEN (4)
#define LDON_LEN (4)
const char Delimiter[] = {0xff, 0xff, 0xff};
const char Telegram_LDOFF[] = {0x65, 0x01, 0x04, 0x01};
const char Telegram_LDON[] = {0x65, 0x01, 0x05, 0x01};
char HMI_Buffer[128];
char HMI_Index = 0;
void setup() {
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
//Serialはデバッグ用途, Serial1はHMIとの送受信に使用する
Serial.begin(9600);
Serial1.begin(9600);
Serial1.setTX(UART1_TX);
Serial1.setRX(UART1_RX);
//オープニングタイトルを3秒表示した後、LED Off/On画面へ遷移する
delay(3000);
Serial1.print("page 1");
Serial1.write(0xff);
Serial1.write(0xff);
Serial1.write(0xff);
}
void loop() {
char dat;
//HMIからのイベント確認
if(Serial1.available()){
HMI_Buffer[HMI_Index] = Serial1.read();
HMI_Index ++;
//読み取った結果に 0xff, 0xff, 0xff が含まれている場合HMIからのイベントを受信と判断して解析する
if(HMI_Index > 2){
if(memcmp((HMI_Buffer + (HMI_Index - DELIMITER_LEN)), Delimiter, DELIMITER_LEN) == 0)
HMI_Index = 0;
//LDOFFイベントの判定
if(memcmp(HMI_Buffer, Telegram_LDOFF, LDOFF_LEN) == 0){
digitalWrite(LED_PIN, LOW);
}
//LDONイベントの判定
else if(memcmp(HMI_Buffer, Telegram_LDON, LDON_LEN) == 0){
digitalWrite(LED_PIN, HIGH);
}
}
}
}
結果
コメント