# Development/debugging tool for ESP32

**URL:** <https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200>\
**Category:** Libraries\
**Created:** [September 16, 2024, 3:53pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200 "2024-09-16T15:53:58Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [September 16, 2024, 3:53pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/1 "2024-09-16T15:53:58Z")

</div>

Hello,  
Here is a shell for ESP32 cpu: [GitHub - vvb333007/espshell: Command line interface debug tool for Arduino projects on ESP32 hardware](https://github.com/vvb333007/espshell)  
~~Single .c file which can be placed to the directory where your .ino script is to add interactive shell (CLI) to your sketch. No modification to the sketch is needed: the espshell.c will gain control automatically.~~

A library, which hooks up on a startup process and gains control at the very beginning to start a CLI on serial interface.

Once uploaded it creates a command line interface on UART0 which can be accessed either via Arduino IDE Serial Monitor or, much better, via terminal software (PuTTY, TeraTerm etc)

Tried to mimic Cisco's CLI look & feel 🙂

There is README.md file with a little bit more details and examples.

If anyone will find it useful - i would like to get a feedback.  
Enjoy!

Commands:

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/f/3/f/f3ff0c2120ea2b752db42801d052bd41ae36aba4.png)

i2c scanning / reading / writing :

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/2/b/1/2b146b52d8d9bf6b6034d0ebfeb5e247f07555fd.png)

Sequence generation (using RMT pereipherial)

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/9/a/9/9a9aa5610b1cd6c8e8fdfcb32594b5c475a00124.png)

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [January 23, 2025, 2:11pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/2 "2025-01-23T14:11:08Z")

</div>

We are progressing 🙂 for last few months a few updates were made:

1. filesystem support (flash and SD (over SPI)) , FAT, LittleFS and SPIFFS  

2. Sketch variables support (accessing sketch variables from the shell)  

3. Frequency meters / Pulse counters (up to 8 on ESP32 or up to 4 on S3)

4. Commands can be executed in background by adding "&" at the end of the command line (just like in linux/bash)

5. Context help hotkey ("?")

6. Ctrl+C pauses sketch execution (can be resumed with command "resume")

7. Sketch variables can be **registered** so they become available for the shell commands:

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/0/9/d/09d1788663817fe5e9fb4126d4099a502246b57d.png)

Too many changes to list them all. File size grew to 300kb and then I decided to split it and make a library. So I did :). It is now available through Arduino IDE Library Manager, search for "ESPShell".

It works on generic ESP32 boards, ESP32-S3 boards and ESP-CAM as well. It would be good to know if it compiles/works on other Espressif MCUs.

ESPShell expects "Serial" to be of class "HardwareSerial" . No USB-CDC console support yet :-/

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [March 12, 2025, 4:32pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/3 "2025-03-12T16:32:36Z")

</div>

Yes, finally added support for Hardware CDC boards.

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [May 20, 2025, 5:22am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/4 "2025-05-20T05:22:17Z")

</div>

Documentation, alpha version 🙂

> **[ESPShell : Documentation Index](https://vvb333007.github.io/espshell/html/index.html)**

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 10, 2025, 11:13am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/5 "2025-08-10T11:13:36Z")

</div>

How many tasks do you need to run the shell? Not so many: IDLE0 and IDLE1

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/0/e/e/0ee4cfbd6261e3c84f69a857ead49cfabaa4ffdb.png)

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [August 10, 2025, 11:29am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/6 "2025-08-10T11:29:36Z")

</div>

How about adding some sort of identifier to the prompt in case we want to work with 2 or more at a time. Maybe chipid?

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [August 10, 2025, 11:31am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/7 "2025-08-10T11:31:12Z")

</div>

Is it possible to display task info?

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 10, 2025, 3:07pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/8 "2025-08-10T15:07:09Z")

</div>

Technically, yes, however it is not so much of useful info there: stack pointers, ticks etc. So I decided just to display task address (handle), its priority and name.

