Remote Debug APIs
The RemoteDebug class provides a web-based interface for remote debugging and monitoring of ESP32 devices. It offers:
GPIO Control: Configure pins as input/output and control their states remotely
ADC Monitoring: Real-time voltage monitoring with live graphs and configurable sampling rates
Console Log Viewing: Capture and display stdout output with ANSI color support
Multi-Client Support: Efficient batched updates to support multiple simultaneous web clients
The component uses the espp WiFi, ADC, and FileSystem components for functionality, and provides a responsive web interface accessible from any browser on the local network.
API Reference
Header File
Classes
-
class RemoteDebug : public espp::BaseComponent
Remote Debug Component.
Provides a web-based interface for remote GPIO control and ADC monitoring. Allows real-time control of GPIO pins and plotting of ADC values.
Features:
GPIO control (set high/low, read state, configure mode)
ADC value reading and real-time plotting
Configurable sampling rates
Mobile-friendly responsive interface
Remote Debug Example
// Connect to WiFi using espp WifiSta logger.info("Connecting to WiFi SSID: {}", CONFIG_REMOTE_DEBUG_WIFI_SSID); espp::WifiSta wifi_sta({.ssid = CONFIG_REMOTE_DEBUG_WIFI_SSID, .password = CONFIG_REMOTE_DEBUG_WIFI_PASSWORD, .num_connect_retries = 5, .on_connected = [&logger]() { logger.info("WiFi connected!"); }, .on_disconnected = [&logger]() { logger.warn("WiFi disconnected!"); }, .on_got_ip = [&logger](ip_event_got_ip_t *event) { logger.info("got IP: {}.{}.{}.{}", IP2STR(&event->ip_info.ip)); }}); // Wait for connection while (!wifi_sta.is_connected()) { std::this_thread::sleep_for(100ms); } logger.info("WiFi connected successfully"); // Build GPIO list from menuconfig std::vector<espp::RemoteDebug::GpioConfig> gpios; #if CONFIG_REMOTE_DEBUG_NUM_GPIOS >= 1 gpios.push_back({.pin = static_cast<gpio_num_t>(CONFIG_REMOTE_DEBUG_GPIO_0), .mode = GPIO_MODE_INPUT, .label = CONFIG_REMOTE_DEBUG_GPIO_0_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_GPIOS >= 2 gpios.push_back({.pin = static_cast<gpio_num_t>(CONFIG_REMOTE_DEBUG_GPIO_1), .mode = GPIO_MODE_INPUT, .label = CONFIG_REMOTE_DEBUG_GPIO_1_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_GPIOS >= 3 gpios.push_back({.pin = static_cast<gpio_num_t>(CONFIG_REMOTE_DEBUG_GPIO_2), .mode = GPIO_MODE_INPUT, .label = CONFIG_REMOTE_DEBUG_GPIO_2_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_GPIOS >= 4 gpios.push_back({.pin = static_cast<gpio_num_t>(CONFIG_REMOTE_DEBUG_GPIO_3), .mode = GPIO_MODE_INPUT, .label = CONFIG_REMOTE_DEBUG_GPIO_3_LABEL}); #endif // Build ADC list from menuconfig size_t task_stack_size = 4096; #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 1 task_stack_size += 2048; int adc_sample_rate_hz = CONFIG_REMOTE_DEBUG_ADC_SAMPLE_RATE_HZ; size_t adc_buffer_size = CONFIG_REMOTE_DEBUG_ADC_BUFFER_SIZE; #else int adc_sample_rate_hz = 1; // Default to 1 Hz if no ADCs configured size_t adc_buffer_size = 1; // Default to buffer size of 1 if no ADCs configured #endif std::vector<espp::RemoteDebug::AdcChannelConfig> adc1_channels; #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 1 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_0), .label = CONFIG_REMOTE_DEBUG_ADC_0_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 2 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_1), .label = CONFIG_REMOTE_DEBUG_ADC_1_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 3 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_2), .label = CONFIG_REMOTE_DEBUG_ADC_2_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 4 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_3), .label = CONFIG_REMOTE_DEBUG_ADC_3_LABEL}); task_stack_size += 2048; #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 5 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_4), .label = CONFIG_REMOTE_DEBUG_ADC_4_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 6 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_5), .label = CONFIG_REMOTE_DEBUG_ADC_5_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 7 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_6), .label = CONFIG_REMOTE_DEBUG_ADC_6_LABEL}); #endif #if CONFIG_REMOTE_DEBUG_NUM_ADCS >= 8 adc1_channels.push_back({.channel = static_cast<adc_channel_t>(CONFIG_REMOTE_DEBUG_ADC_7), .label = CONFIG_REMOTE_DEBUG_ADC_7_LABEL}); task_stack_size += 2048; #endif // Configure remote debug espp::RemoteDebug::Config config { .device_name = CONFIG_REMOTE_DEBUG_DEVICE_NAME, .gpios = gpios, .adc1_channels = adc1_channels, .adc2_channels = {}, .server_port = static_cast<uint16_t>(CONFIG_REMOTE_DEBUG_SERVER_PORT), .adc_sample_rate = std::chrono::milliseconds(1000 / adc_sample_rate_hz), .gpio_update_rate = std::chrono::milliseconds(100), .adc_history_size = adc_buffer_size, .task_priority = 5, .task_stack_size = task_stack_size, #if CONFIG_REMOTE_DEBUG_ENABLE_LOGS .enable_log_capture = true, .max_log_size = CONFIG_REMOTE_DEBUG_LOG_BUFFER_SIZE, #else .enable_log_capture = false, #endif .log_level = espp::Logger::Verbosity::INFO }; espp::RemoteDebug remote_debug(config); remote_debug.start(); logger.info("Remote Debug Server started on port {}!", CONFIG_REMOTE_DEBUG_SERVER_PORT); logger.info("GPIO pins available: {}", gpios.size()); logger.info("ADC channels available: {}", adc1_channels.size()); std::this_thread::sleep_for(2s); // Create a timer to periodically generate log messages int counter = 0; auto timer = espp::Timer(espp::Timer::Config{.name = "Log Timer", .period = 2s, .callback = [&logger, &counter]() { logger.info("Timer tick #{}", counter++); if (counter % 3 == 0) { logger.warn("Warning message every 3 ticks"); } if (counter % 5 == 0) { logger.error("Error message every 5 ticks"); } return false; // don't stop }, .stack_size_bytes = 6192}); logger.info("Timer started - generating log messages every 2 seconds"); // Keep running while (true) { std::this_thread::sleep_for(1s); }
Public Functions
-
explicit RemoteDebug(const Config &config)
Construct remote debug interface.
- Parameters:
config – Configuration structure
-
~RemoteDebug()
Destructor.
-
bool start()
Start the debug server.
- Returns:
true if started successfully
-
void stop()
Stop the debug server.
-
inline bool is_active() const
Check if server is running.
- Returns:
true if active
-
bool set_gpio(gpio_num_t pin, int level)
Set GPIO output level.
- Parameters:
pin – GPIO pin number
level – Level (0=low, 1=high)
- Returns:
true if successful
-
int get_gpio(gpio_num_t pin)
Read GPIO level.
- Parameters:
pin – GPIO pin number
- Returns:
Level (0 or 1), or -1 on error
-
bool configure_gpio(gpio_num_t pin, gpio_mode_t mode)
Configure GPIO mode.
- Parameters:
pin – GPIO pin number
mode – GPIO mode (input/output)
- Returns:
true if successful
-
inline const std::string &get_name() const
Get the name of the component
Note
This is the tag of the logger
- Returns:
A const reference to the name of the component
-
inline void set_log_tag(const std::string_view &tag)
Set the tag for the logger
- Parameters:
tag – The tag to use for the logger
-
inline espp::Logger::Verbosity get_log_level() const
Get the log level for the logger
See also
See also
- Returns:
The verbosity level of the logger
-
inline void set_log_level(espp::Logger::Verbosity level)
Set the log level for the logger
See also
See also
- Parameters:
level – The verbosity level to use for the logger
-
inline void set_log_verbosity(espp::Logger::Verbosity level)
Set the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls set_log_level
- Parameters:
level – The verbosity level to use for the logger
-
inline espp::Logger::Verbosity get_log_verbosity() const
Get the log verbosity for the logger
See also
See also
See also
Note
This is a convenience method that calls get_log_level
- Returns:
The verbosity level of the logger
-
inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)
Set the rate limit for the logger
See also
Note
Only calls to the logger that have _rate_limit suffix will be rate limited
- Parameters:
rate_limit – The rate limit to use for the logger
-
struct AdcChannelConfig
ADC configuration.
-
struct Config
Configuration for remote debug.
Public Members
-
std::string device_name = {"ESP32 Device"}
Device name shown in UI title.
-
std::vector<GpioConfig> gpios
GPIO pins to expose.
-
std::vector<AdcChannelConfig> adc1_channels
ADC1 channels to monitor.
-
std::vector<AdcChannelConfig> adc2_channels
ADC2 channels to monitor.
-
uint16_t server_port = {8080}
HTTP server port.
-
std::chrono::milliseconds adc_sample_rate = {100}
ADC sampling interval.
-
std::chrono::milliseconds gpio_update_rate = {100}
GPIO state update interval.
-
size_t adc_history_size = {20}
Number of ADC samples to keep.
-
size_t task_priority = {5}
Priority for update tasks.
-
size_t task_stack_size = {4096}
Stack size for update tasks.
-
bool enable_log_capture = {false}
Enable stdout redirection to file.
-
std::string log_file_path{"debug.log"}
Path to log file. Will be appended to espp::FileSystem::get_root_path().
-
size_t max_log_size = {100000}
Maximum log file size in bytes.
-
std::string device_name = {"ESP32 Device"}
-
struct GpioConfig
GPIO configuration.