Quick Reference
There's a more detailed and technical document available online.
Tips & Troubleshooting
- Communication UART (Rx, Tx) can be configured in the System Settings.
- Boot log and debug messages are available on pin GPIO2 (P2) at 115200 baud, 1 stop bit, no parity. Those messages may be disabled through compile flags.
- Loopback test: Connect the Rx and Tx pins with a piece of wire. Anything you type in the browser should appear on the screen. Set Parser Timeout = 0 in Terminal Settings to be able to manually enter escape sequences.
- Use Ctrl+F12 to open a screen debug panel. Additional debugging can be enabled in the Terminal Settings (near the bottom).
- For best performance, use the module in Client mode (connected to external network) and minimize the number of simultaneous connections. Enabling AP consumes extra RAM because the DHCP server and Captive Portal DNS server are started.
- Check that the WiFi channel used is clear; interference may cause flaky connection. A good mobile app to use for this is WiFi Analyzer (Google Play). Adjust the hotspot strength and range using the Tx Power setting.
- Hold the BOOT button (GPIO0 to GND) for ~1 second to force enable AP. Hold it for ~6 seconds to restore default settings. (This is indicated by the blue LED rapidly flashing). Default settings can be overwritten in the System Settings.
Basic Intro & Nomenclature
ESPTerm emulates VT102 (pictured) with some additions from later VT models and Xterm. All commonly used attributes and commands are supported. ESPTerm is capable of displaying ncurses applications such as Midnight Commander using agetty.
ESPTerm accepts UTF-8 characters received on the communication UART and displays them on the screen, interpreting some codes as Control Characters. Those are e.g. Carriage Return (13), Line Feed (10), Tab (9), Backspace (8) and Bell (7).
Escape sequences start with the control character ESC (27), followed by any number of ASCII characters forming the body of the command.
Nomenclature & Command Types
Examples on this help page use the following symbols for special characters and command types:
(spaces are for clarity only, DO NOT include them in the commands!)
Name | Symbol | ASCII | C string | Function |
---|---|---|---|---|
ESC | \e |
ESC (27) |
"\e" , "\x1b" , "\033" |
Introduces an escape sequence. (Note: \e is a GCC extension) |
Bell | \a |
BEL (7) |
"\a" , "\x7" , "\07" |
Audible beep |
String Terminator | ST |
ESC \ (27 92)or \a (7) |
"\x1b\\" , "\a" |
Terminates a string command (\a can be used as an alternative) |
Control Sequence Introducer | CSI |
ESC [ |
"\x1b[" |
Starts a CSI command. Examples: \e[?7;10h , \e[2J |
Operating System Command | OSC |
ESC ] |
"\x1b]" |
Starts an OSC command. Is followed by a command string terminated by ST . Example: \e]0;My Screen Title\a |
Select Graphic Rendition | SGR |
CSI n;n;nm |
"\x1b[1;2;3m" |
Set text attributes, like color or style. 0 to 10 numbers can be used, \e[m is treated as \e[0m |
There are also some other commands that don't follow the CSI, SGR or OSC pattern, such as \e7
or
\e#8
. A list of the most important escape sequences is presented in the following sections.
Screen Behavior & Refreshing
The initial screen size, title text and button labels can be configured in Terminal Settings.
Screen updates are sent to the browser through a WebSocket after some time of inactivity on the communication UART (called "Redraw Delay"). After an update is sent, at least a time of "Redraw Cooldown" must elapse before the next update can be sent. Those delays are used is to avoid burdening the server with tiny updates during a large screen repaint. If you experience issues (broken image due to dropped bytes), try adjusting those config options. It may also be useful to try different baud rates.
UTF-8 support
ESPTerm supports all UTF-8 characters, but to reduce the screen buffer RAM size,
only a small amount of unique multi-byte characters can be used at the same time
(up to 160, depending on compile flags). Unique multi-byte characters are stored in a
look-up table and are removed when they are no longer used on the screen. In
rare cases it can happen that a character stays in the table after no longer
being used (this can be noticed when the table fills up and new characters
are not shown correctly). This is fixed by clearing the screen (\e[2J
or \ec
).
User Input: Keyboard, Mouse
Keyboard
The user can input text using their keyboard, or on Android, using the on-screen keyboard which is open using a button beneath the screen. Supported are all printable characters, as well as many control keys, such as arrows, Ctrl+letters and function keys. Sequences sent by function keys are based on VT102 and Xterm.
The codes sent by Home, End, F1-F4 and cursor keys are affected by various keyboard modes (Application Cursor Keys, Application Numpad Mode, SS3 Fn Keys Mode). Some can be set in the Terminal Settings, others via commands.
Here are some examples of control key codes:
Key | Code | Key | Code |
---|---|---|---|
Up | \e[A , \eOA |
F1 | \eOP , \e[11~ |
Down | \e[B , \eOB |
F2 | \eOQ , \e[12~ |
Right | \e[C , \eOC |
F3 | \eOR , \e[13~ |
Left | \e[D , \eOD |
F4 | \eOS , \e[14~ |
Home | \eOH , \e[H , \e[1~ |
F5 | \e[15 |
End | \eOF , \e[F , \e[4~ |
F6 | \e[17~ |
Insert | \e[2~ |
F7 | \e[18~ |
Delete | \e[3~ |
F8 | \e[19~ |
Page Up | \e[5~ |
F9 | \e[20~ |
Page Down | \e[6~ |
F10 | \e[21~ |
Enter | \r (13) |
F11 | \e[23~ |
Ctrl+Enter | \n (10) |
F12 | \e[24~ |
Tab | \t (9) |
ESC | \e (27) |
Backspace | \b (8) |
Ctrl+A..Z | ASCII 1-26 |
Action buttons
The blue buttons under the screen send ASCII codes 1, 2, 3, 4, 5, which incidentally correspond to Ctrl+A,B,C,D,E. This choice was made to make button press parsing as simple as possible.
Mouse
ESPTerm implements standard mouse tracking modes based on Xterm. Mouse tracking can be used to implement powerful user interactions such as on-screen buttons, draggable sliders or dials, menus etc. ESPTerm's mouse tracking was tested using VTTest and should be compatible with all terminal applications that request mouse tracking.
Mouse can be tracked in different ways; some are easier to parse, others more powerful. The coordinates
can also be encoded in different ways. All mouse tracking options are set using option commands:
CSI ? n h
to enable, CSI ? n l
to disable option n.
Mouse Tracking Modes
All tracking modes produce three numbers which are then encoded and send to the application. First is the event number N, then the X and Y coordinates, 1-based.
Mouse buttons are numbered: 1=left, 2=middle, 3=right. Wheel works as two buttons (4 and 5) which generate only press events (no release).
Option | Name | Description |
---|---|---|
9 |
X10 mode | This is the most basic tracking mode, in which only button presses are reported. N = button - 1: (0 left, 1 middle, 2 right, 3, 4 wheel). |
1000 |
Normal mode |
In Normal mode, both button presses and releases are reported.
The lower two bits of N indicate the button pressed:
00b (0) left, 01b (1) middle, 10b (2) right, 11b (3) button release.
Wheel buttons are reported as 0 and 1 with added 64 (e.g. 64 and 65).
Normal mode also supports tracking of modifier keys, which are added to N as bit masks:
4=Shift, 8=Meta/Alt, 16=Control/Cmd. Example: middle button with Shift = 1 + 4 = 101b (5).
|
1002 |
Button-Event tracking |
This is similar to Normal mode (1000 ), but mouse motion with a button held is also reported.
A motion event is generated when the mouse cursor moves between screen character cells.
A motion event has the same N as a press event, but 32 is added.
For example, drag-drop event with the middle button will produce N = 1 (press), 33 (dragging) and 3 (release).
|
1003 |
Any-Event tracking | This mode is almost identical to Button Event tracking (1002), but motion events are sent even when no mouse buttons are held. This could be used to draw on-screen mouse cursor, for example. Motion events with no buttons will use N = 32 + 11b (35). |
1004 |
Focus tracking |
Focus tracking is a separate function from the other mouse tracking modes, therefore they can be enabled together.
Focus tracking reports when the terminal window (in Xterm) gets or loses focus, or in ESPTerm's case, when any
user is connected. This can be used to pause/resume a game or on-screen animations.
Focus tracking mode sends CSI I when the terminal receives, and CSI O when it loses focus.
|
Mouse Report Encoding
The following encoding schemes can be used with any of the tracking modes (except Focus tracking, which is not affected).
Option | Name | Description |
---|---|---|
-- | Normal encoding |
This is the default encoding scheme used when no other option is selected.
In this mode, a mouse report has the format CSI M n x y ,
where n, x and y are characters with ASCII value = 32 (space) + the respective number, e.g.
0 becomes 32 (space), 1 becomes 33 (!). The reason for adding 32 is to avoid producing control characters.
Example: \e[M !! - left button press at coordinates 1,1 when using X10 mode.
|
1005 |
UTF-8 encoding | This scheme should encode each of the numbers as a UTF-8 code point, expanding the maximum possible value. Since ESPTerm's screen size is limited and this has no practical benefit, this serves simply as an alias to the normal scheme. |
1006 |
SGR encoding |
In SGR encoding, the response looks like a SGR sequence with the three numbers as semicolon-separated
ASCII values. In this case 32 is not added like in the Normal and UTF-8 schemes, because
it would serve nor purpose here. Also, button release is not reported as 11b,
but using the normal button code while changing the final SGR character: M for button press
and m for button release. Example: \e[2;80;24m - the right button was released
at row 80, column 24.
|
1015 |
URXVT encoding |
This is similar to SGR encoding, but the final character is always M and the numbers are
like in the Normal scheme, with 32 added. This scheme has no real advantage over the previous schemes and
was added solely for completeness.
|
Alternate Character Sets
ESPTerm implements Alternate Character Sets as a way to print box drawing characters
and special symbols. A character set can change what each received ASCII character
is printed as on the screen (eg. "{" is "π" in codepage 0
). The implementation is based
on the original VT devices.
Since ESPTerm also supports UTF-8, this feature is the most useful for applications which can't print UTF-8 or already use alternate character sets for historical reasons.
Supported codepages
B
- US ASCII (default)A
- UK ASCII: # replaced with £0
- Symbols and basic line drawing (standard DEC alternate character set)1
- Symbols and advanced line drawing (based on DOS codepage 437, ESPTerm specific)2
- Block characters and thick line drawing (ESPTerm specific)3
- Extra line drawing (ESPTerm specific)
All codepages use codes 32-127, 32 being space. A character with no entry in the active codepage stays unchanged.
Codepage 0
Codepage 1
Codepage 2
Codepage 3
Codepage switching commands
There are two character set slots, G0 and G1. Those slots are selected as active using ASCII codes Shift In and Shift Out (those originally served for shifting a red-black typewriter tape). Often only G0 is used for simplicity.
Each slot (G0 and G1) can have a different codepage assigned. G0 and G1 and the active slot number are
saved and restored with the cursor and cleared with a screen reset (\ec
).
The following commands are used:
Code | Meaning |
---|---|
\e(x |
Set G0 = codepage x |
\e)x |
Set G1 = codepage x |
SO (14) | Activate G0 |
SI (15) | Activate G1 |
Commands: Style Attributes
All text attributes are set using SGR commands like \e[1;4m
, with up to 10 numbers separated by semicolons.
To restore all attributes to their default states, use SGR 0: \e[0m
or \e[m
.
Those are the supported text attributes SGR codes:
Style | Enable | Disable |
---|---|---|
Bold | 1 | 21, 22 |
Faint | 2 | 22 |
Italic | 3 | 23 |
Underlined | 4 | 24 |
9 | 29 | |
Overline | 53 | 55 |
Blink | 5 | 25 |
Inverse | 7 | 27 |
𝔉𝔯𝔞𝔨𝔱𝔲𝔯 | 20 | 23 |
Conceal1 | 8 | 28 |
1Conceal turns all characters invisible.
Commands: Color Attributes
Colors are set using SGR commands (like \e[30;47m
). The following tables list the SGR
codes to use. Selected colors are used for any new text entered, as well as for empty
space when using clearing commands (except screen reset \ec
, which first clears all
style attriutes. The configured default colors can be restored using SGR 39
for
foreground and SGR 49
for background.
The actual color representation of the basic 16 colors depends on a color theme which can be selected in Terminal Settings.
Background image can be set using \e]70;url\a
(see section System Functions).
Foreground colors
Background colors
256-color palette
ESPTerm supports in total 256 standard colors. The dark and bright basic colors are
numbered 0-7 and 8-15. To use colors higher than 15 (or 0-15 using this simpler numbering),
send CSI 38 ; 5 ; n m
, where n
is the color to set. Use CSI 48 ; 5 ; n m
for background colors.
Commands: Cursor Functions
The coordinates are 1-based, origin is top left. The cursor can move within the entire screen, or in the active Scrolling Region if Origin Mode is enabled.
After writing a character, the cursor advances to the right. If it has reached the end of the row, it stays on the same line, but writing the next character makes it jump to the start of the next line first, scrolling up if needed. If Auto-wrap mode is disabled, the cursor never wraps or scrolls the screen.
Legend: Italic letters such as n are ASCII numbers that serve as arguments, separated with a semicolon. If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command.
Movement
Code | Meaning |
---|---|
\e[nA
|
Move cursor up (A ), down (B ), right (C ), left (D ) |
\e[nF
|
Go n lines up (F ) or down (E ), start of line |
\e[rd
|
Go to absolute position - row (d ), column (G ), or both (H ). Use \e[H to go to 1,1.
|
\e[6n
|
Query cursor position. Sent back as \e[r;cR .
|
Save / restore
Code | Meaning |
---|---|
\e[s
|
Save (s ) or restore (u ) cursor position |
\e7
|
Save (7 ) or restore (8 ) cursor position and attributes |
Scrolling Region
Code | Meaning |
---|---|
\e[a;br
|
Set scrolling region to rows a through b and go to 1,1. By default, the scrolling region spans the entire screen height. The cursor can leave the region using absolute position commands, unless Origin Mode (see below) is active. |
\e[?6h
|
Enable (h ) or disable (l ) Origin Mode and go to 1,1. In Origin Mode, all coordinates
are relative to the Scrolling Region and the cursor can't leave the region.
|
\e[nS
|
Move contents of the Scrolling Region up (S ) or down (T ), pad with empty
lines of the current background color. This is similar to what happens when AutoWrap
is enabled and some text is printed at the very end of the screen.
|
Tab stops
Code | Meaning |
---|---|
\eH
|
Set tab stop at the current column. There are, by default, tabs every 8 columns. |
\e[nI
|
Advance (I ) or go back (Z ) n tab stops or end/start of line. ASCII TAB (9) is equivalent to \e[1I |
\e[0g
|
Clear tab stop at the current column (0 ), or all columns (3 ). |
Other options
Code | Meaning |
---|---|
\e[?7h
|
Enable (h ) or disable (l ) cursor auto-wrap and screen auto-scroll |
\e[?12h
|
Toggle cursor blinking (h on, l off) |
\e[?25h
|
Show (h ) or hide (l ) the cursor |
\e[?45h
|
Enable (h ) or disable (l ) reverse wrap-around (when using "move left" or backspace) |
Commands: Screen Functions
Legend: Italic letters such as n are ASCII numbers that serve as arguments, separated with a semicolon. If an argument is left out, it's treated as 0 or 1, depending on what makes sense for the command.
Erasing & Inserting
Code | Meaning |
---|---|
\e[mJ |
Clear part of screen. m: 0 - from cursor, 1 - to cursor, 2 - all |
\e[mK |
Erase part of line. m: 0 - from cursor, 1 - to cursor, 2 - all |
\e[nX |
Erase n characters in line. |
\e[nL |
Insert (L ) or delete (M ) n lines. Following lines are pulled up or pushed down.
|
\e[n@ |
Insert (@ ) or delete (P ) n characters. The rest of the line is pulled left or pushed right.
Characters going past the end of line are lost.
|
Supersized lines
Code | Meaning |
---|---|
\e#1 , \e#2 |
Make the current line part of a double-height line.
Use 1 for the top, 2 for the bottom half.
|
\e#3 , \e#4 |
Make the current line part of a double-width, double-height line.
Use 3 for the top, 4 for the bottom half.
|
\e#6 |
Make the current line double-width. |
\e#5 |
Reset the current line to normal size. |
Other
Code | Meaning |
---|---|
\ec |
Clear screen, reset attributes and cursor. This command also restores the default screen size, title, button labels and messages and the background URL. |
\e[?1049h |
Switch to (h ) or from (l ) an alternate screen.
ESPTerm can't implement this fully, so the original screen content is not saved,
but it will remember the cursor, screen size, terminal title, button labels and messages.
|
\e[8;r;ct |
Set screen size to r rows and c columns (this is a command borrowed from Xterm) |
\e[nb |
Repeat last printed characters n times (moving cursor and using the current style). |
\e#8 |
Reset all screen attributes to default and fill the screen with the letter "E". This was historically used for aligning CRT displays, now can be useful e.g. for testing erasing commands. |
Commands: Networking
ESPTerm implements commands for device-to-device messaging and for requesting external servers. This can be used e.g. for remote control, status reporting or data upload / download.
Networking commands use the format \e^...\a
, a Privacy Message (PM).
PM is similar to OSC, which uses ]
in place of ^
. The PM payload (text between \e^
and \a
)
must be shorter than 256 bytes, and should not contain any control characters (ASCII < 32).
Device-to-device Messaging
To send a message to another ESPTerm module, use: \e^M;DestIP;message\a
.
This command sends a POST request to http://<DestIP>/api/v1/msg
.
The IP address may be appended by a port, if needed (eg. :8080). In addition to POST,
a GET request can also be used. In that case, any GET arguments (/api/v1/msg?arguments
)
will be used instead of the request body. This is intended for external access
when sending POST requests is not convenient.
Each ESPTerm listens for such requests and relays them to UART:
\e^m;SrcIP;L=length;message\a
, with length being the byte length of
message, as ASCII.
Notice a pattern with the first letter: capital is always a command, lower case a response. This is followed with the HTTP commands and any networking commands added in the future.
Example: Node 192.168.0.10 sends a message to 192.168.0.19: \e^M;192.168.0.19;Hello\a
.
Node 192.168.0.19 receives \e^m;192.168.0.10;L=5;Hello\a
on the UART. Note that the IP
address in the reception message is that of the first node, thus it can be used to send a message back.
External HTTP requests
To request an external server, use \e^H;method;options;url\nbody\a
.
method
- can be any usual HTTP verb, such asGET
,POST
,PUT
,HEAD
.options
- is a comma-separated list of flags and parameters:H
- get response headersB
- get response bodyX
- ignore the response, return nothingN=nonce
- a custom string that will be added in the options field of the response message. Use this to keep track of which request a response belongs to.T=ms
- request timeout (default 5000 ms), in millisecondsL=bytes
- limit response length (default 0 = don't limit). Applies to the head, body, or both combined, depending on theH
andB
flagsl=bytes
- limit the response buffer size (default 5000 B). This can reduce RAM usage, however it shouldn't be set too small, as this buffer is used for both headers and the response body.
url
- full request URL, includinghttp://
. Port may be specified if different from :80, and GET arguments may be appended to the URL if needed.body
- optional, separated fromurl
by a single line feed character (\n
). This can be used for POST and PUT requests. Note: the command may be truncated to the maximum total length of 256 characters if too long.
The response has the following format: \e^h;status;options;response\a
status
- a HTTP status code, eg. 200 is OK, 404 Not found.options
- similar to those in the request, here describing the response data. This field can contain comma-separatedB
,H
andL=bytes
andN=nonce
.response
- the response, as requested. If both headers and body are received, they will be separated by an empty line (i.e.\r\n\r\n
). Response can be up to several kilobytes long, depending on theL=
andl=
options.
Example: \e^H;GET;B;http://wtfismyip.com/text\a
- get the body of a web page
(wtfismyip.com is a service that sends back your IP address).
A response could be \e^h;200;B,L=11;80.70.60.50\a
.
Commands: System Functions
It's possible to dynamically change the screen title text and action button labels. Setting an empty label to a button makes it look disabled. The buttons send ASCII 1-5 when clicked. Those changes are not retained after restart.
Single-byte commands & queries
Code | Meaning |
---|---|
CAN (24) | This ASCII code is sent by ESPTerm when it becomes ready to receive commands. When this code is received on the UART, it means ESPTerm has restarted and is ready. Use this to detect spontaneous restarts which require a full screen repaint. As a control character sent to ESPTerm, CAN aborts any currently received commands and clears the parser. |
ENQ (5) | ESPTerm responds to this control characters with an "answerback message". This message contains the curretn version, unique ID, and the IP address if in Client mode. |
\e[5n |
Query device status, ESPTerm replies with \e[0n "device is OK".
Can be used to check if the terminal has booted up and is ready to receive commands.
|
Setting parameters
Code | Meaning |
---|---|
\e[n q |
Set cursor style: eg. \e[3 q (the space is part of the command!).
0 - block (blink), 1 - default, 2 - block (steady), 3 - underline (blink),
4 - underline (steady), 5 - I-bar (blink), 6 - I-bar (steady). The default style (number 1)
can be configured in Terminal Settings
|
\e]0;t\a |
Set screen title to t (this is a standard OSC command) |
\e]27;1;u\a |
Set background image to URL u (including protocol) that can be resolved by the user's browser. The image will be scaled to fit the screen, preserving aspect ratio. A certain border must be added to account for the screen margins. Use empty string to disable the image feature. Note that this won't work for users connected to the built-in AP. |
\e]27;2;n\a |
Set number of visible buttons to n (0-5). To hide/show the entire buttons bar, use the dedicated hiding commands (see below) |
\e]28;x;t\a
|
Set label for button x (1-5) to t - e.g.\e]28;1;Yes\a
sets the first button text to "Yes".
|
\e]29;x;m\a
|
Set message for button x (1-5) to m - e.g.\e]29;3;+\a
sets the 3rd button to send "+" when pressed. The message can be up to
10 bytes long.
|
\e]30;x;c\a
|
Set button x (1-5) color to c - e.g.\e]30;2;#00FF00\a
makes the 2nd button green. Supported are SGR colors 1-255
and TrueColor in the format #RRGGBB . Use 0 to
reset to the default color.
|
\e[?800h |
Show (h ) or hide (l ) the action buttons (the blue buttons under the screen).
|
\e[?801h |
Show (h ) or hide (l ) menu/help links under the screen.
|
\e[?2004h |
Enable (h ) or disable (l ) Bracketed Paste mode.
This mode makes any text sent using the Upload Tool be preceded by \e[200~
and terminated by \e[201~ . This is useful for distinguishing keyboard input
from uploads.
|
\e[12h |
Enable (h ) or disable (l ) Send-Receive Mode (SRM).
SRM is the opposite of Local Echo, meaning \e[12h disables and \e[12l enables Local Echo.
|
Other
Code | Meaning |
---|---|
\e]9;t\a
|
Show a notification with text t. This will be either a desktop notification or a pop-up balloon. |
\e[?ns |
Save (s ) and restore (r ) any option set using CSI ? n h .
This is used by some applications to back up the original state before
making changes.
|
Remote GPIO Control
ESPTerm provides a simple API to remotely control and read GPIO pins GPIO2, GPIO4, and GPIO5. The main use of this API is to remotely reset a device that communicates with ESPTerm through the UART.
GPIO2 is normally used for debug UART, so when used as GPIO, debug logging is disabled. You can configure the pin functions in System Settings.
The GPIO control endpoint is /api/v1/gpio
, with optional GET arguments:
do2=x
- set GPIO2 level. x can be0
,1
, ort
to toggle the pin.do4=x
- set GPIO4 leveldo5=x
- set GPIO5 levelpulse=ms
- the command starts a pulse. After the given amount of time (milliseconds) has elapsed, the pins are set to the opposite levels than what was specified (in the case of toggle, the original pin state)
A quick example: /api/v1/gpio?do4=1&pulse=500
sends a 500ms long positive pulse on GPIO4.
The GPIO endpoint always returns a JSON object like this: {"io2":0,"io4":1,"io5":0}
, showing
the current input levels. Input reading works always, regardless of the GPIO settings.