Recently I configured a Raspberry PI 5, with CasaOS, running some applications I want to keep always on.During some tests, using a temporary power adapter, happened of not being able to ssh to the Raspberry.As there were no monitor and keyboard attached to it, I needed to disconnect the board and move it into my desktop, where I was not able to reproduce the issue assuming then it was just a glitch. I decide then to enable the serial console on the Raspberry board, and create a small converter Serial - Telnet/HTTP using the cheapest and smallest esp32 C6 I had in my toolbox, a M5Stack NanoC6
FunctionsDisclaimer: I'm assuming the network and the Raspberry are connected to a private and secured network, as on this project there is no encryption nor password required. Don't use this solution if the perimeter it is not secure.
The NanoC6 use the groove port to connect to the Raspberry UART on GPIO pins, configured internally as Serial1, and enable two different protocol:
- Telnet for interactive commands
- Http to send preconfigured commands and visualize the output
We don't have any spare pins for other functionalities, like controlling a relay/mosfet to power on/off the Raspberry, out of scope on this cheap version, costing less than 6$.There is an RGB LED I can control on the NanoC6, but as the board is supposed to be remote, it doesn't make sense to use it.
The board is configured to use a fixed IP address on the network, with auto-reconnection, if the access point is not available for some time, like during blackouts, so it is not required to discover the IP eventually provided by the router/dhcp server.
TelnetThe most complete way to manage the Raspberry is via Telnet, which may not be available by default on your Operasting System. On MacOS in installed telnet client via brew, while most of the Linux distributions provides a telnet client. On Windows I used Putty in the past
enrico@MacBook-Pro-3 K3S % telnet 192.168.2.6
Trying 192.168.2.6...
Connected to 192.168.2.6.
Escape character is '^]'.
enrico@raspberrypi:~$
enrico@raspberrypi:~$ w
w
18:19:39 up 1:00, 1 user, load average: 0.00, 0.07, 0.19
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
enrico ttyAMA0 - 17:19 0.00s 0.05s ? w
enrico@raspberrypi:~$
enrico@raspberrypi:~$ ^]
telnet> quit
Connection closed.
I can execute any command like on the ssh shell.We need to keep in mind about the speed of the serial console, which it is not as responsive as ssh and some char requires escape.
To exit from a Telnet session, we need to send "cmd" + "]" on MacOS, or "control" + "]" on different systems and then type "quit"
The implementation is quite simple, very char coming from Serial1 on the ESP32 is forwarded to the Telnet session, if active, or buffered to be sent later on first connection, or via http server
In the same way, every char coming from the telnet session is forwarded to the Serial1 port. There is no processing in between.In the future, I should add some escape or filtering for special chars, like arrows or backslash, which now generate spurious chars.
It's highly suggested to use this console only to recover the Raspberry when become inaccessible via network, like after a crash/disk failure or power outage, as the speed is slower than ssh client, due to serial communication involved.
HTTPAny command received from the Raspberry via serial port is stored in a buffer of 10.000 characters. On every connection via HTTP, the buffer content is sent to the client.Eventually, as any critical error or crash is sent via serial console, on the first connection it will be displayed on the browser.
There are available 7 preconfigured commands, for the most common function:
- ifconfig -a: to viasualize all the interfaces and IP addresses
- dmesg: to see last messages from console
- ps -ef: to see all the processes running
- reboot: to restart the board
- vcgencmd measure_temp: to visualize the CPU temperature
- uptime: to check the current uptime of the OS
- last: visualize the history of boots and access
After pushing one of the equivalent buttons, the command will be executed, and 2 seconds after, the page will be refreshed with the output received by the Raspberry.
It is not possible to send random command via web, that is possible only interactively via Telnet
Raspberry PI settingsSerial console
The first step is to enable the serial communication:
On raspberry 1 to 4, you need to simply run raspi-config as root or sudo, goinf to the options: Interface Options, then I6 Serial Port, then respond yes on both requests, see screenshots
The interface will be available on GPIO 14 and 15, corresponding to pins 8 and 10.
You need to connect the TXD ping to your ESP32 RX pin, 2 on my board, and RXT to your TX pin on the ESP32, pin 1 on my board.
On Raspberry 5, there is a dedicated port with connector, closer to the mini HDMI ports, corresponding to the device ttyAMA10. If you have the right cable you should use that port, otherwise you need to customize, as root, the file /boot/firmware/cmd.txt to use the GPIO pins, corresponding to the device ttyAMA0. My config looks like this:
console=ttyAMA0,115200 console=tty1 root=PARTUUID=10c79d38-02 rootfstype=ext4 fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles cfg80211.ieee80211_regdom=DE
Autologin
If you plan to use only telnet, you can skip this step.
Autologin it's required to send commands via HTTP, which will be forwarded to the Raspberry via serial port.
While raspi-config provide a setting for autologin via local console (tty1), we need to enable that feature manually creating a dedicated configuration
cd /etc/systemd/system
mkdir serial-getty@ttyAMA0.service.d
cd serial-getty\@ttyAMA0.service.d/
vim autologin.conf
Put the following content on the file autologin.conf
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin YOURUSER --noclear --keep-baud 115200,38400,9600 %I $TERM ttyAMA0 vt100
Just replace YOURUSER with the name of the user with sudo enabled, pi by default
CodeFollow the link to the repo and copy locally the arduino code.
You will need few changes, on line 9 and 10 for your WIFI setting, and line 23 to 25 to match your Network CIDR. Eventually, if you use a different board than the M5Stack NanoC6, you may need to adapt the pin assigned to Serial1, on the line 244.as the memory and storage consumed is minimal, there is no need to.The code requires a 3rd party library: ESPTelnet, available in the library manager on the Arduino IDE.
Comments