Nextion Editor × Raspberry Pi Pico
- はじめに|Nextion 3.2インチ(NX4024T032)×Raspberry Pi Pico×BH1750で照度計を作る
- この記事で使う部品(Nextion NX4024T032・Raspberry Pi Pico・BH1750 ほか)
- 配線図|NextionのUART1とBH1750のI2C0をRaspberry Pi Picoに接続する
- Nextion Editorの使い方|ダウンロードから新規プロジェクト作成(Display direction・Character Encoding)まで
- Nextionのフォント作成(Font Creator)|「Invalid Font ID」エラーとSpecified Characterの指定方法
- Picture・Text・Button部品の配置|画像Importのサイズ制限「ERROR 1 pieces」とTouch Release Event
- ダーク/ライトモード切り替えを実装しSimulatorで動作確認する
- コンパイルからmicroSDカード書き込みまで|.tftファイルを実機に転送する
- MicroPythonでBH1750のlux値をNextionにUART送信する(コード解説)
- 完成デモ|lux値・ラベル・イメージ画像が連動して切り替わる様子
- よくある質問(FAQ)
- まとめ
- シリーズ記事一覧
はじめに|Nextion 3.2インチ(NX4024T032)×Raspberry Pi Pico×BH1750で照度計を作る
こんにちは。ニンジンです🥕
今回は、Nextion社の抵抗式タッチパネル「NX4024T032」(3.2インチ・400×240)を使って、Raspberry Pi PicoとBH1750照度センサーで測った明るさ(lux値)をタッチパネルに表示するミニ工作を作りました。
画面には lux数値・帯ラベル(NIGHT / DIM / HALLWAY / LIVING / DESK / OUTDOOR)・明るさに応じたイメージ画像 の3点セットをリアルタイム表示し、画面をタッチするとダーク/ライトモードも切り替えられます。
▲ 完成イメージ。lux値が変わるとラベルとイメージ画像が連動して切り替わる
Nextionのタッチパネル自体は電子工作界隈で定番の部品ですが、専用ソフト「Nextion Editor」の使い方を日本語でまとめた資料はほとんど見当たりませんでした(検索して確認済みです)。この記事では、実際に手を動かして分かった操作・つまずいたポイントをできる限り漏らさず記録しています。Nextion Editorを初めて触る方の助けになれば嬉しいです。
この記事で分かること
- Nextion Editorのダウンロード〜新規プロジェクト作成の手順
- フォントを作らないとコンパイルが通らない仕様と、Font Creatorの正しい設定
- 画像(Picture部品)・文字(Text部品)・ボタン(Button部品)の配置方法
- ボタンタッチでダーク/ライトモードを切り替えるスクリプトの書き方
- 作った画面をmicroSDカード経由で実機に書き込む手順
- BH1750のlux値をUART経由でNextionに送信するMicroPythonコード
なお、このNextionディスプレイは、将来作る予定のケーブル切断機のUIとしても使う想定です。今回はその先行検証も兼ねています。
この記事で使う部品(Nextion NX4024T032・Raspberry Pi Pico・BH1750 ほか)
今回の工作で使った部品です。ディスプレイ以外は、これまでのPico記事で使ってきたものと同じ、電子工作の定番パーツです。

UART1本+電源2本をPicoにつなぐだけで、抵抗式タッチ画面が動かせる
Nextion 3.2” TFT 400X240 抵抗式タッチパネル(NX4024T032)
この記事の主役ディスプレイ。専用のNextion EditorでGUI画面を作り、microSDカード経由で本体に書き込みます。Picoとの通信はUART(シリアル)1本で完結し、画像・フォントの管理は本体側で行うため、Pico側のコードはシンプルなままです。




