Labels

Wednesday, 4 November 2026

ESP32 Telnet

ESPTelnet

After successfully investigating SSH terminal access to ESP32 and recognising that SSH security is complex and not required for my purposes I decided to try telnet.

Google gives some choices for a telnet server, I chose to install ESPTelnet


As this is back in Arduino land testing becomes easier.  I simply installed ESP Telnet library by Lennart Hennings and found in the examples "TelnetServerExample.  After uploading I see console messages to show that Telnet is up and running.  I can then Telnet in from my PC.  As usual there are not much of a shell provided, text typed in is echoed. Input from the client is processed by a function "onTelnetInput" which has a couple of commands "ping" and "bye".
 


I want to run programs on my ESP32 as well as controlling / monitoring it through remote access.  To test this I added a simple blink program to the example. When ESP32 is started the system LED is turned on/off each second.  The sketch works fine.  The only snag is that Telnet response drops.  When you type something you have to wait about 10s for a response.  The blink loop repeats every two seconds meaning the telnet loop can only work between loops.  Clearly the loop() function cycle time needs to be kept short to allow telnet processing.  For example a non-blocking version of blink would  need to be written.

Google Telnet

I googled "esp32 remote terminal" to identify potentially useful resources.  Google AI came up with an informative answer.  When I clarified my request it gave me a complete program!

I couldn't resist taking Google up on its offer. I copied code into a sketch entered my user/password and compiled it.  It didn't require installation of libaries and did exactly what I wanted!

Async Telnet

It is very pleasing to setup a telnet server with so little effort.  To be a practical tool, telnet needs to interfere as little as possible with useful work, the job for which we are using ESP32.  To do this we need non-blocking code, in practice this means we shouldn't need to include telnet commands within arduino loop() function.  Telnet functions should be invoked when needed using callback functions.

"Async Telnet for ESP32" by Frank Boesing seems to be perfect.
  

I copied source code snippetes into a sketch, added wifi initialisation code to setup() built the sketch and it worked.  I see a console message "Telnet server active" and I can telnet into ESP32 from a WSL command prompt.
By default the sketch is setup as a "log server" where communication is one way, so that ESP32 can transmit information to the telnet client.  Once I enabled the "handle incoming data" variable anything typed on Telnet client was returned to ESP32 and handled by a callback function.  Typically, this function will allow commands to be transmitted to ESP32 for control purposes.

Outro


AsyncTelnet gives me a much easier, appropriate solution to my desire for remote access.  It can be implemented without obstructing other software running on ESP32 and should be part of my overall ESP32 remote access objective.

I did have one problem getting AsyncTelnet code to work which led to my first productive use of AI which I will write about next.


Sunday, 1 November 2026

ESP32 SSH

breezy_ssh

My breezybox project provided me with a terminal shell for ESP32 through a PC USB COM port complete with unix-style commands.  This was a very good start but I really want remote access to ESP32 which would give me freedom to connect from various devices and wouldn't require the ESP32 device to be attached to my PC.

Breezybox has an additional component called breezy_ssh which implements an SSH server alongside breezybox to meet this requirement.  Building on knowledge gained from the breezybox install breezy_ssh installation was very straightforward (it was a breeze ;)).

I downloaded an example provided by Valentin Danylchuk which included an sdkconfig and partition table.  After a little tweak the build was successfully flashed to ESP32-S3 and started up. Using the serial console I could see that breezybox was working and I could use the file system as previously.  In addition there was a prompt to start the ssh server.

The first action is to connect to wifi ("wifi connect") and bring up the ssh server ("sshd start").  I could then start an ssh client session on the PC😊😊.

Using breezy_ssh

The SSH client session works much better than a serial console.  I/O redirection works so I can echo text and redirect (">") it to a file.  wget is now working so I can download files using http.  vi works so I can edit files locally.  This gives me everything I need to set up a simple web site, just containing an index.html file.  I then start a web server ("httpd web") and access it from my browser.

The "big picture" below shows COM ports, serial console, ssh session and web access.


One downside with breezy_ssh is that I need to use the serial console to start wifi and ssh.  Generously, Valentin does provide the ability to run shell scripts and a script "init.sh" is executed when you start up.  Unfortunately the script didn't work for me when I put "wifi connect" in init.sh, so I have to start it manually.  With further effort I could probably arrange for wifi and sshd to start within the program or diagnose how to make init.sh work.

libssh

