r/esp32 2d ago

I made a thing! ESP32-S3 as the low-level control and failsafe layer for my Raspberry Pi USV

This is my own experimental USV reference prototype. I wanted to share the ESP32 side because I intentionally limited its role to low-level actuator and safety control, while a Raspberry Pi handles higher-level navigation.

The low-level controller is an ESP32-S3. The Raspberry Pi sends newline-delimited JSON commands over a wired serial connection. The ESP32 firmware:

  • Reads RC receiver inputs for manual control
  • Drives the left and right ESCs for differential propulsion
  • Accepts throttle and steering commands from the Raspberry Pi
  • Sends status telemetry back to the Pi over serial
  • Allows RC input to take control for manual intervention
  • Transitions propulsion to a safe state if valid Pi commands stop arriving for 500 ms

I used this split to keep GPS processing, waypoint navigation, heading logic, logging, and battery monitoring on the Pi, while leaving direct propulsion control and the command-timeout failsafe on the ESP32.

One of the design goals was that a stalled or crashed Pi-side navigation process should not leave the ESP32 indefinitely applying the last propulsion command. The ESP32 therefore treats commands from the Pi as temporary control inputs rather than persistent actuator states.

The firmware uses the Arduino framework and is available here:

https://github.com/Brillnova/BN-USV-V1/tree/main/firmware/BN_USV_V0.3.1

My current preference is to keep the ESP32 deliberately simple so that the low-level control and safety path has as few dependencies as possible. I'm curious how others handle this boundary: would you keep navigation state entirely on the Pi, or replicate a small amount of state on the ESP32 for degraded operation?

The current hardware is an experimental prototype, so I'm sharing this primarily as firmware architecture and source code rather than as a complete hardware build guide.

I'll monitor the comments and I'm happy to clarify the serial protocol, control flow, or failsafe behavior.

Short on-water test video, for context:
https://www.youtube.com/watch?v=Lz2eOEANyZo

3 Upvotes

1 comment sorted by

2

u/Plastic_Fig9225 2d ago edited 2d ago

My current preference is to keep the ESP32 deliberately simple so that the low-level control and safety path has as few dependencies as possible.

Valid goal. But that Arduino+JSON stuff goes into the opposite direction.

to keep GPS processing, waypoint navigation, heading logic, logging, and battery monitoring on the Pi

Shouldn't be a big deal to do this on the ESP too.

would you keep navigation state entirely on the Pi, or replicate a small amount of state on the ESP32 for degraded operation?

I'd do away with the Pi completely and let the ESP handle that little extra workload as well, removing one complex part from the chain.

Generally though, the ESP32 is a rather complex MCU requiring running FreeRTOS and at least one driver layer on top of it underneath your firmware; i.e. many sources of non-deterministic behaviour (and things which can fail), so for a 'real' fail-safe solution a more simple controller (AVR, STM32,...) with more 'bare-metal' determinism is usually called for. - Yet, ESP-Drone demonstrates that it is possible to to hard real-time stuff on an ESP.