Yes I think I would add ability to change default “esp32“ in the prompt to user-defined prompt.

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 10, 2025, 3:12pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/9 "2025-08-10T15:12:30Z")

</div>

Messy screenshot.

Creating “rising“ and “falling“ conditions and actions. Creating periodic events.

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/8/6/0/86067a20eb3cfed8f2bae1aef228693b07474663.png)

Started a doc for this feature, [Aliases and Events : creating and executing shell scripts](https://vvb333007.github.io/espshell/html/Aliases_And_Events.html) but it is far from being finished :D. Writing documentation is harder than writing code.

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 11, 2025, 8:18am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/10 "2025-08-11T08:18:24Z")

</div>

Like this? HighWM == High Water Mark. The close it to zero, the higher chances to see Guru Meditating

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/1/5/0/15022d4f5f07963fdd9c5335dfc40722f92dd2fb.png)

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 11, 2025, 8:40am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/11 "2025-08-11T08:40:54Z")

</div>

IO MUX.

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/b/d/9/bd954e015ecc5c73e3cdb75b981fb2b03b1f3f4f.png)

It is all configurable, I mean, every GPIO can be reassigned to any IOMUX or GPIO matrix function. For GPIO matrix one can connect IN/OUT signals also. Virtual pins (constant 1 and constant 0 are also supported :). to some extent)

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 12, 2025, 6:03pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/12 "2025-08-12T18:03:12Z")

</div>

Like this?

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/8/b/4/8b4bfbdc065867e77aae772fb9165ad3124573aa.png)

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [August 12, 2025, 6:52pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/13 "2025-08-12T18:52:14Z")

</div>

Looks good, but I was hoping the board id/name could be stored on the board.  
Let me try to explain better.  
I am assuming what I am seeing is from a sketch that somehow stays resident or a new bootloader.  
When that ^^ is created/uploaded an identifier is assigned although I don;t understand why ChipID can't be used somehow.  
The utility of this is when I have a handful of boards in a drawer, I hook up the board and the first prompt from the board (and all others) is prefaced with the unique ID so I know I have the board with the XYZ sketch loaded.  
Am I clear?

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 12, 2025, 7:09pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/14 "2025-08-12T19:09:16Z")

</div>

I will think on how to do it better :). I got you. May be EEPROM emulation area on the flash is good place to store ESPShell settings.

---

<div class="post-metadata">

**Author:** ![sonofcy](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/sonofcy/32/1283617_2.png) [@sonofcy](https://forum.arduino.cc/u/sonofcy)\
**Post date:** [August 12, 2025, 7:28pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/15 "2025-08-12T19:28:44Z")

</div>

Consider that a user of your tool may inadvertently overwrite that area. Maybe also look at the partition feature?  
I looked at the chip ID and it only uses the low-order 31 bits and is therefore not unique.

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [August 12, 2025, 7:33pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/16 "2025-08-12T19:33:32Z")

</div>

> [@sonofcy](#):
>
> overwrite that area.

at the end of “nvs“ area.

accessing user partitions, storing files there is not good.

having a separate partition just for the library is too much. let it be last 64 bytes of NVS

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [November 28, 2025, 3:12pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/17 "2025-11-28T15:12:46Z")

</div>

Github main (not in the releases section yet):

WiFi support added. Coexists with sketches that use the ESP32 WiFi library. In particular - can reconfigure WiFi in runtime from the command line while sketch is running. Two interfaces supported: AP and STA. Configuration somehow mimics Cisco shell:

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/1/1/3/11392794dabd664862ebb300ff4e26f96f6a1b2e.png)

Can be configured as WiFi extender. Here is the screenshot of my laptop connected to internet through my esp32 dev board

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/2/4/7/247b5ad2d0de07a7a71401b02eb20609d5bf3e7c.jpeg)

