Full reference: widgets, attributes, scripts, hardware bindings, Arduino, tools, devices, and firmware. Same content as HELP.md. Editor version and release notes: in the app, Help → Changelog (currently 2.16). Community: Discord.
Visual HMI designer for ESP32 displays (Elecrow CrowPanel, Waveshare ESP32 LCDs, generic SPI TFTs, custom boards). Nextion-style widgets and serial language, compiled to .ehmi instead of .tft.
setup()/loop().Open index.html. For Web Serial upload use Chrome/Edge and python -m http.server 8765 then http://localhost:8765/. After code changes: Ctrl+F5.
No paid cloud. You push into a repository you own. GitHub does not store a token you can look up later — you create a Personal Access Token, copy it once, and paste it into the editor. File → Save still downloads a local .hmi.json.
test_esp-hmi.main exists.ESP-HMI Editor. Set an expiration.github_pat_… immediately — GitHub will not show it again.Direct link: github.com/settings/personal-access-tokens
Tokens (classic) → Generate new token (classic) → enable the repo scope → copy ghp_…. That token can access all your private repos; prefer the fine-grained one.
main. Folder = hmi-projects.Repo layout: hmi-projects/untitled/project.hmi.json plus pictures/ and gmovs/.
File → Open from GitHub… → Refresh list → Open. On another PC, paste the same token and repo first.
Test can say “Connected” while Save is refused. Edit the PAT: repository selected, Contents = Read and write, generate a new token, paste it. If the repo has no commits, add a README on GitHub first.
Token is stored only in this browser. Use Forget token on a shared PC.
Toolbox (drag widgets) · Canvas at device resolution · Attributes grid · Pages/Fonts/Pictures/Gmov · Event tabs · Output. Round devices draw a circle; corners of the square buffer are unused on glass.
| Key | Action |
|---|---|
| Ctrl+N / O / S | New v2 / Open / Save |
| Ctrl+Z / Y / D | Undo / Redo / Duplicate |
| Del | Delete widget |
| Arrows / Shift+Arrows | Nudge 1 / 10 px |
| Ctrl+Enter | Compile |
| F5 / F1 / Esc | Simulator / Help / Close dialogs |
Edit → Bring forward / Send backward changes stacking order (who is on top and who gets the touch).
All colors are RGB565 (0–65535): Black 0, White 65535, Red 63488, Green 2016, Blue 31, Gray 33840, Yellow 65504.
| Attr | Meaning |
|---|---|
objname | Unique name on the page. Used in scripts: nTemp.val=24. |
id | Numeric id (read-only). Sent in touch packets. |
x y w h | Position and size in device pixels. Pictures scale with w×h. |
xcen | 0 left, 1 center, 2 right. |
ycen | 0 top, 1 center, 2 bottom. |
vis | 1 show, 0 hide on LCD / Debug. Designer still shows it faded so you can select it. vis bStart,0 |
transparancy (transp) | 0–100. 0 opaque, 100 fully see-through. t0.transp=50. Every widget. |
objname, id, bco (solid color), sta (0 crop / 1 solid / 2 stretch image), pic (background picture id), lock (0 unlocked / 1 locked). A locked page cannot be edited until you unlock it (Pages list button, Attributes, or Edit menu). Click empty canvas to edit the page. page home or page 0 switches pages.
t)A label, not the box you type into. txt string · font · pco text color · bco fill · sta 0 crop / 1 solid / 2 image · style 0 rectangle / 1 rounded / 2 oval / 3 circle · pic / picc background / crop image · isbr wrap · pw password dots.
t0.txt="Hello"
ti)The enter / edit box for the QWERTY keypad and numpad. Drop Text input + a keypad, tap the box, then tap keys. txt typed string · pw 1 password dots.
ti0.txt="" kb0.txt="ti0"
n)val integer · same look attrs as Text · lenth digit width · format 0 dec / 1 hex / 2 HEX.
nTemp.val=186
b)Momentary. txt · pco/bco normal · pco2/bco2 pressed · sta style pic pic2.
bt)Toggle. val 0/1 · txt/txt2 · off colors pco/bco · on colors pco2/bco2 · pic/pic2.
j)val 0–100 · pco bar · bco track · sta/pic.
bat)Charge icon. val 0–100 (or minval/maxval) · pco fill · pco2 low (≤20%) · bco empty · sta 0 crop / 1 solid / 2 image · style 0 icon / 1 icon+%. Example: bat0.val=72.
tw)Rising bars with a network label (same layout as a phone status icon). txt is the label — set 4G, 3G, 2G, 5G, LTE in Attributes. val 0–100 maps to 0–4 bars · pco bars+text · pco2 off bars · style 0 bars only / 1 bars+label. Examples: tw0.txt="5G" · tw0.val=75.
wf)Signal rings. val 0–100 maps to 0–4 rings · pco on · pco2 off · style 0 icon / 1 icon+%. Example: wf0.val=80.
h)val · minval maxval · pco knob · bco track · wid thickness. Example: nSpeed.val=hSpeed.val on Release.
z)val · minval maxval · font value/tick typeface · fco font color · pco needle · bco face · pco2 red zone · wid thickness · style 0 arc / 1 dial / 2 speedometer / 3 half.
c) / Radio (r)val 0/1. Radio: only one on the page stays on.
p)pic resource id · fit 0 stretch / 1 contain / 2 cover. Change at runtime (Nextion): p0.pic=2.
p0.pic=2
hmiSetInt("p0.pic", 2);
Serial.print("p0.pic=2");
Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF);
ic)Small glyph or custom image. Default 32×32 — drag handles to resize. val built-in glyph (0 home · 1 settings · 2 power · 3 play · 4 pause · 5 stop · 6 left · 7 right · 8 up · 9 down · 10 menu · 11 check · 12 close · 13 plus · 14 minus · 15 warning · 16 info · 17 heart · 18 star · 19 bell · 20 lock · 21 user · 22 search · 23 edit · 24 trash · 25 download · 26 upload · 27 clock · 28 mail · 29 light) · pic custom Pictures id (-1 = glyph) · fit 0 stretch / 1 contain / 2 cover · pco glyph colour · sta 3 transparent (default) · style 0 outline / 1 filled · wid stroke px. Tools → Icon Resizer scales a PNG to 16–96 px and can drop it as an Icon widget.
ic0.val=2 ic0.pco=RED icLogo.pic=3
pl)Vertical scrolling list of project pictures (max 32). Import images on the Pictures tab, then drop Picture list from the toolbox. Default name pl0, default ids 0|1|2.
How to use: set ch (count) and txt (pic ids, 0|2|5) in Attributes. gdh row height · wid gap · fit 0 stretch / 1 contain / 2 cover · val selected row. Tick en (auto scroll) to loop continuously · tim ms per pixel (smaller = faster) · dir 0 down / 1 up. Drag to scroll by hand, tap a row to select.
| Command | Meaning |
|---|---|
add pl0,2 | Append picture id 2 |
add pl0,1,5 | Insert picture 5 at index 1 |
del pl0,0 | Remove index 0 |
cle pl0 | Empty the list |
pl0.ch=4 | Set count (pad / truncate) |
pl0.txt="0|2|5" | Replace the whole list |
pl0.val=2 | Select row 2 |
pl0.add=3 | Same as add pl0,3 |
pl0.del=1 | Same as del pl0,1 |
pl0.en=1 | Start auto-scroll (0 stops) |
pl0.tim=25 | Auto-scroll speed (ms / pixel) |
pl0.dir=1 | Scroll up (0 down) |
get pl0.val | Read selected index |
add pl0,2 add pl0,1,5 del pl0,0 cle pl0 pl0.ch=4 pl0.txt="0|2|5|1" pl0.en=1 pl0.tim=25
Serial.print("add pl0,2");
Serial.write(0xFF); Serial.write(0xFF); Serial.write(0xFF);
hmiSetInt("pl0.add", 3);
hmiSetInt("pl0.en", 1);
int sel = hmiGetInt("pl0.val");
m)Invisible hit area (dashed in the editor).
sh)Vector shape. style 0 rectangle / 1 rounded / 2 oval / 3 circle / 4 triangle / 5 diamond / 6 pentagon / 7 hexagon / 8 star / 9 arrow / 10 line / 11 polygon / 12 freehand · sta 0 outline / 1 fill / 2 fill+outline · bco fill colour · pco outline · wid outline px · dir triangle/arrow/line · txt polygon points x,y;x,y (0–1000). Polygon: Draw points then click in the box; Done drawing / Fit to path shrinks the widget box to the drawing. Freehand: click-drag; the box snaps to the sketch on release.
sh0.bco=RED sh0.style=8 sh0.txt="100,200;900,200;500,900"
kb)On-screen keyboard. Tap a Text input, then tap keys. Bottom-left 123 opens digits and symbols; #+= opens more special characters; ABC returns to letters. txt optional pin · val 0 lower / 1 SHIFT / 2 symbols / 3 more symbols · style 0 letters / 1 letters + number row.
np)Numeric keypad. Tap a Number/Text then type, same as QWERTY. Always has a decimal . next to 0. style 0 decimal + backspace / 1 decimal + Enter. Number widgets only accept 0–9; use Text input for decimals.
np0.txt="nTemp"
s)add s0,0,128 · cle s0,0 · ch channels · pco0–3 · gdc grid · bco.
bg)1–10 bars. ch count · val bar 0 · val1–val9 other bars · minval/maxval · dir 0 left / 1 right / 2 up / 3 down · wid gap px · pco0–pco9 bar colors · bco · sta/pic same as other widgets · gdh grid step (0 off) · style 0 rectangle / 1 rounded.
bg0.val=62 bg0.val1=40 bg0.ch=4
cam)Shows JPEG snapshots from a second ESP32-CAM on the same Wi-Fi. Same-chip OV2640 + SPI LCD is not supported (pins and RAM collide).
path e.g. http://192.168.1.20/capture · en 1 run / 0 stop (tap toggles) · tim ms between frames · fit 0 stretch / 1 contain / 2 cover. Set Device → Edit → Wi-Fi SSID / password so the HMI can join the LAN. Then Export + flash, then Upload.
cam0.en=1 cam0.path="http://192.168.1.20/capture"
qr)txt payload · pco/bco ink/paper.
gm)gmov animation id · en play · loop. gm0.gmov=1 · play gm0,1,1.
tm) — not a widgettype 51 · vscope global/local · tim ms · en run. Script goes in Timer Event.
tmPoll.en=1 tmPoll.tim=200
hmiSetInt("tmPoll.en", 1);
hmiSetInt("tmPoll.tim", 200);
int on = hmiGetInt("tmPoll.en");
va) — not a widgetNot drawn. type 52 · vscope global/local · sta Number/String · val or txt. Use from event scripts, Debug, UART, and Arduino.
vaRun.val=1 tStatus.txt=vaNote.txt
hmiSetInt("vaRun.val", 1);
int run = hmiGetInt("vaRun.val");
hmiSetText("vaNote.txt", "ready");
g)Marquee. Same look as Text · dir 0 left / 1 right / 2 up / 3 down · tim ms/step · en run. Long txt stays on one line (no wrap). g0.txt="Alarm…" g0.en=1.
x)Fixed-point. Display is val / 10^vvs1. vvs0 digits before decimal (pad) · vvs1 after. Example: val=1234 vvs1=2 → 12.34.
q)Window into a project picture. pic · cropx / cropy source offset · widget w×h is the crop size. Runtime: q0.pic=2.
tc)Signature pad. Draw in the simulator. pco pen · bco fill · wid width · val stroke count. Clear: cle tc0.
sw)Pill toggle. Press flips val. pco ON track · bco OFF track.
cb)Dropdown. txt items (\r or |) · val selected index. Simulator: click to open, click a row to pick.
ts)Always-open list. txt lines · val index · pco2/bco2 selected row.
sl)Single-line text (no wrap). Same look attrs as Text.
dr)Table / log. path optional file · txt rows · val highlighted row. First line is a header.
fb)path folder header · txt file names · click a row to set val.
fs)Transfer status. path · txt status · en 1 streaming. Click toggles in the simulator; hook real I/O in user_app.cpp.
vd)vid / gmov resource · from 0 resource / 1 file · path URL · en play · loop.
vd0.vid=1
vd0.en=1
play vd0,1,1
hmiSetInt("vd0.vid", 1);
au)vid resource · from · path · en · loop. Nextion: play 0,2,1.
play au0,2,1
au0.en=1
hmiSetText("au0.path", "/sd/beep.wav");
ex)from 0 resource / 1 file · pic id · path URL or /sd/logo.png · fit. Runtime: ex0.pic=2.
+ Pic imports images. Click a thumbnail with a page selected to set the page background; with a text/number/button selected to set pic. Drag onto the canvas to place.
Font Generator (Tools): TTF or system font → bitmap atlas → Fonts tab → set widget font.
Built-in LCD faces (font 0–3) are ASCII only (space through ~). They have no °, µ, or ℃. The firmware draws a small ring for ° / ℃ / ℉ so 24.5°C still looks right. For other symbols, use ASCII (*C, uA) or generate a bitmap font with charset Digits / units (includes ° %).
GMOV Generator: PNG sequence, GIF (Chrome/Edge), or video → frames + delay + loop → Gmov tab → drag onto the canvas.
Icon Resizer (Tools): PNG/JPG → square 16 / 24 / 32 / 48 / 64 / 96 px (keeps transparency) → Pictures, or drop as an Icon widget. Use Image Resizer for full-screen photos.
Tabs: Touch Press, Touch Release, Preinitialize, Timer. One instruction per line. // comments. Autocomplete: Enter/Tab insert, ↑↓ move, Esc close, Ctrl+Space. Compatible with the Nextion instruction set. if/while/for belong in events, not UART. No spaces in parameter lists. Colors: BLACK 0 · WHITE 65535 · BLUE 31 · GREEN 2016 · RED 63488 · GRAY 33840 · YELLOW 65504 · BROWN 48192.
| Instruction | Parameters | Example |
|---|---|---|
obj.attr=value | destination = number, string, color, or another attribute | t0.txt="Hello" · nTemp.val=186 · n0.val=hSpeed.val · b0.bco=RED |
txt+= / txt-= | append string / delete N chars from the end | t0.txt+=" °C" · t0.txt-=4 |
+= -= *= /= %= | integer math on .val | n0.val+=10 · n0.val/=3 |
++ / -- | none | n0.val++ |
&= |= ^= <<= >>= | bitmask or shift count | n0.val&=255 · n0.val<<=1 |
pid = page name or index. Runs Preinitialize.
page home page 0
cid = objname or id. 0 = whole page.
ref t0 ref 0
No parameters. Pause / resume waveform refresh.
cid = name or id. event = 1 press, 0 release.
click bStart,1 click 4,0
cid = name, id, or 255 (all). state = 0 hide on LCD / Debug, 1 show. The designer keeps hidden widgets faded so you can still edit them.
vis bStart,0 vis 255,0
Enable/disable touch. Same cid rules as vis. state 0 off, 1 on.
tsw b0,0
Send to host: 0x70 string or 0x71 int32le. attrib = n0.val, t0.txt, 123, "ok".
get nTemp.val get t0.txt
No parameters. Returns current page id (0x66).
Raw serial, no return header. Strings = ASCII. Numbers = 4-byte LE. length 0 = all.
print t0.txt prints t0.txt,4 prints n0.val,2
Raw hex bytes, space-separated (this command allows spaces).
printh 0D 0A printh 65 00 01 01
No parameters. Pause / resume serial execution; drop the serial queue.
Number ↔ text. Types must differ. length 0 = natural; >0 pads or keeps last N digits.
cov n0.val,t0.txt,0 cov n0.val,t0.txt,4 cov t0.txt,n0.val,0
Same as cov. format: 0 int, 1 commas, 2 hex.
covx n0.val,t0.txt,0,1 covx n0.val,t0.txt,4,2
Copy count chars from src starting at start (0 = first) into dest.
substr va0.txt,t0.txt,0,5
Write string length into a number. ASCII: both are the same.
strlen t0.txt,n0.val
Split src on delimiter key (quoted). Put piece index (0 = first) in dest.
spstr va0.txt,t0.txt,",",0 spstr "ab|cd|ef",t0.txt,"|",2
wave = waveform name or id. channel 0–3. value 0–255 or an attribute.
add s0,0,128 add s0,0,h0.val
Transparent waveform bytes from the host (simulator treats like add).
addt s0,0,20
Clear a waveform channel (255 = all), a TouchCap (cle tc0), or a Picture list (cle pl0).
cle s0,0 cle s0,255 cle tc0 cle pl0
When the first argument is a Picture list (pl0): add pl0,2 appends pic 2 · add pl0,1,5 inserts pic 5 at index 1 · del pl0,0 removes index 0 · cle pl0 empties. Also pl0.ch=4 · pl0.txt="0|2|5" · pl0.val=2 · pl0.en=1 auto-scroll · pl0.tim=25 · pl0.dir=0. On a waveform, add s0,0,128 is still widget, channel, sample.
add pl0,2 del pl0,1 pl0.en=1
Write / read 1 KB EEPROM (RAM in the simulator). Number = 4 bytes LE. String + trailing 0. addr 0–1023.
wepo n0.val,10 repo n0.val,10 wepo t0.txt,20
Run a function from Arduino → Globals (auto-registered on Export). Args: numbers, n0.val, or one "string". int return → sys0.
call startPump call setSpeed,180 call setSpeed,n0.val call sayHello,"HI" call readRaw nTemp.val=sys0
Range for the rand system variable.
randset 1,100 n0.val=rand
rest — reset to page 0. delay=100 — parsed (simulator does not wait). touch_j — calibrate (log only). doevents — refresh inside a loop.
cls BLACK
Filled rect. (x,y) top-left.
fill 20,20,150,50,RED
line 20,30,170,200,BLUE
Hollow rect. (x1,y1) top-left, (x2,y2) bottom-right.
draw 10,10,70,70,GREEN
Hollow / filled circle. Center (x,y), radius r.
cir 100,100,30,RED cirs 100,100,30,RED
pic 10,20,0
Crop w×h at (x,y) from picture picid and draw it there.
picq 20,50,30,20,0
Crop w×h from (srcx,srcy) of picid; draw at (destx,desty).
xpic 20,50,30,20,15,15,0
Draw text in a box. xcen 0 left / 1 center / 2 right. ycen 0 top / 1 center / 2 bottom. sta 0 crop / 1 solid / 2 image / 3 none. text = "OK" or t0.txt.
xstr 10,10,100,30,1,WHITE,GREEN,1,1,1,"OK"
Move widget to (x2,y2). priority 0–100, time ms (runtime jumps to dest).
move t0,0,0,100,80,50,120
Place cid1 above cid2. cid2 = 255 → top.
setlayer t0,n0 setlayer t0,255
Start Audio, Video, or GMOV (Nextion). ch = id or name. loop 0 once / 1 repeat.
play 0,2,1 play au0,2,1 play vd0,1,1
Sets result to 1 if a project picture matches path.
findfile "logo.png",n0.val
Event scripts only. Braces on their own lines. Compare with == != > < >= <=. Join with && || and no spaces.
if(nTemp.val>80)
{
tStatus.txt="HOT"
}else if(nTemp.val<0)
{
tStatus.txt="COLD"
}else
{
tStatus.txt="ok"
}
while(n0.val<10)
{
n0.val++
doevents
}
for(sys0=0;sys0<8;sys0++)
{
n0.val=sys0
}
| Name | Meaning | Example |
|---|---|---|
dim / dims | Backlight 0–100. Widget paths work. dim=0 is off. | dim=40 · dim=hDim.val |
dp | Page index (write changes page) | n0.val=dp |
baud / bauds | UART baud | bauds=115200 |
bkcmd | 0 silent · 1 errors · 2 also OK | bkcmd=2 |
sendxy | 1 = send touch coordinates | sendxy=1 |
sleep / wup / thup | Sleep, wake page, wake on touch | sleep=1 |
rand | Random (after randset) | n0.val=rand |
sys0 sys1 sys2 | Scratch ints. call return → sys0 | n0.val=sys0 |
rtc0…rtc6 | Y M D h m s weekday | nYear.val=rtc0 |
pio0…pio7 / pwm4…pwm7 | GPIO / PWM | pio1=1 |
ASCII command + three bytes FF FF FF.
Serial2.print("nTemp.val=186");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
| First byte | Meaning |
|---|---|
| 0x00 / 0x01 / 0x1A | Bad instruction / OK / bad name |
| 0x65 | Touch: page, component id, 1=press 0=release |
| 0x66 | Current page (sendme) |
| 0x70 / 0x71 | String / int32le from get |
See examples/host_arduino/host_arduino.ino.
F5 / Debug: click widgets, type host commands, watch return codes. Round panels are circular here too.
The instruction terminal sends Nextion ASCII commands (ended with FF FF FF) to the simulator, the LCD (Connect LCD — same COM port as Upload), or both. Tick the checkboxes to choose. get n0.val replies show in the log when the panel firmware includes USB return-code mirroring. Close Arduino Serial Monitor first. Upload disconnects the debug serial session so it can use the port.
Hardware tab: widget ↔ GPIO/sensor on this ESP32. Types: analog, analog map, NTC, digital in/out, PWM, DHT11/22 temp/hum, DS18B20, BME280 (needs Adafruit lib), custom userRead_<name>().
value = raw * scale + offset. A ! on a pin means the LCD already uses it.
hmiSetInt("nTemp.val", t);
hmiSetText("tStatus.txt", "OK");
int speed = hmiGetInt("hSpeed.val");
hmiSetInt("vaRun.val", 1);
hmiSetInt("tmPoll.en", 1);
Export downloads a complete Arduino sketch ZIP. Unzip, open the .ino in Arduino IDE, click Upload.
Timers, variables, and widgets share one path language. Use it in event scripts, the Arduino tab, or UART.
| Path | When | Example |
|---|---|---|
obj.attr | Current page, unique name, or global timer/variable | vaRun.val · tmPoll.en · nTemp.val |
page.obj.attr | Object on another page | home.nTemp.val · settings.hDim.val |
| Command | Example |
|---|---|
hmiSetInt("path", n) | hmiSetInt("vaRun.val", 1); |
hmiGetInt("path") | int run = hmiGetInt("vaRun.val"); |
hmiSetText("path", "s") | hmiSetText("tStatus.txt", "OK"); |
hmiGetText("path") | String s = hmiGetText("vaNote.txt"); |
hmiSetInt("nTemp.val", 24); // Number
hmiSetInt("zTemp.val", 24); // Gauge
hmiSetInt("jLoad.val", 40); // Progress
hmiSetInt("btCool.val", 1); // Dual-state
hmiSetInt("bStart.vis", 0); // hide a widget
hmiSetInt("vaRun.val", 1); // Variable (Number)
hmiSetText("vaNote.txt", "ok"); // Variable (String)
hmiSetInt("tmPoll.tim", 200); // Timer period
hmiSetInt("tmPoll.en", 1); // start timer
hmiSetInt("p0.pic", 2); // Picture resource
hmiSetInt("q0.pic", 1); // Crop source
hmiSetInt("ex0.pic", 3); // ExPicture
hmiSetInt("gm0.gmov", 1); // GMOV clip
hmiSetInt("gm0.en", 1);
hmiSetInt("vd0.vid", 1); // Video resource
hmiSetInt("vd0.en", 1);
hmiSetText("au0.path", "/sd/beep.wav");
hmiSetInt("au0.en", 1);
hmiSetInt("home.nTemp.val", 24); // other page
int t = hmiGetInt("nTemp.val");
int on = hmiGetInt("tmPoll.en");
vaRun.val=1
tmPoll.en=1
tmPoll.tim=200
nTemp.val=24
tStatus.txt="RUN"
vis bStart,0
if(vaRun.val==1)
{
tStatus.txt="RUN"
}
Serial2.print("vaRun.val=1");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Serial2.print("tmPoll.en=1");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Serial2.print("nTemp.val=24");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Serial2.print("p0.pic=2");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Serial2.print("vd0.vid=1");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Serial2.print("play 0,2,1");
Serial2.write(0xFF); Serial2.write(0xFF); Serial2.write(0xFF);
Grouped: Elecrow · Waveshare (including round 1.28 / 2.1 / 2.8C ●) · SPI LCD (ILI9341, ST7789, GC9A01 round, ILI9488, ST7796, custom) · Generic · Custom. Tags show [SPI] or [RGB].
Device → Edit… sets bus, driver, resolution, UART, GPIO, Flash Size, and Partition Scheme (same names as Arduino IDE Tools, including Custom). Custom writes partitions.csv into the Arduino ZIP. RGB 5"/7" leave few free pins. Pin maps were checked against official Elecrow GitHub / Waveshare wiki tables — see HELP.md §15.1. CrowPanel Basic 7.0 uses EK9716BD3 + EK73002ACGB (not generic RGB565; Advance 7.0 is SC7277). -1 means expander or unused, not a GPIO. Do not drive GPIO2 as backlight on Waveshare 4.3/5/7 (that pin is red data).
| Action | Result |
|---|---|
| Compile | Checks names, scripts, bindings, SPI/RGB pins, display/touch drivers, PSRAM |
| Save / Open | .hmi.json source |
| Export | Arduino sketch ZIP. Warns first on wrong pins, incompatible drivers, missing PSRAM, or unsupported touch |
| Export LVGL UI C / toolbar LVGL | UI-only LVGL v9 C ZIP. No firmware. Call ui_init() after your display exists. Version 9.4 / 9.5 / 9.6 |
| Upload | Web Serial UI file (optional after the first flash) |
Unzip → open SketchName.ino in Arduino IDE Libraries: LovyanGFX + ArduinoJson 7.x Board: ESP32 Dev Module or ESP32S3 Dev Module Partition Scheme: Huge APP Upload
The UI is compiled into ui.ehmi on LittleFS (editor Upload). Before Export, the editor lists configuration mistakes (SPI pins vs the preset, RGB on a non-S3, ILI9341 on an RGB bus, XPT2046 without TOUCH_CS, GT911/CST816 without TOUCH_SDA/TOUCH_SCL, flash/PSRAM GPIOs). Device → Edit shows the same check live. RGB panels still need Arduino IDE PSRAM = OPI PSRAM. If Partition Scheme is Custom, the ZIP includes partitions.csv — Arduino IDE Tools → Partition Scheme = Custom.
page home
t0.txt="Hello"
nTemp.val=24
vaRun.val=1
tmPoll.en=1
vis bStart,0
dim=50
if(vaRun.val==1)
{
tStatus.txt="RUN"
}
More detail, firmware API, and limitations: HELP.md in this folder.