I felt breezybox + breezy_ssh looked a bit complicated for my needs and wanted to look at alternatives.

libssh, written by David Cermak, is the ssh library for ESP32 IDF and is used within breezybox. I decided to test the example he provides (esp_ssh).  Initially I tried to use IDFv6 both VSC and CLI versions.  Surprisingly it wouldn't compile.  I found this is due to "breaking changes" introduced between ESPv5 and ESPv6.  David does provide a "Shim" to enable libssh to work with IDFv6 but I didn't have much success with it.
Instead I used IDFv5 to and the libssh example builds and flashes without problems. I can start ESP32S3, wifi and ssh server are started automatically.  I can ssh in from WSL or Putty, which works better.  Any text typed into SSH client is echoed on the serial console. There are only three command reset, hello (hello world message) and exit.

The example is much simpler than breezybox which is good.  Naturally it has less functionality and I would need to write my own terminal shell.  

Libssh is the base library used for ssh on ESP32 with IDF and therefore the simplest possible implementation.  Looking at the source code I see that there is much complexity to deal with ssh authentication, creating and checking keys etc.  

For my purposes I don't actually need any security as I only intend to use CLI access on the local network.  This thought leads me to try telnet access in the next stage of my investigation.

 


Breezybox Terminal

 Rationale

The idea of running a terminal shell on an ESP32 appeals to me.  Normally you download a program to ESP which then does what it has been instructed in the source code.  Input and output are either carried out through peripherals (buttons, keypad, OLED screen, LEDs, etc.) or a web page which is built to display results or accept instructions (buttons, text boxes etc).

A terminal shell allows typing inputs on a keyboard and showing outputs on a screen.  You can run a command and display results using a Command Line Interface (CLI).  I have used CLI for over 40 years and it makes me feel I have a real computer under my control rather than pre-programmed hardware.

Previously I have tried out Shellminator on an ESP32-C3.  However, I am interested in using Breezybox which has many more capabilities including a file system, together with associated commands, and SSH access.

ESPShell

I purchased an ESP32-S3 N16R8 for the new project.  Although most current ESP32 models are RISC-V, ESP32-S3 runs more powerful Xtensa cores.  This model comes with an extra 8MB PSRAM (pseudo-static RAM, memory contents are preserved when powered off) and 16MB flash memory.  It has no SD card or screen.

As a first test, before working on Breezybox I tried ESPShell.  Installation is as simple as installing the library and adding the header ("#include espshell.h") to your Arduino sketch.  There is no need to amend setup() or loop() functions!  Results are very impressive, a set of commands to tell you about your system.  Arduino serial monitor doesn't display well so a TeraTerm session is preferred. It gives a lot more information than Shellminator.


Breezybox Headaches

Although ESPShell is very good I would like to try the Unix like interface, SSH access and other features available on Breezybox.


In contrast to ESPShell, breezybox required plenty of time and patience.  It hasn't been developed for Arduino meaning I had to use the more complex/advanced/complete ESP-IDF environment.

At first I had no success, I could not build an image either using ESP-IDF CLI or VSC (Visual Studio Code).   Firstly there were errors mainly relating to "json" not found which I circumvented.  Then came "usb_serial_jtag not found" errors.

Eventually it occurred to me that I am using a recent major new version ESP-IDF v6.0.1.  Perhaps  Breezybox had been developed using IDF v5.  It turns out there are major "breaking" changes in the new IDF version.  I installed IDF v5.5.5 which was the last one before IDF v6 and the breezybox build worked.

Breezybox Build

In fact, with the correct environment, installation and build are incredibly easy using the ESP-IDF framework.



Although the build was successful, I had more work to do using "IDF menuconfig" to configure appropriate options.

The image was bigger than the default 0x100000.  So we need to add a partitions.csv file which gives us 0x2000000 in the "factory partition".


Next I had to configure 16MB RAM
Finally I had to configure the USB COM port to be used as the system console.

At last I have a working image.




















Using Breezybox

Breezybox has its own virtual filesystem in Flash memory.  Its initial size is 1.5M.  The only file existing initially is "init.sh" which echoes a message "Welcome to Breezybox".  A set of commands  is provided to manage files.  
Other useful shell commands are also provided for system status, networking.
More interestingly there is a command "httpd" to start a web server and "eget" to download executable apps to the system.



Adding memory