画面サイズ違いのNextionディスプレイもある
今回使ったNX4024T032(3.2インチ)以外にも、Nextionには2.4〜7.0インチまでラインナップがあります。もっと大きい画面で作りたい場合は、下記も候補になります(操作方法は今回紹介するNextion Editorの手順と共通です)。
| サイズ | 購入リンク |
|---|---|
| 2.4インチ | |
| 2.8インチ | |
| 3.5インチ | |
| 4.3インチ | |
| 5.0インチ | |
| 7.0インチ |
※リンクはアフィリエイトを含みます。価格・在庫・同梱内容は変わることがあるので、購入前に各商品ページをご確認ください。
配線図|NextionのUART1とBH1750のI2C0をRaspberry Pi Picoに接続する
BH1750の配線は前回記事とまったく同じです(SDA=GP0・SCL=GP1・VCC=3V3(OUT)・GND)。まだ配線したことがない場合は、先にこちらをご覧ください。
今回追加するのはNextion側の配線だけです。NextionはPicoのUART1(GP4/GP5)とシリアル通信でつながります。信号は3.3V TTLなので、レベルシフタは不要です。
| Nextion側 | Picoの物理ピン | GPIO | 備考 |
|---|---|---|---|
| RX | 6番 | GP4(UART1 TX) | 間に1kΩ直列を入れると保護になる(任意) |
| TX | 7番 | GP5(UART1 RX) | 同上 |
| GND | 18番 | GND | 他の空きGNDピンでも可 |
| 5V | 40番 | VBUS | USB給電時のみ有効。実機組込み時は独立した5V/1A以上の電源を推奨(モーター系のノイズ回避) |
MicroPython側の初期化はこの1行だけです。
from machine import Pin, UART
uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))Nextionのデフォルトボーレートは9600です。
Nextion Editorの使い方|ダウンロードから新規プロジェクト作成(Display direction・Character Encoding)まで
まずは公式ダウンロードページからNextion Editorを入手します。
新規プロジェクトの作成
ここで重要な設定が2つあります。
Display directionは0_Vertical / 90_Horizontal / 180_Vertical / 270_Horizontalの4択から選びます。今回は90_Horizontalを選択します。使用用途に合わせて向きの設定をしてください。
Character Encodingは必ずUTF8を選びます。
0x5C(バックスラッシュ)になる文字(「ソ」など)が、Nextionのエスケープ文字と衝突して文字化けやコマンドエラーを起こす既知の不具合があるためです。フォント作成の手間はUTF8でもShift-JISでも変わらないので、最初からUTF8に統一します。画面構成(4ペイン)
Nextion Editorの画面は大きく4つのペインに分かれています。
左上 Toolbox: 部品パレットです。
- 使える部品: Text / Scrolling text / Number / Xfloat / Button / Progress bar / Picture / Crop / Hotspot / TouchCap / Gauge / Waveform / Slider / Timer / Variable / Dual-state button / Checkbox / Radio / QRcodeなど
- グレーアウトで使用不可: Switch / ComboBox / TextSelect / SLtext / DataRecord / FileBrowser / FileStream / Gmov / Video / Audio / ExPicture
右上 Page: ページの追加・削除・並び替えを行います。
- Add / Delete / Insert / MoveUp / MoveDown / Copy / Import・ExportPage
右下 Attribute: 選択中の部品のプロパティ一覧です。
.txt.pic.font.xcen.ycen.w.h.bco.pco.sta.styleなど
部品の配置・命名
Nextionのフォント作成(Font Creator)|「Invalid Font ID」エラーとSpecified Characterの指定方法
Nextion Editorで最初につまずきやすいのがフォント作成です。新規プロジェクトはフォントが1つも登録されていない状態が初期値で、Text部品を使う場合、最低1つフォントを作らないと以下のエラーでコンパイルが失敗します。
Error:Page:page0 Fail:lux_text.font InputVal Invalid:Invalid Font ID
Error:Compile failed! 1 Errors, 0 Warnings,「コマンドを送ったのに反応がない」系のトラブルとは違い、これはコンパイル自体が止まるので分かりやすいエラーですが、原因(フォント未作成)に初見でたどり着くのは難しいポイントです。手順は以下の通りです。
Font Creator起動直後に、以下を設定します。
- Font source(PC内の任意フォント。今回はArial)
- Height(px、今回32)
- Anti-aliasing(お好みでON)
- Encoding(UTF8)
Rangeは「ASCII Character」「All Character」「Specified Character」の3択です。
0123456789 lxADEGHIKLMNORSTUVWY(数字・スペース・”lx”・ラベル用大文字)。これでフォントサイズは1,066バイト(約1KB)まで激減します。- Rangeで「Specified Character」を選ぶ
- 文字列欄に実際に使う文字を入力する
0123456789 lxADEGHIKLMNORSTUVWY - Font Nameを入力(半角英数字)する
- Generateボタンで
.ziファイルを書き出す
.fontの紐付けをやり直す必要がありません。.txtにセットすると、エラーは出ずに表示が空欄になります。例えば0123456789 lxしか登録していない状態でlux_text.txt="TEST"を送ると、T/E/Sの字形が存在しないため何も表示されません。バグではなく仕様どおりの挙動なので、「コマンドを送ったのに表示が変わらない」ときはまずフォントの文字セットを疑ってください。Text部品の.txt編集方法
Attribute上のtxt行はシングルクリックでは編集不可です。値の部分をダブルクリックするとテキスト入力ダイアログが開きます。
Picture・Text・Button部品の配置|画像Importのサイズ制限「ERROR 1 pieces」とTouch Release Event
Picture部品と画像Import
Picture(.picで画像を丸ごと切り替える)とCrop(1枚の大きな画像から一部を切り出す)は別物です。「lux帯に応じて複数の画像を切り替える」用途はPictureを使います(lux_pic.pic=2のように番号指定で丸ごと差し替え)。
ここで注意が必要なのが画像サイズです。画像サイズが画面解像度(400×240)を超えるとImportが失敗します。エラーメッセージは以下の通りです。
import successfully 0 pieces, ERROR 1 pieces今回は6段階分(0〜5、NIGHT〜OUTDOORのイメージ画像)をImportします。複数枚Importすると、Add順に0,1,2…とリソース番号が振られます。今回使用した6段階のイメージ画像(200×200・24bit無圧縮BMP形式)は以下からダウンロードできます。
6段階イメージ画像をダウンロード(ZIP)Picture部品側では.objnameを分かりやすい名前(lux_pic)にリネームし、.picにリソース番号、.w/.hを画像サイズに合わせて設定します。
.pic欄にリソース番号を設定します。
ここで設定する番号は、ディスプレイ通電時のデフォルト表示に使われる番号なので、1つだけ選択すればOKです。実際に0〜5番の画像を状況に応じて切り替える処理は、後述のPythonプログラム側で指示します。
lux_labelの追加・位置調整・配色
帯ラベル(NIGHT / DIM / HALLWAYなど)を表示するText部品をもう1つ追加します。フォントはlux_textと共通のものを使い回せます。
3つの部品(lux_pic / lux_text / lux_label)の位置・サイズは以下の通り確定させました。画面(400×240)を左右分割し、左に画像、右側にテキスト2段という構成です。
| objname | 種類 | 役割 | x, y, w, h |
|---|---|---|---|
lux_pic | Picture | 帯に応じた画像(200×200、6種) | 10, 20, 200, 200 |
lux_text | Text | lux数値表示(例: “184 lx”) | 220, 80, 170, 80 |
lux_label | Text | 帯ラベル表示 | 220, 175, 170, 50 |
ページ全体の背景色は、キャンバスの何もない場所をクリックして部品の選択を外すと、Attributeにページ自体の.bcoが表示され、そこから変更できます。
Text部品には.sta(背景の塗り方: Solid color / Crop Image / Imageの3択)、.bco(背景色)、.pco(文字色)、.style(枠の立体表現)があります。
lux_labelの.bcoをページ背景と同色、.pcoをアンバー系(R255/G180/B60)に設定します。
.staをSolid colorのまま使い、.bcoをページ背景と同じ色に手動で合わせることで、見た目は透過しているように見せています。Button部品とVariable部品の配置(ダーク/ライトモード切り替えの下準備)
NX4024T032はタッチスクリーン対応ですが、lux表示だけでは無タッチ操作になってしまうため、タッチ操作の実例としてダーク/ライトモードの切り替えボタンを追加しました。Nextion側のみで完結する実装で、Pico側のUART通信・コードは無改変です。
次に、状態管理用のVariable部品(mode_flag)を1つ追加します。画面には表示されません。
最終的な画面レイアウトは以下の通りです(縦方向は上余白15px→Button50px→隙間15px→lux_text 80px→隙間15px→lux_label 50px→下余白15pxで合計240pxちょうど)。
| objname | 種類 | 役割 | x, y, w, h |
|---|---|---|---|
mode_btn | Button | ダーク/ライトモード切り替えボタン | 220, 15, 170, 50 |
mode_flag | Variable | モード状態管理(非表示) | (非表示のため配置不問) |
ダーク/ライトモード切り替えを実装しSimulatorで動作確認する
mode_btnを選択し、上部のEventタブをクリックすると、タッチ操作に対応するイベントスクリプトを書けます。
ここに以下のスクリプトを記述します(実機で動作確認済み)。
if(mode_flag.val==0)
{
page0.bco=65469
lux_text.bco=65469
lux_label.bco=65469
lux_text.pco=6338
mode_flag.val=1
}
else
{
page0.bco=4259
lux_text.bco=4259
lux_label.bco=4259
lux_text.pco=65535
mode_flag.val=0
}Nextionの色指定は8bit RGBではなくRGB565という16bit形式です。カラーピッカー自体は8bit RGB感覚で選べますが、スクリプトで直接指定する場合は以下の変換式で求めます。
RGB565 = ((R>>3)<<11) | ((G>>2)<<5) | (B>>3)lux_labelのアンバー色(R255/G180/B60)はモードを問わず固定でも視認性に問題ありませんでした。注意: .sta=Solid colorの部品は、ページ背景を変えるときに各部品の.bcoも同時に変えないと背景色が浮いて見えます。今回はpage0.bcoと各Textの.bcoを同じ値で同時に書き換えることで対応しています。画像(lux_pic)はダーク背景前提で作成しましたが、ライトモードに切り替えても縁の浮きなど見え方の問題は発生しませんでした(実機確認済み)。Simulator(Debug)での動作確認
画面下部のInstruction Input Areaに、Nextionのコマンドを直接打って実行できます。
- 「Run all commands」ボタンで実行
- 入力形式はString / Hexの切り替えあり
- 文字列コマンドを打つ場合は必ず「String」を選ぶ
実際に使ったコマンド例です。
lux_text.txt="999 lx"
lux_label.txt="NIGHT"
lux_pic.pic=0
lux_pic.pic=1
...
lux_pic.pic=5lux_pic.pic=0〜5を順に送り、6段階の画像が切り替わる様子です。
mode_btnをクリックすると、ダーク⇔ライトが切り替わることも確認できます。
.pic=0が既定値のときに.pic=0を送っても見た目上変化なし。これは正常) ③Instruction Input Areaが「Hex」モードのままだったコンパイルからmicroSDカード書き込みまで|.tftファイルを実機に転送する
Compile成功時のログ例です。
Available Memory:3584
Global Memory:16
Total size of picture:28,824
Total size of font:1,066
Page:page0 Memory Occupied:16+44=60
File Check Finish
Compile Successful! 0 Errors, 0 Warnings,File Size:331,452Total size of picture / Total size of font / File Sizeを見て、使用デバイスのフラッシュ容量(NX4024T032は4MB)に収まっているか必ず確認してください。コンパイル自体はフラッシュ容量オーバーでもエラーになりません(実機書き込み時に初めて問題化します)。.tftファイルの書き出し
microSDカードでの書き込み手順
- Nextion本体の電源をOFF(未給電の状態)
- microSDカードを本体のスロットに挿入
- 電源ON(配線図どおりPico経由でVBUSから5Vを供給、またはUSB経由)→ 自動でアップロード進捗バーが表示され、内蔵フラッシュに書き込まれる
▲ 電源ON直後、アップロード進捗バーが表示され書き込みが進む様子
- 完了したら電源OFF → SDカードを抜く(挿したままだと起動のたびに再書き込みしようとすることがある)
- SDカードを抜いた状態で電源ON → 作った画面が表示されれば成功
MicroPythonでBH1750のlux値をNextionにUART送信する(コード解説)
Pico側のコードです。BH1750からlux値を読む部分は前回記事と同じ実装(0x10連続高分解能モード)なので、詳しい仕組みはそちらをご覧ください。
# nextion-tft001 / nextion-lux.py
from machine import Pin, I2C, UART
import time
# --- BH1750(照度センサー、既存記事 bh1750-lux-meter001 から流用) ---
I2C_ID = 0
SCL_PIN = 1
SDA_PIN = 0
BH1750_ADDR = 0x23 # ADDRピンをGNDに落とした場合。VCCなら0x5C
CONT_H_RES_MODE = 0x10 # 連続・高分解能モード(分解能1lx)
i2c = I2C(I2C_ID, scl=Pin(SCL_PIN), sda=Pin(SDA_PIN), freq=400000)
# --- Nextion(NX4024T032、UART1経由) ---
uart = UART(1, baudrate=9600, tx=Pin(4), rx=Pin(5))
NEXTION_TERM = b"\xff\xff\xff" # Nextionへの文字列コマンドは末尾にこの3バイトが必須
# lux帯のしきい値(上限lux, ラベル)。JIS Z9110の住宅内推奨照度がベース。
LUX_BANDS = (
(2, "NIGHT"),
(30, "DIM"),
(100, "HALLWAY"),
(500, "LIVING"),
(1000, "DESK"),
(65536, "OUTDOOR"),
)
def read_lux():
i2c.writeto(BH1750_ADDR, bytes([CONT_H_RES_MODE]))
time.sleep_ms(180) # 測定完了まで待つ(データシートの最大測定時間180ms)
hi, lo = i2c.readfrom(BH1750_ADDR, 2)
raw = (hi << 8) | lo
return raw / 1.2 # データシートの変換係数でluxに直す
def band_of(lux):
for pic_id, (upper, label) in enumerate(LUX_BANDS):
if lux <= upper:
return pic_id, label
return len(LUX_BANDS) - 1, LUX_BANDS[-1][1]
def nextion_send(cmd):
uart.write(cmd)
uart.write(NEXTION_TERM)
last_pic_id = None
while True:
lux = read_lux()
pic_id, label = band_of(lux)
nextion_send('lux_text.txt="{:.0f} lx"'.format(lux))
if pic_id != last_pic_id: # 帯が変わったときだけラベル・画像を送信(無駄な通信を減らす)
nextion_send('lux_label.txt="{}"'.format(label))
nextion_send('lux_pic.pic={}'.format(pic_id))
last_pic_id = pic_id
time.sleep(1)
ポイントは3つです。
NEXTION_TERM = b"\xff\xff\xff": Nextionへの文字列コマンドは、末尾に0xFF 0xFF 0xFFの終端3バイトを付けないと実行されません。nextion_send()関数で毎回自動的に付与しています。band_of(): しきい値のタプルLUX_BANDSを上から順に見て、lux値が収まる帯のインデックス(=Picture部品の.pic番号)とラベル文字列を返します。Nextion Editor側のlux_picは帯が低い順に0〜5番の画像を登録してあるので、インデックスがそのまま.pic番号として使えます。- 差分送信:
lux_text(数値)は毎秒送りますが、lux_label(ラベル)とlux_pic(画像)は帯が変わったときだけ送信しています。UART通信の回数を減らし、画面のちらつきも防げます。
完成デモ|lux値・ラベル・イメージ画像が連動して切り替わる様子
実機でBH1750に手をかざしたり離したりしてlux値を変化させると、数値・ラベル・イメージ画像が連動して切り替わります。
▲ lux値の変化に応じて画面が切り替わる様子
mode_btnをタッチすると、ダーク⇔ライトモードも切り替わります。
▲ ボタンタッチでダーク/ライトモードが切り替わる様子
よくある質問(FAQ)
Q「Invalid Font ID」エラーでコンパイルが失敗します
AText部品を使う場合、フォントを最低1つ登録する必要があります。新規プロジェクトはフォントが0個の状態が初期値です。Font Creatorでフォントを作成し、Fontsタブに追加してから、対象のText部品の.fontに番号を設定してください。
Qフォントの「All Character」を選んだらファイルサイズが10MB超えました
ANX4024T032のフラッシュ容量(フォント+画像合計4MB)を確実にオーバーします。「Specified Character」を選び、実際に使う文字だけを指定してください。今回の用途なら0123456789 lxADEGHIKLMNORSTUVWY程度で十分です。
Q.txtに文字列をセットしても画面に何も表示されません
Aその文字がフォントの文字セットに含まれていない可能性が高いです。エラーは出ずに空欄表示になる仕様なので、まずFont Creatorで指定した文字列を確認してください。
Q画像がImportできません(ERROR 1 pieces)
A画像サイズが画面解像度(NX4024T032なら400×240)を超えています。事前に400×240以下にリサイズしてからImportしてください。
QSimulatorでコマンドを送っても画面が変わりません
AInstruction Input Areaが「Hex」モードのままになっていないか確認してください。文字列コマンドを打つ場合は「String」モードを選ぶ必要があります。フォントの文字セット不足(前述)も併せて疑ってください。
QSDカード書き込みで”Data Error”が出ます
ANextion Editorをv1.63.3以降に更新するか、USB-TTLアダプタ経由のシリアル書き込みに切り替えると解決することがあります(公式FAQより)。
Q他のNextion機種(2.4インチ・4.3インチなど)でも同じ手順で使えますか
A基本的な操作(新規プロジェクト作成・フォント作成・部品配置・コンパイル・SDカード書き込み)は共通です。画面解像度とDisplay directionだけ、使用する機種に合わせて選び直してください。
QNextion Editorの画面を日本語化できますか
Aエディタ本体のUIは英語固定で、公式の日本語化手段はありません。ただしCharacter EncodingをUTF8にすれば、画面に表示させる文字(Text部品の.txtなど)は日本語で問題なく表示できます。
まとめ
Nextion Editorを使って、Raspberry Pi Pico + BH1750の照度計をタッチパネルディスプレイに表示する工作を作りました。
- フォント作成(Font Creator)は「Specified Character」で必要な文字だけ登録するのが鉄則
- 画像(Picture部品)は画面解像度以下にリサイズしてからImportする
- ボタンのTouch Release Eventだけで、Pico側のコードを変えずにダーク/ライトモード切り替えが実装できる
- Pico側は差分送信の工夫で、UART通信量を減らしつつ滑らかな表示更新ができる
日本語資料が少ない領域だったので、今回の記事がNextion Editorで何かを作りたい方の助けになれば幸いです。このNextionディスプレイは、次に作る予定のケーブル切断機のUIとしても使っていく予定なので、進捗はまた記事にしていきます。
Follow me on X
本ブログの中の人「ニンジン🥕」はXやってます。新着記事はいち早くポストでお知らせしているので、見逃したくない方は @ninjin_py_vba をフォローしてみてください🥕
@ninjin_py_vba をフォローシリーズ記事一覧
電子工作・自動化ツールの製作記録をシリーズごとにまとめています。気になるテーマからお読みください。
-
FILE.01 — IoT
Raspberry Pi Pico W × GASラズパイPico W×GASで自作!「LINEで動く温湿度&スマートリモコン」完全ロードマップ
「外出中のペットの室温が心配…」そんな思いからスタートしたIoT自作プロジェクトの総集編。温湿度監視からエアコン遠隔操作まで、仕組みをゼロから作りたい方のための全5回の開発記録です。
シリーズを読む -
FILE.02 — CNC
Arduino × レーザー刻印CNCCNC自作シリーズ
高精度な加工を目指し、本格的な自作CNC製作に挑戦中。現在は基幹パーツであるオリエンタルモーターの納品を待つ「設計・準備編」を公開。ハードとソフトの両面から、理想のマシンを形にする過程をリアルタイムにお届けします。
シリーズを読む -
FILE.03 — XY軸制御
Raspberry Pi × ステッピングモーターXYテーブルシリーズ
Raspberry Piとステッパモーターを使い、ゼロから2軸制御に挑む記録。OS設定から回路設計、多軸制御のPythonコードまで、躓きやすいポイントを徹底図解。電子工作初心者が「動く感動」を味わうための実戦ガイドです。
シリーズを読む -
FILE.04 — 業務自動化
Python × Excel × CustomTkinter【Python開発記】NINJIN Mail制作記
PythonとExcelを連携させ、実務で即戦力となるメール送信ツールを開発。CustomTkinterによるUI構築や、ミスを防ぐテンプレート活用術など、現場の「痒い所に手が届く」自動化ノウハウを細部まで丁寧に解説します。
シリーズを読む -
FILE.05 — 業務自動化
Python × Excel × GUIアプリ化Invoice Maker(請求書・見積書自動作成)
手作業の請求書作成から卒業!PythonでExcelデータを読み込み一括PDF化する「Invoice_Maker」の作り方を全3回で解説。基本ロジックからGUIアプリ化まで、実務で役立つ自動化ノウハウが満載です。
シリーズを読む



















































































コメント