Back to Arduino Esp32

Console

docs/en/api/console.rst

3.3.825.5 KB
Original Source

####### Console #######

About

The Console library provides an interactive command-line interface (CLI) for ESP32 applications. It wraps the ESP-IDF console component and exposes an Arduino-style API for registering commands, starting a background REPL (Read-Eval-Print Loop) task, managing command history, and parsing typed arguments using the argtable3 library.

Features include:

  • Background REPL task with configurable stack, priority, and core affinity.
  • Tab completion and inline hints powered by the linenoise library.
  • Persistent command history saved to LittleFS or SPIFFS.
  • Typed argument parsing via argtable3 (integers, strings, optional arguments, etc.).
  • Context-aware command callbacks for object-oriented design.
  • Transport-agnostic: works with UART Serial and HWCDC / USB-JTAG (HWCDCSerial) — the same transport that Serial uses is detected automatically from the ARDUINO_USB_MODE / ARDUINO_USB_CDC_ON_BOOT build flags.

.. note::

The Console REPL currently does not support USB OTG (CDC via TinyUSB / USBSerial). On boards where USB OTG is selected as the Serial transport, the REPL will not receive input. Use UART or HWCDC instead.

Note that some features like history and tab completion are only available on terminals that support VT100 escape sequences. The Arduino IDE Serial Monitor does not support them. If needed, you can use any other terminal that supports VT100 escape sequences, such as PuTTY, Minicom or Picocom. If your terminal prints weird sequences of characters like [5n, it means that the terminal does not support VT100 escape sequences. To disable VT100 escape sequences, you can use the setPlainMode() method and use a plain text mode instead.

The Console library is usable by all ESP32 variants. Depending on how the board's USB and Serial are implemented, you may need to ensure that USB CDC is enabled on boot and use the Hardware CDC. For example, on the most recent ESP32-P4 revisions, you need to enable USB CDC On Boot and set the USB Mode to Hardware CDC and JTAG.

Header File

.. code-block:: arduino

#include <Console.h>

..

Overview

The library exposes a single global object Console of type ConsoleClass.

Typical usage:

  1. (Optional) Call configuration methods such as setPrompt(), setMaxHistory(), and setHistoryFile() before calling begin().
  2. Call Console.begin() to initialize the underlying esp_console module.
  3. Register commands with Console.addCmd() or Console.addCmdWithContext().
  4. Call Console.addHelpCmd() to register the built-in help command.
  5. Call Console.attachToSerial(true) to start the interactive session in a background task.

Alternatively, skip attachToSerial(true) and call Console.run() manually from your own input loop (see the ConsoleManual example).

Two function-pointer typedefs are provided for command callbacks:

.. code-block:: arduino

// Simple callback
typedef int (*ConsoleCommandFunc)(int argc, char **argv);

// Context-aware callback (receives a user-supplied pointer as the first argument)
typedef int (*ConsoleCommandFuncWithCtx)(void *context, int argc, char **argv);

..

Both argtable3 (<console/argtable3/argtable3.h>) and linenoise (<console/linenoise/linenoise.h>) headers are included by Console.h and are directly available in your sketch.

Argument Parsing with argtable3

The Console library re-exports the argtable3 <https://www.argtable.org/>_ C library, which provides GNU-style argument parsing for your commands. Instead of manually parsing argv strings, you declare typed argument descriptors and let argtable handle validation, error messages, and automatic hint generation.

Declaring Arguments


Each argument is created by calling a constructor function. The two most common variants are:

  • arg_xxx1(...)required argument (exactly 1 occurrence).
  • arg_xxx0(...)optional argument (0 or 1 occurrence).

Available types:

.. list-table:: :header-rows: 1 :widths: 25 25 50

    • Constructor
    • Value field
    • Description
    • arg_int0 / arg_int1
    • ->ival[0]
    • Integer (decimal, hex 0x, or octal 0 prefix)
    • arg_dbl0 / arg_dbl1
    • ->dval[0]
    • Double-precision floating point
    • arg_str0 / arg_str1
    • ->sval[0]
    • String (no whitespace unless quoted)
    • arg_lit0 / arg_lit1
    • ->count
    • Boolean flag (no value — presence means true)
    • arg_end
    • (none)
    • Sentinel that terminates the table and stores parse errors

Every constructor takes four parameters:

.. code-block:: c

struct arg_xxx* arg_xxx1(
    const char *shortopts,   // Short option letter, e.g. "p" for -p (or NULL)
    const char *longopts,    // Long option name, e.g. "pin" for --pin (or NULL)
    const char *datatype,    // Placeholder shown in hints, e.g. "<pin>"
    const char *glossary     // Description shown in help text
);

When both shortopts and longopts are NULL, the argument is positional (matched by order, not by a flag).

Building an Argument Table


Group all argument descriptors into a struct that ends with arg_end:

.. code-block:: arduino

// Declare a global struct for the argument table
static struct {
  struct arg_int *pin;     // positional, required: GPIO pin number
  struct arg_int *value;   // positional, required: 0 or 1
  struct arg_end *end;     // must always be last — tracks parse errors
} my_args;

void setup() {
  // Allocate and initialize each argument descriptor.
  // arg_int1: required int arg.  (NULL, NULL) = positional (no -x/--xx flag).
  my_args.pin   = arg_int1(NULL, NULL, "<pin>", "GPIO pin number");
  my_args.value = arg_int1(NULL, NULL, "<0|1>", "0 = LOW, 1 = HIGH");
  // arg_end(N): sentinel — N is the max number of errors to store.
  my_args.end   = arg_end(2);

  // Register the command, passing &my_args as the argtable.
  // The Console library auto-generates the hint string from the table.
  Console.addCmd("gpio", "Write a GPIO pin", &my_args, cmd_gpio);
}

Parsing Inside a Command Handler


Inside the command callback, call arg_parse() to validate the arguments and fill in the values:

.. code-block:: arduino

static int cmd_gpio(int argc, char **argv) {
  // Parse argv against the argument table
  int nerrors = arg_parse(argc, argv, (void **)&my_args);
  if (nerrors != 0) {
    // Print human-readable error messages to stdout
    arg_print_errors(stdout, my_args.end, argv[0]);
    return 1;
  }

  // Access the parsed values through the typed fields
  int pin = my_args.pin->ival[0];   // first (and only) int value
  int val = my_args.value->ival[0];

  pinMode(pin, OUTPUT);
  digitalWrite(pin, val ? HIGH : LOW);
  printf("GPIO %d = %d\n", pin, val);
  return 0;
}

Optional Arguments and Flags


Use arg_xxx0 for optional parameters, and check ->count to see if they were supplied:

.. code-block:: arduino

static struct {
  struct arg_str *ssid;      // required positional string
  struct arg_str *password;  // optional positional string
  struct arg_lit *verbose;   // optional flag: -v / --verbose
  struct arg_end *end;
} connect_args;

void setup() {
  connect_args.ssid     = arg_str1(NULL, NULL, "<ssid>", "Network name");
  connect_args.password = arg_str0(NULL, NULL, "[<password>]", "Password (optional)");
  connect_args.verbose  = arg_lit0("v", "verbose", "Print extra info");
  connect_args.end      = arg_end(3);
  // ...
}

static int cmd_connect(int argc, char **argv) {
  int nerrors = arg_parse(argc, argv, (void **)&connect_args);
  if (nerrors != 0) {
    arg_print_errors(stdout, connect_args.end, argv[0]);
    return 1;
  }

  const char *ssid = connect_args.ssid->sval[0];

  // Check if the optional password was supplied
  const char *pass = (connect_args.password->count > 0)
                     ? connect_args.password->sval[0]
                     : "";

  // Check if the -v / --verbose flag was present
  bool verbose = (connect_args.verbose->count > 0);

  // ...
  return 0;
}

See the ConsoleGPIO and ConsoleWiFi examples for complete working sketches.

Arduino-esp32 Console API

begin


Initialize the console module. Must be called before any other method.

.. code-block:: arduino

   bool begin(size_t maxCmdLen = 256, size_t maxArgs = 32)

..

Parameters

  * ``maxCmdLen`` (Optional)
     - Maximum length of a single command-line in bytes. Default: ``256``.

  * ``maxArgs`` (Optional)
     - Maximum number of whitespace-separated tokens on a line. Default: ``32``.

Returns * true on success; false if esp_console_init() fails.

Notes * Sets up linenoise tab-completion and hints automatically. * Loads history from the file set by setHistoryFile() if one was configured. * Calling begin() again after it has already succeeded has no effect.

end


De-initialize the console module.

.. code-block:: arduino

   void end()

..

Notes * Stops the REPL task if running. * Saves command history to the configured file before freeing resources.

setPrompt


Set the prompt string displayed at the start of each input line.

.. code-block:: arduino

   void setPrompt(const char *prompt)
   void setPrompt(const String &prompt)

..

Parameters * prompt — Prompt string. Default: "esp> ".

Notes * Must be called before begin() to take effect in the REPL task.

setMaxHistory


Set the maximum number of command history entries kept in RAM.

.. code-block:: arduino

   void setMaxHistory(uint32_t maxLen)

..

Parameters * maxLen — Maximum history entries. Default: 32.

setHistoryFile


Set the filesystem and file path for persistent command history.

.. code-block:: arduino

   void setHistoryFile(fs::FS &fs, const char *path)
   void setHistoryFile(fs::FS &fs, const String &path)

..

The method combines fs.mountpoint() and path internally to build the full VFS path used by linenoise for loading and saving history. You only need to pass the filesystem-relative path.

Parameters * path — File path relative to the filesystem root, e.g. "/history.txt".

  * ``fs`` — A mounted Arduino filesystem object.
    Accepts ``LittleFS``, ``SPIFFS``, ``FFat``, etc.

Notes * History is loaded from this file at begin() and saved after every command. * The filesystem must be mounted before begin() is called.

Example

  .. code-block:: arduino

      LittleFS.begin(true);
      Console.setHistoryFile(LittleFS, "/history.txt");

setTaskStackSize


Set the REPL background task stack size in bytes.

.. code-block:: arduino

   void setTaskStackSize(uint32_t size)

..

Parameters * size — Stack size in bytes. Default: 4096.

setTaskPriority


Set the REPL background task priority.

.. code-block:: arduino

   void setTaskPriority(uint32_t priority)

..

Parameters * priority — FreeRTOS task priority. Default: 2.

setTaskCore


Pin the REPL task to a specific CPU core.

.. code-block:: arduino

   void setTaskCore(BaseType_t core)

..

Parameters * core — Core index (0 or 1) or tskNO_AFFINITY. Default: tskNO_AFFINITY.

usePsram


Route all Console PSRAM-eligible allocations to external SPI RAM.

.. code-block:: arduino

   void usePsram(bool enable)

..

When enabled:

  • The esp_console command registry (heap_alloc_caps in esp_console_config_t) is allocated from PSRAM.
  • The REPL FreeRTOS task stack is allocated from PSRAM via xTaskCreatePinnedToCoreWithCaps().

This frees internal SRAM for other uses at the cost of slightly higher latency for stack and heap accesses. Has no effect if PSRAM is not available or not initialized at boot.

Parameters * enabletrue to use PSRAM, false for internal RAM (default: true).

Notes * Must be called before begin() to affect heap allocation, and before attachToSerial(true) to affect the task stack.

Example

  .. code-block:: arduino

      Console.usePsram(true);  // before begin()
      Console.begin();
      Console.attachToSerial(true);

  ..

addCmd


Register a command. Three overloads are available depending on how the hint is provided.

.. code-block:: arduino

   // Auto-generated hint (no hint / hint from argtable)
   bool addCmd(const char *name, const char *help, ConsoleCommandFunc func)
   bool addCmd(const String &name, const String &help, ConsoleCommandFunc func)

   // Explicit hint string
   bool addCmd(const char *name, const char *help, const char *hint, ConsoleCommandFunc func)
   bool addCmd(const String &name, const String &help, const String &hint, ConsoleCommandFunc func)

   // argtable3 argument table (hint auto-generated from the table)
   bool addCmd(const char *name, const char *help, void *argtable, ConsoleCommandFunc func)

..

Parameters

  * ``name`` (Required)
     - Command name as typed at the prompt. Must not contain spaces. The pointer must
       remain valid until ``end()`` is called.

  * ``help`` (Required)
     - Help text shown by the built-in ``help`` command.

  * ``hint`` (Optional)
     - Short argument synopsis shown inline while typing, e.g. ``"<pin> <value>"``.

  * ``argtable`` (Optional)
     - Pointer to an argtable3 argument table (a struct ending with ``arg_end``). The hint
       is generated automatically from the table. The table is only read during registration.

  * ``func`` (Required)
     - Command handler. Receives ``argc`` / ``argv`` where ``argv[0]`` is the command name.
       Return ``0`` for success, non-zero for failure.

Returns * true on success.

addCmdWithContext


Register a context-aware command.

.. code-block:: arduino

   bool addCmdWithContext(const char *name, const char *help,
                          ConsoleCommandFuncWithCtx func, void *ctx)
   bool addCmdWithContext(const String &name, const String &help,
                          ConsoleCommandFuncWithCtx func, void *ctx)

   bool addCmdWithContext(const char *name, const char *help, const char *hint,
                          ConsoleCommandFuncWithCtx func, void *ctx)
   bool addCmdWithContext(const String &name, const String &help, const String &hint,
                          ConsoleCommandFuncWithCtx func, void *ctx)

   bool addCmdWithContext(const char *name, const char *help, void *argtable,
                          ConsoleCommandFuncWithCtx func, void *ctx)

..

Parameters

  * ``func`` — Callback of type ``ConsoleCommandFuncWithCtx``. The ``context`` pointer is
    passed as the first argument on every call.

  * ``ctx`` — Arbitrary pointer forwarded to ``func`` as its first argument.

  All other parameters are the same as ``addCmd``.

Returns * true on success.

removeCmd


Unregister a previously registered command.

.. code-block:: arduino

   bool removeCmd(const char *name)
   bool removeCmd(const String &name)

..

Parameters * name — Name of the command to remove.

Returns * true on success; false if the command was not found.

addHelpCmd


Register the built-in help command.

.. code-block:: arduino

   bool addHelpCmd()

..

When called with no arguments, help lists all registered commands with their hints and help text. When called with a command name (e.g. help gpio), it prints the details for that command only.

Returns * true on success.

removeHelpCmd


Remove the built-in help command.

.. code-block:: arduino

   bool removeHelpCmd()

..

Returns * true on success.

setHelpVerboseLevel


Control the verbosity of the built-in help command.

.. code-block:: arduino

   bool setHelpVerboseLevel(int level)

..

Parameters * level - 0 — Brief: show command name and hint only. - 1 — Verbose: also show the full help text.

Returns * true on success; false if level is out of range.

attachToSerial


Attach or detach the console from the serial port.

.. code-block:: arduino

   bool attachToSerial(bool enable)

..

When enable is true, starts the Read-Eval-Print Loop in a background FreeRTOS task. The task reads input through Serial (bypassing VFS stdin to avoid a race condition with the UART/USB driver ISR) and passes each line to esp_console_run(). Non-empty entries are added to the command history. Because reading goes through Serial, no transport-specific configuration is required — UART and HWCDC work automatically.

When enable is false, stops the background task and frees the serial port for other use.

.. note::

  USB OTG (CDC via TinyUSB / ``USBSerial``) is **not** currently supported as a REPL
  transport.

At startup, the task probes the terminal for VT100 support by sending a one-time Device Status Request (ESC[5n). If the terminal does not respond within 500 ms, plain mode is enabled automatically. Use setPlainMode() before attachToSerial(true) to override the probe result.

Parameters * enabletrue to attach and start the REPL task, false to detach and stop it.

Returns * true on success.

Notes * begin() must be called before attachToSerial(true). * Calling attachToSerial(true) a second time has no effect. * Calling attachToSerial(false) when not attached has no effect.

isAttachedToSerial


Check whether the console is currently attached to the serial port.

.. code-block:: arduino

   bool isAttachedToSerial()

..

Returns * true if the REPL background task is running.

run


Execute a command-line string directly without a REPL task.

.. code-block:: arduino

   int run(const char *cmdline)
   int run(const String &cmdline)

..

Parameters * cmdline — Full command-line (command name followed by arguments).

Returns * The command handler's return code (0 = success). * -1 if the command was not found or an esp_console error occurred.

Notes * run() can be called from inside a command handler to invoke other commands (command composition). However, the underlying IDF function shares a single parse buffer, so the caller's argv pointers are invalidated after the call returns. Copy any argv values you need into local variables before calling run().

    .. code-block:: arduino

        static int cmd_led(int argc, char **argv) {
          // Read argv BEFORE calling run() — it becomes invalid after.
          bool turnOn = (strcmp(argv[1], "on") == 0);

          if (turnOn) {
            Console.run("gpio write 2 1");
          }
          // Do NOT use argv[1] here.
          return 0;
        }

  * History is **not** updated by ``run()``. Manage history manually when building a
    custom input loop (see the ``ConsoleManual`` example).

clearScreen


Clear the terminal screen.

.. code-block:: arduino

   void clearScreen()

..

setMultiLine


Enable or disable multi-line editing mode.

.. code-block:: arduino

   void setMultiLine(bool enable)

..

Parameters * enabletrue to allow the input line to wrap across multiple terminal rows. Disabled by default.

setPlainMode


Enable or disable plain (non-VT100) input mode.

.. code-block:: arduino

   void setPlainMode(bool enable, bool force = true)

..

In plain mode linenoise falls back to basic line input without cursor movement, arrow-key history navigation, or tab-completion rendering. Useful for terminals that do not support ANSI/VT100 escape sequences (such as the Arduino IDE Serial Monitor).

By default, attachToSerial(true) probes the terminal at startup (sending a one-time Device Status Request) and enables plain mode automatically if the terminal does not respond.

Parameters * enabletrue to enable plain mode, false to restore VT100 mode.

  * ``force`` — When ``true`` (default), the automatic VT100 probe at
    ``attachToSerial(true)`` startup is skipped and the mode set here is kept
    unconditionally. When ``false``, the mode is applied immediately but
    ``attachToSerial(true)`` may still override it based on the probe result.

Notes * This wraps linenoise's internal "dumb mode", a legacy term from the era of character-only display terminals. The Arduino API uses the friendlier name.

isPlainMode


Check whether plain (non-VT100) input mode is currently active.

.. code-block:: arduino

   bool isPlainMode()

..

Returns true if plain mode is enabled, either because it was set explicitly with setPlainMode(true) or because the automatic VT100 probe at attachToSerial(true) startup detected a non-VT100 terminal.

Returns * true if plain mode is active, false otherwise.

splitArgv


Split a command-line string into argv-style tokens in place.

.. code-block:: arduino

   static size_t Console.splitArgv(char *line, char **argv, size_t argv_size)

..

Handles quoted strings (spaces preserved, quotes stripped) and backslash escapes. Modifies the input buffer.

Parameters

  * ``line`` — Null-terminated input string, modified in place.

  * ``argv`` — Output array; each element will point into ``line``.

  * ``argv_size`` — Size of the ``argv`` array. At most ``argv_size - 1`` tokens are
    returned; ``argv[argc]`` is always set to ``NULL``.

Returns * Number of tokens found (argc).

Example

  .. code-block:: arduino

      char line[] = "gpio write 5 1";
      char *argv[8];
      size_t argc = Console.splitArgv(line, argv, 8);
      // argc == 4, argv[0]=="gpio", argv[1]=="write", argv[2]=="5", argv[3]=="1"

  ..

Examples

ConsoleBasic


Full interactive REPL with history, tab completion, and inline hints.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleBasic/ConsoleBasic.ino :language: arduino

ConsoleManual


Manual command execution from a custom input loop in loop(), without a background task.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleManual/ConsoleManual.ino :language: arduino

ConsoleSysInfo


System information commands: uptime, heap, tasks, version, restart.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleSysInfo/ConsoleSysInfo.ino :language: arduino

ConsoleFS


File system CLI over LittleFS: ls, cat, rm, mkdir, write, df.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleFS/ConsoleFS.ino :language: arduino

ConsoleGPIO


GPIO control with argtable3 argument parsing: gpio read, gpio write, gpio mode. LED control is supported with the led command on boards with a built-in LED.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleGPIO/ConsoleGPIO.ino :language: arduino

ConsoleAdvanced


Demonstrates advanced APIs: context-aware commands (addCmdWithContext), dynamic command registration and removal (removeCmd), REPL pause/resume (attachToSerial(false/true)), help verbosity (setHelpVerboseLevel), clearScreen, setPlainMode, setMultiLine, and task tuning (setTaskStackSize, setTaskPriority, setTaskCore).

.. literalinclude:: ../../../libraries/Console/examples/ConsoleAdvanced/ConsoleAdvanced.ino :language: arduino

ConsoleHistory


Persistent command history across reboots using LittleFS (setHistoryFile), PSRAM allocation (usePsram), and the splitArgv tokenising utility.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleHistory/ConsoleHistory.ino :language: arduino

ConsoleWiFi


Wi-Fi management: wifi scan, wifi connect, wifi disconnect, wifi status, wifi ping.

.. literalinclude:: ../../../libraries/Console/examples/ConsoleWiFi/ConsoleWiFi.ino :language: arduino