The first thing we want to do is use eget to download some apps to provide us with extra functionality.  Unfortunately the system is severly memory constrained.  We only have 300k SRAM (static RAM) available.
The solution is to configure to configure our 8MB PSRAM for our use.  In menuconfig we enable PSIRAM.  It happens that our PSRAM is "Octal" which also needs to specified.



Now when the image is rebuilt we have 8MB PSRAM available.


Now we can download apps from valdanylchuk/breezybox.   The ones I want to use are wget (to download files via http) and vi (to edit files locally).  Unfortunately neither appear to work on the serial console.  In addition I/O redirection wasn't working for me, so I had no way of creating webpages so that I could bring up the web server (httpd).

Instead I tried adding a custom command to breezybox source code.  This was a very helpful example as  it worked straightaway and showed me how to register an ESP console command so that it can be used on the command line.

Outro

At this stage I have working breezybox environment although it is not fully functional through the serial console.
A lot of progress has been made, with Google's help, in understanding my ESP32S3 N16R8 system memory/flash and how to use IDF menuconfig.

It is rewarding to understand the complexity of ESP-IDF a little bit more.  It also helps me appreciate the magic which Arduino does to hide/disguise most of this to give casual users the ability to build ESP32 images.

I don't really want to use a serial console to control ESP32, I would like a remote console.  Breezybox provides a component breezy_ssh which provides an ssh server and allows standard access over wifi.  This is the next area to test.



Saturday, 3 October 2026

ESP32-C3 OLED : Monitor

 Intro

Very occasionally I have connectivity problems at home and it can be hard to work out where the problem lies.
If I cant view a webpage from my PC, is the PC misbhaving or the router or a website?
If I cant play music, is my music server misbehaving, is the hifi off line or is wifi not available?



C3-OLED is a tiny board measuring 3cm x 2cm.  In addition to ESP32 wifi it has a little (72x40 pixel) OLED screen.
Since C3-OLED can work independently of any other hardware it can test connectivity by pinging other systems and display abbreviated results on the screen.

Design

This first version is simple; it connects to wifi then pings my home (always on) Raspberry Pi servers and finally checks that my websites on the internet are accessible.

At each stage it prints brief results.

Software

Programming is straightforward.
I use the standard Arduino ESP32 wifi library and example wifi connection sketch.
I use a simple library ESP32Ping for connectivity tests.
The C3-OLED uses a library called U8g2 and the ebay vendor (Brightsparks) kindly provided a working sample OLED sketch.

I combine three example sketches to:
 * connect to wifi and show the assigned IP address
 * ping local servers and show how many were accessible
 * ping internet sites and show how many were accessible

The OLED screen (72 x 40 pixels) is small to be readable I can display about 8 characters each row in 3 rows.  This is fine for basic info.
More detailed messages are output on a serial port. If C3-OLED is attached to a PC they can be viewed through Arduino IDE or Putty.

The OLED screen (72 x 40 pixels) is small to be readable I can display about 8 characters each row in 3 rows.  This is fine for basic info.
More detailed messages are output on a serial port. If C3-OLED is attached to a PC they can be viewed through Arduino IDE or Putty.

It is convenient that I can use C3-OLED anywhere, it can be plugged in to any USB wall socket, or could even be attached to a battery pack.

The monitor program works well.  It runs for about 30s and tells me whether my network is ok.  I can then use PC or Home Assistant for further checks and diagnosis.


Enhancements

There is a lot of scope for enhancements, if I think it is worthwhile:

1) Add a results web page so that I could use a browser on phone, iPad or PC to look at details

2) Run periodically, say once an hour a put in deep sleep in between if there are no issues.  This could be useful if I can send a message somehow (whatsapp, text, email, mqtt, etc) when a problem is detected.

3) 3D print a case to contain C3-OLED safely

4) Check status of more systems such as TV, hifi etc which are normally turned on.



Wednesday, 23 September 2026

ESP-IDF

Intro

ESP-IDF (IoT Development Framework) is the official IDE from Espressif Systems for their microprocessors including ESP32.  As such it can be used to build and download images to ESP32 like the Arduino environment.  Whereas Arduino (successfully) endevours to make programming as simple and painless as possible ESP-IDF enables the user to utilise all ESP32 functions.  Even simple IDF programs can be challenging to develop but it is extremely useful in situations where Arduino IDE doesn't work properly for a particular application.  Arduino uses a SETUP + LOOP configuration, whereas IDF uses function interrupts / callbacks to deal with inputs and other events.