Time support has been added, including timezone and NTP. Timezone is saved to NVS so after reset the system time is correct.

 ![time_ntp](https://europe1.discourse-cdn.com/arduino/original/4X/b/d/5/bd5ab007c2a647c137f51502f2727bd25d091ebd.jpeg)

PS:

oh yes, **hostid** has been added also, stored in the NVS

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [December 3, 2025, 11:13am UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/18 "2025-12-03T11:13:23Z")

</div>

I’ve added an NVS editor (the part that, in the Arduino framework, is handled by the EEPROM class and similar things — including Preferences library).

You can browse NVS as if it were a file system: there are commands like `ls`, `cd`, `rm`, etc.

When you enter the `nvs` command, you’re taken into the editor.

In the screenshot you can see the list of namespaces and the list of key=value pairs.

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/2/0/e/20ed1b9b96218a9e612627a307b27234380bac1a.png)

This is what the WiFi driver stores:

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/f/3/5/f354ee91a4a13ce16d7f70e3fdfa7064586d9af0.png)

Including passwords! 🙂

 ![image](https://europe1.discourse-cdn.com/arduino/original/4X/f/a/9/fa9ae5ea03b3b40b1b1d3807cf993902e6cc6cb7.png)

You can add, delete, and modify values. You can save the entire NVS image as a binary file, or export it as CSV. Later, you can load .bin/import .csv back again.

Not on the Github yet. Polishing :)

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [December 9, 2025, 5:17pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/19 "2025-12-09T17:17:37Z")

</div>

0.99.12 released.

---

<div class="post-metadata">

**Author:** ![vvb333007](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/vvb333007/32/974521_2.png) [@vvb333007](https://forum.arduino.cc/u/vvb333007)\
**Post date:** [March 13, 2026, 1:24pm UTC](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200/20 "2026-03-13T13:24:49Z")

</div>

I’ve added the ability to create variables and associate them with arbitrary memory locations.

Regular sketch variables can already be read and written using shell commands (I posted examples somewhere above). But writing to an arbitrary memory address directly wasn’t something I had implemented before — I didn’t really know how to approach it.

Now I’ve figured out a way to do it.

For example, suppose we want to access memory at address `0x3fce4000` as if it contained an `unsigned int`. And we also want to access memory at `0x3fce4004` as if there were an array of 64 `unsigned int`.

We simply create two variables: `foo` and `bar`:

 ![1](https://europe1.discourse-cdn.com/arduino/original/4X/d/1/7/d1713539a132c2f21bc1d09d7bb08eca019d52e0.jpeg)

Now we can read the value in memory as if it were a variable. We can also modify it using the same shell commands. For example, print the current value, change it to 10, and verify that it was written correctly:

 ![2](https://europe1.discourse-cdn.com/arduino/original/4X/b/6/d/b6de8dc59d29dce7172a0fc57806c57762663e31.jpeg)

And here is our array, variable `bar`. Access to individual elements works exactly the same as before:

`var bar[666] 10` → sets element 666 of the array to the value `10`.

 ![3](https://europe1.discourse-cdn.com/arduino/original/4X/c/6/5/c6597dff9fb52914a70b993a2c0d350b87cbfe16.jpeg)

The following types are supported:

- scalar types (`uint16_t`, `signed short int`, `unsigned long`, etc.)
- pointers (`signed short *`, for example)
- arrays (`int []`)
- arrays of pointers (`void * []`, etc.)

and similar combinations.

Why did I implement this?

Right now I’m digging around in various structures in memory (WiFi driver internals). These structures are meaningful data structures, not just a raw byte dump, and I wanted to be able not only to view memory as C types but also to write to it.

And to do that without worrying about byte order and similar details.

For example, you could map variables onto the UART registers and read/write them as if they were an array.

There are still some small bugs showing up here and there, but I think I’ll polish it up soon and commit it.

[Next page](https://forum.arduino.cc/t/development-debugging-tool-for-esp32/1302200.md?page=2)