Environment

I installed ESP-IDF v6.0.1 for Windows PC.  Installation is very straightforward and it takes a few minutes to download and configure all the code. Clicking the resulting icon gives you a Powershell command line session.  You then use a python script idf.py to confirm which chip is being used (set-target) compile (build), download (flash) and open an ESP32 serial terminal (monitor).  The build process has many (automated) steps and creates a bootloader, executable image and any other required code.

Comprehensive documentation is provided by ESP and there is an excellent set of examples covering most (all?) available functionality.

Examples are vital as there is a very steep learning curve when learning how to control a range of hardware functions.   Most functions (e.g. GPIO, I2C, wifi, web servers) can be implemented by taking one or more example programs and adapting them as required.




RNT Book

There is a bit more to IDF than I can learn by browsing the programming examples and I struggled with IDF attempting to make BreezyBox work on ESP32S3. 

On 25th August, whilst on holiday I received a circular from Rui Santos announcing a new book "Learn ESP-IDF with ESP32".  Random Nerd Tutorials was setup a few years ago by Rui and his partner Sara.  They have published many, many high quality Arduino ESP8266/ESP32 and RPi tutorials from which I have benefited greatly.
They obtain an income from ebook publications and ,although I have been keen to purchase, none has been quite appropriate before.  This one seemed perfect and I jumped in to purchase it on the publication day.

Chapter 1 covers ESP-IDF installation in a Visual Studio (VSC) context and a few basic concepts.  Chapter 2 covers GPIOs; digital outputs, digital inputs, analond inputs and button debouncing using interrupts.  Although the descriptiona are light and superficial you end up with the ability to program many GPIO functions by adapting sample programs.

After Chapter 2 you have the flexibility to cover topics of specific interest: deep sleep, I2C, Wifi, BLE or ESP-NOW.  Using wifi and web servers is my first interest, but I will also cover ESP-NOW which provides networking for ESP32 devices.

USAGE

Once you get used to it, ESP-IDF doesn't seem too difficult.  Examples provided by Espressif look complicated because they are properly written, testing for errors for each hardware operation which makes them rather long.   In comparison Arduino uses standard functions for many different board types so their functions are well known.  For simple applications Arduino is certainly easier and quicker.

I expect to use ESP-IDF in a number of situations:
-  Assembly language programming
-  Whereever a software packages uses dependencies or specifies ESP-IDF install instructions
 -  If I need to use Callback functions.




What is an ESP32?

ESP32 is a 32-bit processor from Espressif Systems with wifi and bluetooth connectivity.  It is a successor to ESP8266 (32-bit cpu and wifi) which became extremely popular with the make community because of its low price and wifi connectivity.  The Arduino IDE incorporated support for ESP8266 and ESP32 which gave hobbyists a simplified approach to build applications for the system.

The first ESP32 was first released in Sepember 2016 so the reange is now ten years old.  There are now two principal designs "S" and "C" based on Xtensa and RISC-V architecture respectively.


ESP32-S3 is based on dual core Xtensa LX7 processors.  Xtensa is marketed by Cadence Systems in San Jose, California.  These processors  can be customised to provide a specific set of functions which the manufacturer requires.  It looks like you can use an IDE to design your processor and it is manufactured based on the results.

ESP32-S3 is a SoC (System on a chip) with 240MHz dul Xtena LX7 CPU, 512KB SRAM (Static RAM), 384KB ROM, 16KB RTC RAM (Very Fast RAM), 8MB PSRAM (Pseudo-static slow RAM), 45 GPIO pins, 3 x UART.  Internal ROM is used internally for wifi drivers, RTOS etc.
The SoC is often combined with extra components in a module board such as ESP-WROOM-32. Mine is an ESP32-S3-N16R8 which has 16MB flash ROM as well as 8MB PSRAM.  The module is a square silver SMD component with an antenna.
The module is mounted on a development board with USB-C ports, 40 pins, boot/reset buttons and an RGB LED.  Mine doesn't have a name but there are some well-known ones: ESP32-DevKitC (Espressif), LolinD32 (Wemos), NodeMCU-32S (Ai-Thinker).

I found some interesting articles which provide more illumination on circuitschools and JLCPCB

I have previously blogged about the ESP32-C3 RISC-V processor. This is important as Espressif have announced they aim to focus on RISC-V in the future which implies that their RISC-V  cores will eventually be as powerful as Xtensa cores.



ESP32 uses the RTOS Real-Time Operating System internally to control hardware.  Programmers can use RTOS functions for time-sensitive operations.  Programming is carried out using ESP-IDF, Arduino or PlatformIO IDEs. Programming can be carried out in C, C++ or micropython.




Monday, 7 September 2026

ESP32C3

Intro

ESP32 processors first became available in September 2016 and I first used them in 2019.  The last ones I purchased in 2023 for my LilyGo T-Display buttons which have been well used since then.

ESP-C3-01M-Kit


My interest was re-kindled when I noticed that the ESP32-C3 range runs on Risc-V.  I  purchased a couple of NodeMCU-Series ESP-C3-01m-Kit but they didn't appear to be totally compatible with the Arduino environment and I didn't progress far with them.  I did subsequently try configuring with ESP-IDF which worked better.




ESP32-C3 Super-Mini

Instead I bought some ESP32 C3 Super mini development boards which seem a lot more compatible with Arduino.


Shellminator


I saw a Hackaday article talking about shell/terminal programs which can be quickly implemented.

After a quick Google I decided to try Shellminator on my ESP32-C3.  Breezybox looks even better but requires a more powerful ESP32-S3 system.


I installed the Shellminator library in Arduino IDE and copied the first example program.

The program works fine and gives me a simple shell.  You can then code applications which make use of the shell.  This is a brilliant start for me and encouraged me to purchase an ESP32-S3 for Breezybox.


Assembly Language

It is good to see that a ESP32 Risc-V processor can be used just like an ARM processor.  At present they are somewhat less powerful, but I am pleased and applaud their progress.  Of course I really ought to try out the assembly language.  It is possible to use inline assembly in the Arduino IDE and it appears possible to include separate assembly modules.  However it looks to be rather unreliable/undocumented/error-prone.

The correct answer is to use the official ESP IDE.  ESP-IDF (Espressif IoT Development Framework) is easy to install.  I use it with Windows.  An icon is provided to invoke the command line environment in a Windows shell.  You use python "idf.py" commands to build, flash and monitor programs on an ESP32.   I will talk about ESP-IDF more in another post.


Luckily for me I found an excellent simple tutorial by Prof Smith at York (US) University.
ESP-IDF uses a package called CMake to create a set of build files for you program, taking into account ESP32 variant, compiler, platform you are using.  To use it you set up a structure of files.  You describe what you are building in the two CMakeLists.txt files.

In this simple example we have a C program defines some variables and prints a result.
Variables are passed in RISC-V registers a0 and a1 into the assembler routine, sub3.s.  The code stores the subtraction result in a0 and returns to C.  In C, a0 is the result "r" which can then be printed out.

Although this is a trivial example it gives us the mechanism to write assembler.  Of course, any usage of the processors GPIO pins or other capabilities requires an understanding of hardware, libraries, structures etc.
It is usual to only write the parts that you want/need to in assembler so the tricky parts can be done in C at first.

Outro

It is good to have an easy entry to RISC-V assembler programming using ESP-IDF.  




Saturday, 1 August 2026

Jellyfin Music : Synchronised lyrics

 

I noticed a article by HowToGeek which said that you can automatically display lyrics for for music played on Jellyfin.  Until now I only used Jellyfin for music but I thought this was worth investigating.


Google AI is currently in excellent form.  It tells me exactly how to do the installation.

First I added a new Jellyfin library for Music (I only used TV Shows and Movies previously) containing some sample music.  This allows me to select and play albums in the same way as films.

Jellyfin has a plugin, sensibly called Lyrics, which will try to find suitable lyrics and associate them with a song.  You schedule a job in Jellyfin to regularly search and add lyrics.


I used a couple of Olivia Dean songs for testing.  When I played a track a new icon could be seen for Lyrics.  I was overjoyed to see that lyrics were synchronised so the display moved through them line by line as the song progressed.

I linked the Jellyfin music library to my NASmusic database so that I can play anything with Jellyfin.

Both the PC and Ipad standard Jellyfin Music Apps display the lyrics properly.





I found that for some tracks lyrics are displayed but not synched to the music, for a few no lyrics are available.

Lyrics are taken from lrclib.net, a wonderful open source database.  It turns out that if the track duration is not within a couple of seconds of the one in the database it will not sync but plain text is displayed.

If the name / details of a track are incorrect the database may not be able to find the music - I expect this can be fixed my correcting mp3tags.