From ae9724d9232637c874d4b5ee44b9d9e79646452f Mon Sep 17 00:00:00 2001
From: William Emfinger
Date: Sun, 11 Feb 2024 18:33:01 -0600
Subject: [PATCH] feat(base_component): add new base component and improve I2C
class + example (#149)
* feat(base_component): add new base component
* Add base component which contains logger with some methods for setting logging level and tag for the logger
* Update i2c to subclass base component and add some extra methods for writing / reading with std::vector. Also added some logging to the i2c component
* Add i2c format helpers for logging the i2c bus which is initialized
* Add missing i2c destructor
* Update i2c example to test new i2c destructor
* Add i2c menu to i2c example for allowing interactive control / query of the i2c bus using cli component
* Update i2c and cli component to have s3 defualts file configuring the console output port to be usb serial/jtag
* added missing base component
* minor update to i2c menu to enable easier reuse
* minor update to deinit
* feat(i2c): change naming of new functions so that older std::bind based peripheral code still compiles
* doc: update
* doc: rebuild
* set logger verbosity to default level so that it doesnt have to be provided
* update to change BMI formatting
* update non-peripheral components to use new base_component class
* doc: rebuild
* fix(controller): fix typo from refactor to base component
* fix(base_component): make constructors with arguments explicit
* add explicit cast
* fix(rtsp): fix out of order BMI member use
* doc: rebuild
---
.clang-format | 2 +-
components/adc/CMakeLists.txt | 2 +-
components/adc/include/continuous_adc.hpp | 21 +-
components/adc/include/oneshot_adc.hpp | 7 +-
components/base_component/CMakeLists.txt | 3 +
.../base_component/include/base_component.hpp | 51 +++
components/bldc_driver/CMakeLists.txt | 2 +-
.../bldc_driver/include/bldc_driver.hpp | 20 +-
components/bldc_haptics/CMakeLists.txt | 2 +-
.../bldc_haptics/include/bldc_haptics.hpp | 20 +-
components/bldc_motor/CMakeLists.txt | 2 +-
components/bldc_motor/include/bldc_motor.hpp | 37 ++-
components/button/CMakeLists.txt | 2 +-
components/button/include/button.hpp | 13 +-
.../cli/example/sdkconfig.defaults.esp32s3 | 3 +
components/controller/CMakeLists.txt | 2 +-
components/controller/include/controller.hpp | 13 +-
components/display/CMakeLists.txt | 2 +-
components/display/include/display.hpp | 61 ++--
components/encoder/CMakeLists.txt | 2 +-
components/encoder/include/abi_encoder.hpp | 7 +-
components/event_manager/CMakeLists.txt | 2 +-
.../event_manager/include/event_manager.hpp | 15 +-
components/file_system/CMakeLists.txt | 2 +-
.../file_system/include/file_system.hpp | 11 +-
components/ftp/CMakeLists.txt | 2 +-
components/ftp/include/ftp_client.hpp | 8 +-
components/ftp/include/ftp_client_session.hpp | 15 +-
components/ftp/include/ftp_server.hpp | 13 +-
components/i2c/CMakeLists.txt | 2 +-
components/i2c/example/CMakeLists.txt | 2 +-
components/i2c/example/main/i2c_example.cpp | 83 +++--
components/i2c/example/main/i2c_menu.hpp | 168 ++++++++++
components/i2c/example/sdkconfig.defaults | 3 +
.../i2c/example/sdkconfig.defaults.esp32s3 | 3 +
components/i2c/include/i2c.hpp | 84 ++++-
components/i2c/include/i2c_format_helpers.hpp | 21 ++
components/input_drivers/CMakeLists.txt | 2 +-
.../input_drivers/include/encoder_input.hpp | 8 +-
.../input_drivers/include/keypad_input.hpp | 8 +-
.../input_drivers/include/touchpad_input.hpp | 12 +-
components/joystick/CMakeLists.txt | 2 +-
components/joystick/include/joystick.hpp | 14 +-
components/led/CMakeLists.txt | 2 +-
components/led/include/led.hpp | 12 +-
components/led_strip/CMakeLists.txt | 2 +-
components/led_strip/include/led_strip.hpp | 13 +-
components/logger/include/logger.hpp | 11 +-
components/monitor/CMakeLists.txt | 2 +-
components/monitor/include/task_monitor.hpp | 8 +-
components/pid/CMakeLists.txt | 2 +-
components/pid/include/pid.hpp | 9 +-
components/rmt/CMakeLists.txt | 2 +-
components/rmt/include/rmt.hpp | 9 +-
components/rtsp/CMakeLists.txt | 2 +-
components/rtsp/include/rtsp_client.hpp | 22 +-
components/rtsp/include/rtsp_server.hpp | 15 +-
components/rtsp/include/rtsp_session.hpp | 22 +-
components/socket/CMakeLists.txt | 2 +-
components/socket/include/socket.hpp | 11 +-
components/task/CMakeLists.txt | 2 +-
components/task/include/task.hpp | 24 +-
components/thermistor/CMakeLists.txt | 2 +-
components/thermistor/include/thermistor.hpp | 16 +-
components/timer/CMakeLists.txt | 2 +-
components/timer/include/timer.hpp | 16 +-
components/wifi/CMakeLists.txt | 2 +-
components/wifi/include/wifi.hpp | 66 ++++
components/wifi/include/wifi_ap.hpp | 8 +-
components/wifi/include/wifi_sta.hpp | 13 +-
doc/Doxyfile | 1 +
doc/en/base_component.rst | 16 +
doc/en/index.rst | 1 +
docs/_sources/base_component.rst.txt | 16 +
docs/_sources/base_peripheral.rst.txt | 20 ++
docs/_sources/index.rst.txt | 1 +
docs/adc/adc_types.html | 7 +-
docs/adc/ads1x15.html | 5 +-
docs/adc/ads7138.html | 5 +-
docs/adc/continuous_adc.html | 83 ++++-
docs/adc/index.html | 3 +-
docs/adc/oneshot_adc.html | 83 ++++-
docs/adc/tla2528.html | 5 +-
docs/base_component.html | 293 +++++++++++++++++
docs/base_peripheral.html | 190 +++++++++++
docs/battery/bldc_driver.html | 83 ++++-
docs/battery/bldc_motor.html | 87 ++++-
docs/battery/index.html | 7 +-
docs/battery/max1704x.html | 5 +-
docs/bldc/bldc_driver.html | 83 ++++-
docs/bldc/bldc_motor.html | 87 ++++-
docs/bldc/index.html | 3 +-
docs/button.html | 83 ++++-
docs/cli.html | 7 +-
docs/color.html | 5 +-
docs/controller.html | 83 ++++-
docs/csv.html | 5 +-
docs/display/display.html | 87 ++++-
docs/display/display_drivers.html | 7 +-
docs/display/index.html | 3 +-
docs/encoder/abi_encoder.html | 83 ++++-
docs/encoder/as5600.html | 5 +-
docs/encoder/encoder_types.html | 3 +-
docs/encoder/index.html | 3 +-
docs/encoder/mt6701.html | 5 +-
docs/event_manager.html | 78 ++++-
docs/file_system.html | 83 ++++-
docs/filters/biquad.html | 5 +-
docs/filters/butterworth.html | 5 +-
docs/filters/index.html | 3 +-
docs/filters/lowpass.html | 5 +-
docs/filters/sos.html | 5 +-
docs/filters/transfer_function.html | 3 +-
docs/ftp/ftp_server.html | 163 ++++++++-
docs/ftp/index.html | 3 +-
docs/genindex.html | 309 +++++++++++++++++-
docs/haptics/bldc_haptics.html | 87 ++++-
docs/haptics/drv2605.html | 5 +-
docs/haptics/index.html | 3 +-
docs/i2c.html | 234 ++++++++++---
docs/index.html | 7 +-
docs/input/encoder_input.html | 83 ++++-
docs/input/ft5x06.html | 5 +-
docs/input/gt911.html | 5 +-
docs/input/index.html | 3 +-
docs/input/keypad_input.html | 83 ++++-
docs/input/t_keyboard.html | 5 +-
docs/input/touchpad_input.html | 83 ++++-
docs/input/tt21100.html | 5 +-
docs/io_expander/aw9523.html | 5 +-
docs/io_expander/index.html | 3 +-
docs/io_expander/mcp23x17.html | 5 +-
docs/joystick.html | 83 ++++-
docs/led.html | 83 ++++-
docs/led_strip.html | 83 ++++-
docs/logger.html | 20 +-
docs/math/bezier.html | 5 +-
docs/math/fast_math.html | 3 +-
docs/math/gaussian.html | 5 +-
docs/math/index.html | 3 +-
docs/math/range_mapper.html | 5 +-
docs/math/vector2d.html | 5 +-
docs/monitor.html | 86 ++++-
docs/network/index.html | 3 +-
docs/network/socket.html | 83 ++++-
docs/network/tcp_socket.html | 81 ++++-
docs/network/udp_socket.html | 81 ++++-
docs/nfc/index.html | 3 +-
docs/nfc/ndef.html | 5 +-
docs/nfc/st25dv.html | 5 +-
docs/objects.inv | Bin 61948 -> 64792 bytes
docs/pid.html | 83 ++++-
docs/qwiicnes.html | 5 +-
docs/rmt.html | 85 ++++-
docs/rtc/bm8563.html | 5 +-
docs/rtc/index.html | 3 +-
docs/rtsp.html | 253 +++++++++++++-
docs/search.html | 1 +
docs/searchindex.js | 2 +-
docs/serialization.html | 5 +-
docs/state_machine.html | 11 +-
docs/tabulate.html | 5 +-
docs/task.html | 83 ++++-
docs/thermistor.html | 83 ++++-
docs/timer.html | 83 ++++-
docs/wifi/index.html | 3 +-
docs/wifi/wifi_ap.html | 83 ++++-
docs/wifi/wifi_sta.html | 83 ++++-
168 files changed, 4748 insertions(+), 567 deletions(-)
create mode 100644 components/base_component/CMakeLists.txt
create mode 100644 components/base_component/include/base_component.hpp
create mode 100644 components/cli/example/sdkconfig.defaults.esp32s3
create mode 100644 components/i2c/example/main/i2c_menu.hpp
create mode 100644 components/i2c/example/sdkconfig.defaults.esp32s3
create mode 100644 components/i2c/include/i2c_format_helpers.hpp
create mode 100644 components/wifi/include/wifi.hpp
create mode 100644 doc/en/base_component.rst
create mode 100644 docs/_sources/base_component.rst.txt
create mode 100644 docs/_sources/base_peripheral.rst.txt
create mode 100644 docs/base_component.html
create mode 100644 docs/base_peripheral.html
diff --git a/.clang-format b/.clang-format
index 0e0bcba93..e49f21ef6 100644
--- a/.clang-format
+++ b/.clang-format
@@ -40,7 +40,7 @@ BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeInheritanceComma: false
BreakBeforeTernaryOperators: true
-BreakConstructorInitializersBeforeComma: false
+BreakConstructorInitializersBeforeComma: true
BreakConstructorInitializers: BeforeColon
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
diff --git a/components/adc/CMakeLists.txt b/components/adc/CMakeLists.txt
index 6c1087e11..b7d911cd4 100644
--- a/components/adc/CMakeLists.txt
+++ b/components/adc/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger task esp_adc)
+ REQUIRES base_component task esp_adc)
diff --git a/components/adc/include/continuous_adc.hpp b/components/adc/include/continuous_adc.hpp
index be356b42e..78be586f0 100644
--- a/components/adc/include/continuous_adc.hpp
+++ b/components/adc/include/continuous_adc.hpp
@@ -10,7 +10,7 @@
#include "esp_adc/adc_continuous.h"
#include "adc_types.hpp"
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
namespace espp {
@@ -27,7 +27,7 @@ namespace espp {
* \section adc_continuous_ex1 Continuous ADC Example
* \snippet adc_example.cpp continuous adc example
*/
-class ContinuousAdc {
+class ContinuousAdc : public espp::BaseComponent {
public:
/**
* @brief Configure the sample rate (globally applied to each channel),
@@ -50,12 +50,14 @@ class ContinuousAdc {
* @param config Config used to initialize the reader.
*/
explicit ContinuousAdc(const Config &config)
- : sample_rate_hz_(config.sample_rate_hz), window_size_bytes_(config.window_size_bytes),
- num_channels_(config.channels.size()), conv_mode_(config.convert_mode),
- result_data_(window_size_bytes_, 0xcc),
- logger_({.tag = "Continuous Adc",
- .rate_limit = std::chrono::milliseconds(100),
- .level = config.log_level}) {
+ : BaseComponent("ContinuousAdc", config.log_level)
+ , sample_rate_hz_(config.sample_rate_hz)
+ , window_size_bytes_(config.window_size_bytes)
+ , num_channels_(config.channels.size())
+ , conv_mode_(config.convert_mode)
+ , result_data_(window_size_bytes_, 0xcc) {
+ // set the rate limit for the logger
+ logger_.set_rate_limit(std::chrono::milliseconds(100));
// initialize the adc continuous subsystem
init(config.channels);
// and start the task
@@ -203,7 +205,7 @@ class ContinuousAdc {
#if !CONFIG_IDF_TARGET_ESP32
if (output_format_ == ADC_DIGI_OUTPUT_FORMAT_TYPE2) {
if (check_valid_data(p)) {
- auto unit = p->type2.unit;
+ auto unit = (adc_unit_t)p->type2.unit;
auto channel = (adc_channel_t)p->type2.channel;
auto data = p->type2.data;
auto id = get_id(unit, channel);
@@ -398,7 +400,6 @@ class ContinuousAdc {
adc_digi_convert_mode_t conv_mode_;
adc_digi_output_format_t output_format_;
std::vector result_data_;
- Logger logger_;
std::unique_ptr task_;
TaskHandle_t task_handle_{NULL};
std::mutex data_mutex_;
diff --git a/components/adc/include/oneshot_adc.hpp b/components/adc/include/oneshot_adc.hpp
index acce851ef..6bbe91c1f 100644
--- a/components/adc/include/oneshot_adc.hpp
+++ b/components/adc/include/oneshot_adc.hpp
@@ -10,7 +10,7 @@
#include "esp_adc/adc_oneshot.h"
#include "adc_types.hpp"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -22,7 +22,7 @@ namespace espp {
* \section adc_oneshot_ex1 Oneshot ADC Example
* \snippet adc_example.cpp oneshot adc example
*/
-class OneshotAdc {
+class OneshotAdc : public BaseComponent {
public:
/**
* @brief Configure the unit for which to read adc values from the provided
@@ -44,7 +44,7 @@ class OneshotAdc {
* @param config Config used to initialize the reader.
*/
explicit OneshotAdc(const Config &config)
- : logger_({.tag = "Oneshot Adc", .level = config.log_level}) {
+ : BaseComponent("OneShotAdc", config.log_level) {
init(config);
}
@@ -185,6 +185,5 @@ class OneshotAdc {
adc_oneshot_unit_handle_t adc_handle_;
adc_cali_handle_t adc_cali_handle_;
std::atomic calibrated_{false};
- Logger logger_;
};
} // namespace espp
diff --git a/components/base_component/CMakeLists.txt b/components/base_component/CMakeLists.txt
new file mode 100644
index 000000000..1d8b9a5e8
--- /dev/null
+++ b/components/base_component/CMakeLists.txt
@@ -0,0 +1,3 @@
+idf_component_register(
+ INCLUDE_DIRS "include"
+ REQUIRES logger)
diff --git a/components/base_component/include/base_component.hpp b/components/base_component/include/base_component.hpp
new file mode 100644
index 000000000..4170255e9
--- /dev/null
+++ b/components/base_component/include/base_component.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include
+#include
+
+#include "logger.hpp"
+
+namespace espp {
+/// Base class for all components
+/// Provides a logger and some basic logging configuration
+class BaseComponent {
+public:
+ /// Set the tag for the logger
+ /// \param tag The tag to use for the logger
+ void set_log_tag(const std::string_view &tag) { logger_.set_tag(tag); }
+
+ /// Set the log level for the logger
+ /// \param level The verbosity level to use for the logger
+ /// \sa Logger::Verbosity
+ /// \sa Logger::set_verbosity
+ void set_log_level(Logger::Verbosity level) { logger_.set_verbosity(level); }
+
+ /// Set the log verbosity for the logger
+ /// \param level The verbosity level to use for the logger
+ /// \note This is a convenience method that calls set_log_level
+ /// \sa set_log_level
+ /// \sa Logger::Verbosity
+ /// \sa Logger::set_verbosity
+ void set_log_verbosity(Logger::Verbosity level) { set_log_level(level); }
+
+ /// Set the rate limit for the logger
+ /// \param rate_limit The rate limit to use for the logger
+ /// \note Only calls to the logger that have _rate_limit suffix will be rate limited
+ /// \sa Logger::set_rate_limit
+ void set_log_rate_limit(std::chrono::duration rate_limit) {
+ logger_.set_rate_limit(rate_limit);
+ }
+
+protected:
+ BaseComponent() = default;
+
+ explicit BaseComponent(std::string_view tag, Logger::Verbosity level = Logger::Verbosity::WARN)
+ : logger_({.tag = tag, .level = level}) {}
+
+ explicit BaseComponent(const Logger::Config &logger_config)
+ : logger_(logger_config) {}
+
+ /// The logger for this component
+ Logger logger_ = espp::Logger({.tag = "BaseComponent", .level = Logger::Verbosity::INFO});
+};
+} // namespace espp
diff --git a/components/bldc_driver/CMakeLists.txt b/components/bldc_driver/CMakeLists.txt
index 86f338bb0..4e90d84c0 100644
--- a/components/bldc_driver/CMakeLists.txt
+++ b/components/bldc_driver/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger driver)
+ REQUIRES base_component driver)
diff --git a/components/bldc_driver/include/bldc_driver.hpp b/components/bldc_driver/include/bldc_driver.hpp
index 1fd092316..d5bb8f297 100644
--- a/components/bldc_driver/include/bldc_driver.hpp
+++ b/components/bldc_driver/include/bldc_driver.hpp
@@ -7,7 +7,7 @@
#include "driver/gpio.h"
#include "driver/mcpwm_prelude.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -16,7 +16,7 @@ namespace espp {
* https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/mcpwm.html
* peripheral.
*/
-class BldcDriver {
+class BldcDriver : public BaseComponent {
public:
static constexpr size_t TIMER_RESOLUTION_HZ = 80 * 1000 * 1000; // 80 MHz
static constexpr size_t FREQUENCY_HZ = 20 * 1000; // 20 KHz
@@ -48,11 +48,16 @@ class BldcDriver {
* @param config Config used to initialize the driver.
*/
explicit BldcDriver(const Config &config)
- : gpio_ah_((gpio_num_t)config.gpio_a_h), gpio_al_((gpio_num_t)config.gpio_a_l),
- gpio_bh_((gpio_num_t)config.gpio_b_h), gpio_bl_((gpio_num_t)config.gpio_b_l),
- gpio_ch_((gpio_num_t)config.gpio_c_h), gpio_cl_((gpio_num_t)config.gpio_c_l),
- gpio_en_(config.gpio_enable), gpio_fault_(config.gpio_fault), dead_zone_(config.dead_zone),
- logger_({.tag = "BLDC Driver", .level = config.log_level}) {
+ : BaseComponent("BldcDriver", config.log_level)
+ , gpio_ah_((gpio_num_t)config.gpio_a_h)
+ , gpio_al_((gpio_num_t)config.gpio_a_l)
+ , gpio_bh_((gpio_num_t)config.gpio_b_h)
+ , gpio_bl_((gpio_num_t)config.gpio_b_l)
+ , gpio_ch_((gpio_num_t)config.gpio_c_h)
+ , gpio_cl_((gpio_num_t)config.gpio_c_l)
+ , gpio_en_(config.gpio_enable)
+ , gpio_fault_(config.gpio_fault)
+ , dead_zone_(config.dead_zone) {
configure_power(config.power_supply_voltage, config.limit_voltage);
init(config);
}
@@ -411,6 +416,5 @@ class BldcDriver {
std::array operators_;
std::array comparators_;
std::array generators_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/bldc_haptics/CMakeLists.txt b/components/bldc_haptics/CMakeLists.txt
index cb71043a1..a4fc9a32e 100644
--- a/components/bldc_haptics/CMakeLists.txt
+++ b/components/bldc_haptics/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger math pid task bldc_motor
+ REQUIRES base_component math pid task bldc_motor
)
diff --git a/components/bldc_haptics/include/bldc_haptics.hpp b/components/bldc_haptics/include/bldc_haptics.hpp
index 048957f90..3ba617ba3 100644
--- a/components/bldc_haptics/include/bldc_haptics.hpp
+++ b/components/bldc_haptics/include/bldc_haptics.hpp
@@ -4,10 +4,10 @@
#include
#include
+#include "base_component.hpp"
#include "bldc_motor.hpp"
#include "detent_config.hpp"
#include "haptic_config.hpp"
-#include "logger.hpp"
#include "task.hpp"
namespace espp {
@@ -93,7 +93,7 @@ concept MotorConcept = requires {
/// \snippet bldc_haptics_example.cpp bldc_haptics_example_1
/// \section bldc_haptics_ex2 Example 2: Playing a haptic click / buzz
/// \snippet bldc_haptics_example.cpp bldc_haptics_example_2
-template class BldcHaptics {
+template class BldcHaptics : public BaseComponent {
public:
/// @brief Configuration for the haptic motor
struct Config {
@@ -113,19 +113,19 @@ template class BldcHaptics {
/// @brief Constructor for the haptic motor
/// @param config Configuration for the haptic motor
explicit BldcHaptics(const Config &config)
- : detent_pid_({.kp = 0, // will be set later (motor_task)
+ : BaseComponent("BldcHaptics", config.log_level)
+ , detent_pid_({.kp = 0, // will be set later (motor_task)
.ki = 0, // not configurable for now
.kd = 0, // will be set later (update_detent_config)
.integrator_min = 0, // not configurable for now
.integrator_max = 0, // not configurable for now
.output_min = -1, // go ahead and set some bounds (operates on current)
.output_max = 1}) // go ahead and set some bounds (operates on current)
- ,
- kp_factor_(config.kp_factor), kd_factor_min_(config.kd_factor_min),
- kd_factor_max_(config.kd_factor_max), motor_(config.motor),
- logger_({.tag = "BldcHaptics",
- .rate_limit = std::chrono::milliseconds(100),
- .level = config.log_level}) {
+ , kp_factor_(config.kp_factor)
+ , kd_factor_min_(config.kd_factor_min)
+ , kd_factor_max_(config.kd_factor_max)
+ , motor_(config.motor) {
+ logger_.set_rate_limit(std::chrono::milliseconds(100));
logger_.info("Initializing haptic motor\n"
"\tkp_factor: {}\n"
"\tkd_factor_min: {}\n"
@@ -432,7 +432,5 @@ template class BldcHaptics {
std::reference_wrapper motor_; ///< Pointer to the motor to use for haptics
std::unique_ptr motor_task_; ///< Task which runs the haptic motor
-
- Logger logger_; ///< Logger for the haptics
};
} // namespace espp
diff --git a/components/bldc_motor/CMakeLists.txt b/components/bldc_motor/CMakeLists.txt
index 98f4ad03e..dec80c1be 100644
--- a/components/bldc_motor/CMakeLists.txt
+++ b/components/bldc_motor/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger math pid task
+ REQUIRES base_component math pid task
)
diff --git a/components/bldc_motor/include/bldc_motor.hpp b/components/bldc_motor/include/bldc_motor.hpp
index a4790548f..6dc973480 100644
--- a/components/bldc_motor/include/bldc_motor.hpp
+++ b/components/bldc_motor/include/bldc_motor.hpp
@@ -2,8 +2,8 @@
#include
+#include "base_component.hpp"
#include "fast_math.hpp"
-#include "logger.hpp"
#include "pid.hpp"
#include "task.hpp"
@@ -65,7 +65,7 @@ struct DummyCurrentSense {
* @snippet bldc_motor_example.cpp bldc_motor example
*/
template
-class BldcMotor {
+class BldcMotor : public BaseComponent {
public:
/**
* @brief Filter the raw input sample and return it.
@@ -130,17 +130,27 @@ class BldcMotor {
* necessary sensor calibration.
*/
explicit BldcMotor(const Config &config)
- : num_pole_pairs_(config.num_pole_pairs), phase_resistance_(config.phase_resistance),
- phase_inductance_(config.phase_inductance), kv_rating_(config.kv_rating * _SQRT2),
- current_limit_(config.current_limit), velocity_limit_(config.velocity_limit),
- sensor_direction_(config.sensor_direction), foc_type_(config.foc_type),
- torque_control_type_(config.torque_controller), driver_(config.driver),
- sensor_(config.sensor), current_sense_(config.current_sense),
- pid_current_q_(config.current_pid_config), pid_current_d_(config.current_pid_config),
- pid_velocity_(config.current_pid_config), pid_angle_(config.current_pid_config),
- q_current_filter_(config.q_current_filter), d_current_filter_(config.d_current_filter),
- velocity_filter_(config.velocity_filter), angle_filter_(config.angle_filter),
- logger_({.tag = "BldcMotor", .level = config.log_level}) {
+ : BaseComponent("BldcMotor", config.log_level)
+ , num_pole_pairs_(config.num_pole_pairs)
+ , phase_resistance_(config.phase_resistance)
+ , phase_inductance_(config.phase_inductance)
+ , kv_rating_(config.kv_rating * _SQRT2)
+ , current_limit_(config.current_limit)
+ , velocity_limit_(config.velocity_limit)
+ , sensor_direction_(config.sensor_direction)
+ , foc_type_(config.foc_type)
+ , torque_control_type_(config.torque_controller)
+ , driver_(config.driver)
+ , sensor_(config.sensor)
+ , current_sense_(config.current_sense)
+ , pid_current_q_(config.current_pid_config)
+ , pid_current_d_(config.current_pid_config)
+ , pid_velocity_(config.current_pid_config)
+ , pid_angle_(config.current_pid_config)
+ , q_current_filter_(config.q_current_filter)
+ , d_current_filter_(config.d_current_filter)
+ , velocity_filter_(config.velocity_filter)
+ , angle_filter_(config.angle_filter) {
// initialize the voltage limit
voltage_limit_ = driver_->get_voltage_limit();
voltage_sensor_align_ = voltage_limit_ / 4.0f;
@@ -948,7 +958,6 @@ class BldcMotor {
filter_fn angle_filter_{nullptr};
std::atomic enabled_{false};
Status status_{Status::UNINITIALIZED};
- Logger logger_;
};
} // namespace espp
diff --git a/components/button/CMakeLists.txt b/components/button/CMakeLists.txt
index c3e49703e..b5464f5ff 100644
--- a/components/button/CMakeLists.txt
+++ b/components/button/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES driver logger task)
+ REQUIRES driver base_component task)
diff --git a/components/button/include/button.hpp b/components/button/include/button.hpp
index c45a2f54a..e7b902a8b 100644
--- a/components/button/include/button.hpp
+++ b/components/button/include/button.hpp
@@ -8,7 +8,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
namespace espp {
@@ -19,7 +19,7 @@ namespace espp {
///
/// \section button_ex1 Button Example
/// \snippet button_example.cpp button example
-class Button {
+class Button : public BaseComponent {
public:
/// \brief The event for the button
struct Event {
@@ -65,9 +65,11 @@ class Button {
/// \brief Construct a button
/// \param config The configuration for the button
explicit Button(const Config &config)
- : gpio_num_(config.gpio_num), callback_(config.callback), active_level_(config.active_level),
- event_queue_(xQueueCreate(10, sizeof(EventData))),
- logger_({.tag = config.name, .level = config.log_level}) {
+ : BaseComponent(config.name, config.log_level)
+ , gpio_num_(config.gpio_num)
+ , callback_(config.callback)
+ , active_level_(config.active_level)
+ , event_queue_(xQueueCreate(10, sizeof(EventData))) {
// configure the GPIO for an interrupt
gpio_config_t io_conf;
memset(&io_conf, 0, sizeof(io_conf));
@@ -178,6 +180,5 @@ class Button {
HandlerArgs handler_args_;
std::atomic pressed_{false};
std::unique_ptr task_;
- espp::Logger logger_;
};
} // namespace espp
diff --git a/components/cli/example/sdkconfig.defaults.esp32s3 b/components/cli/example/sdkconfig.defaults.esp32s3
new file mode 100644
index 000000000..eaee743c2
--- /dev/null
+++ b/components/cli/example/sdkconfig.defaults.esp32s3
@@ -0,0 +1,3 @@
+# on the ESP32S3, which has native USB, we need to set the console so that the
+# CLI can be configured correctly:
+CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
diff --git a/components/controller/CMakeLists.txt b/components/controller/CMakeLists.txt
index 50dd73b45..e01474da2 100644
--- a/components/controller/CMakeLists.txt
+++ b/components/controller/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES driver joystick
+ REQUIRES driver base_component joystick
)
diff --git a/components/controller/include/controller.hpp b/components/controller/include/controller.hpp
index dc702983a..f2ad534a5 100644
--- a/components/controller/include/controller.hpp
+++ b/components/controller/include/controller.hpp
@@ -7,8 +7,8 @@
#include "driver/dedic_gpio.h"
#include "driver/gpio.h"
+#include "base_component.hpp"
#include "joystick.hpp"
-#include "logger.hpp"
namespace espp {
/**
@@ -31,7 +31,7 @@ namespace espp {
* \section controller_ex3 I2C Analog Controller Example
* \snippet controller_example.cpp i2c analog controller example
*/
-class Controller {
+class Controller : public BaseComponent {
public:
/**
* @brief The buttons that the controller supports.
@@ -137,7 +137,7 @@ class Controller {
* @brief Create a Digital controller.
*/
explicit Controller(const DigitalConfig &config)
- : logger_({.tag = "Digital Controller", .level = config.log_level}) {
+ : BaseComponent("Digital Controller", config.log_level) {
gpio_.assign((int)Button::LAST_UNUSED, -1);
input_state_.assign((int)Button::LAST_UNUSED, false);
gpio_[(int)Button::A] = config.gpio_a;
@@ -157,8 +157,8 @@ class Controller {
* @brief Create an analog joystick controller.
*/
explicit Controller(const AnalogJoystickConfig &config)
- : joystick_(std::make_unique(config.joystick_config)),
- logger_({.tag = "Analog Joystick Controller", .level = config.log_level}) {
+ : BaseComponent("Analog Joystick Controller", config.log_level)
+ , joystick_(std::make_unique(config.joystick_config)) {
gpio_.assign((int)Button::LAST_UNUSED, -1);
input_state_.assign((int)Button::LAST_UNUSED, false);
gpio_[(int)Button::A] = config.gpio_a;
@@ -175,7 +175,7 @@ class Controller {
* @brief Create a dual d-pad + analog joystick controller.
*/
explicit Controller(const DualConfig &config)
- : logger_({.tag = "Dual Digital Controller", .level = config.log_level}) {
+ : BaseComponent("Dual Digital Controller", config.log_level) {
gpio_.assign((int)Button::LAST_UNUSED, -1);
input_state_.assign((int)Button::LAST_UNUSED, false);
gpio_[(int)Button::A] = config.gpio_a;
@@ -322,6 +322,5 @@ class Controller {
std::vector input_state_;
dedic_gpio_bundle_handle_t gpio_bundle_{NULL};
std::unique_ptr joystick_;
- espp::Logger logger_;
};
} // namespace espp
diff --git a/components/display/CMakeLists.txt b/components/display/CMakeLists.txt
index 50b268d16..31a343098 100644
--- a/components/display/CMakeLists.txt
+++ b/components/display/CMakeLists.txt
@@ -1,6 +1,6 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES driver led lvgl logger task)
+ REQUIRES driver led lvgl base_component task)
# lvgl generates deprecated enum-enum conversion warnings, suppress them
target_compile_options(${COMPONENT_LIB} INTERFACE "-Wno-deprecated-enum-enum-conversion")
add_definitions(-DLV_CONF_INCLUDE_SIMPLE)
diff --git a/components/display/include/display.hpp b/components/display/include/display.hpp
index c383dfcb8..498b5e786 100644
--- a/components/display/include/display.hpp
+++ b/components/display/include/display.hpp
@@ -8,6 +8,7 @@
#include
+#include "base_component.hpp"
#include "led.hpp"
#include "task.hpp"
@@ -23,7 +24,7 @@ namespace espp {
* For more information, see
* https://docs.lvgl.io/8.3/porting/display.html#display-interface
*/
-class Display {
+class Display : public BaseComponent {
public:
/**
* @brief Callback for lvgl to flush segments of pixel data from the pixel
@@ -57,8 +58,7 @@ class Display {
gpio_num_t backlight_pin; /**< GPIO pin for the backlight. */
bool backlight_on_value{
true}; /**< Value to write to the backlight pin to turn the backlight on. */
- size_t stack_size_bytes{
- 4096}; /**< Size of the display task stack in bytes. */
+ size_t stack_size_bytes{4096}; /**< Size of the display task stack in bytes. */
std::chrono::duration update_period{
0.01}; /**< How frequently to run the update function. */
bool double_buffered{
@@ -87,8 +87,7 @@ class Display {
gpio_num_t backlight_pin; /**< GPIO pin for the backlight. */
bool backlight_on_value{
true}; /**< Value to write to the backlight pin to turn the backlight on. */
- size_t stack_size_bytes{
- 4096}; /**< Size of the display task stack in bytes. */
+ size_t stack_size_bytes{4096}; /**< Size of the display task stack in bytes. */
std::chrono::duration update_period{
0.01}; /**< How frequently to run the update function. */
Rotation rotation{Rotation::LANDSCAPE}; /**< Default / Initial rotation of the display. */
@@ -104,19 +103,20 @@ class Display {
* callback.
*/
explicit Display(const AllocatingConfig &config)
- : width_(config.width), height_(config.height),
- display_buffer_px_size_(config.pixel_buffer_size),
- led_channel_configs_(
+ : BaseComponent("Display", config.log_level)
+ , width_(config.width)
+ , height_(config.height)
+ , display_buffer_px_size_(config.pixel_buffer_size)
+ , led_channel_configs_(
std::vector{{.gpio = (size_t)config.backlight_pin,
.channel = LEDC_CHANNEL_0,
.timer = LEDC_TIMER_0,
- .output_invert = !config.backlight_on_value}}),
- backlight_(Led::Config{.timer = LEDC_TIMER_0,
+ .output_invert = !config.backlight_on_value}})
+ , backlight_(Led::Config{.timer = LEDC_TIMER_0,
.frequency_hz = 5000,
.channels = led_channel_configs_,
- .duty_resolution = LEDC_TIMER_10_BIT}),
- update_period_(config.update_period),
- logger_({.tag = "Display", .level = config.log_level}) {
+ .duty_resolution = LEDC_TIMER_10_BIT})
+ , update_period_(config.update_period) {
logger_.debug("Initializing with allocating config!");
// create the display buffers
vram_0_ = (lv_color_t *)heap_caps_malloc(vram_size_bytes(), config.allocation_flags);
@@ -126,7 +126,8 @@ class Display {
assert(vram_1_ != NULL);
}
created_vram_ = true;
- init(config.flush_callback, config.software_rotation_enabled, config.rotation, config.stack_size_bytes);
+ init(config.flush_callback, config.software_rotation_enabled, config.rotation,
+ config.stack_size_bytes);
set_brightness(1.0f);
}
@@ -136,21 +137,25 @@ class Display {
* memory, the pixel buffer size and flush callback.
*/
explicit Display(const NonAllocatingConfig &config)
- : width_(config.width), height_(config.height),
- display_buffer_px_size_(config.pixel_buffer_size), vram_0_(config.vram0),
- vram_1_(config.vram1), led_channel_configs_(std::vector{
- {.gpio = (size_t)config.backlight_pin,
- .channel = LEDC_CHANNEL_0,
- .timer = LEDC_TIMER_0,
- .output_invert = !config.backlight_on_value}}),
- backlight_(Led::Config{.timer = LEDC_TIMER_0,
+ : BaseComponent("Display", config.log_level)
+ , width_(config.width)
+ , height_(config.height)
+ , display_buffer_px_size_(config.pixel_buffer_size)
+ , vram_0_(config.vram0)
+ , vram_1_(config.vram1)
+ , led_channel_configs_(
+ std::vector{{.gpio = (size_t)config.backlight_pin,
+ .channel = LEDC_CHANNEL_0,
+ .timer = LEDC_TIMER_0,
+ .output_invert = !config.backlight_on_value}})
+ , backlight_(Led::Config{.timer = LEDC_TIMER_0,
.frequency_hz = 5000,
.channels = led_channel_configs_,
- .duty_resolution = LEDC_TIMER_10_BIT}),
- update_period_(config.update_period),
- logger_({.tag = "Display", .level = config.log_level}) {
+ .duty_resolution = LEDC_TIMER_10_BIT})
+ , update_period_(config.update_period) {
logger_.debug("Initializing with non-allocating config!");
- init(config.flush_callback, config.software_rotation_enabled, config.rotation, config.stack_size_bytes);
+ init(config.flush_callback, config.software_rotation_enabled, config.rotation,
+ config.stack_size_bytes);
}
/**
@@ -258,7 +263,8 @@ class Display {
* @param rotation Default / initial rotation of the display.
* @param stack_size_bytes Size of the task stack in bytes.
*/
- void init(flush_fn flush_callback, bool sw_rotation_enabled, Rotation rotation, size_t stack_size_bytes = 4096) {
+ void init(flush_fn flush_callback, bool sw_rotation_enabled, Rotation rotation,
+ size_t stack_size_bytes = 4096) {
lv_init();
// Configure the LVGL display buffer with our pixel buffers
@@ -327,6 +333,5 @@ class Display {
std::chrono::duration update_period_;
lv_disp_draw_buf_t disp_buffer_;
lv_disp_drv_t disp_driver_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/encoder/CMakeLists.txt b/components/encoder/CMakeLists.txt
index 86f338bb0..4e90d84c0 100644
--- a/components/encoder/CMakeLists.txt
+++ b/components/encoder/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger driver)
+ REQUIRES base_component driver)
diff --git a/components/encoder/include/abi_encoder.hpp b/components/encoder/include/abi_encoder.hpp
index c04fe9752..acea583e5 100644
--- a/components/encoder/include/abi_encoder.hpp
+++ b/components/encoder/include/abi_encoder.hpp
@@ -5,8 +5,8 @@
#include "driver/gpio.h"
#include "driver/pulse_cnt.h"
+#include "base_component.hpp"
#include "encoder_types.hpp"
-#include "logger.hpp"
namespace espp {
/**
@@ -20,7 +20,7 @@ namespace espp {
* \section encoder_ex2 AbiEncoder (LINEAR) Example
* \snippet encoder_example.cpp abi encoder linear example
*/
-template class AbiEncoder {
+template class AbiEncoder : public BaseComponent {
public:
struct Config {
int a_gpio; /**< GPIO number for the a channel pulse. */
@@ -48,7 +48,7 @@ template class AbiEncoder {
*/
template
explicit AbiEncoder(const Config &config)
- : logger_({.tag = "AbiEncoder", .level = config.log_level}) {
+ : BaseComponent("AbiEncoder", config.log_level) {
// we only care about counts_per_revolution if it is EncoderType::ROTATIONAL
if constexpr (type == EncoderType::ROTATIONAL) {
if (config.counts_per_revolution == 0) {
@@ -275,6 +275,5 @@ template class AbiEncoder {
pcnt_unit_handle_t pcnt_unit_{nullptr};
pcnt_channel_handle_t pcnt_channel_a_{nullptr};
pcnt_channel_handle_t pcnt_channel_b_{nullptr};
- Logger logger_;
};
} // namespace espp
diff --git a/components/event_manager/CMakeLists.txt b/components/event_manager/CMakeLists.txt
index b34800578..cb1e7ccab 100644
--- a/components/event_manager/CMakeLists.txt
+++ b/components/event_manager/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
SRC_DIRS "src"
- REQUIRES logger task)
+ REQUIRES base_component task)
diff --git a/components/event_manager/include/event_manager.hpp b/components/event_manager/include/event_manager.hpp
index 9113d4acb..5a80c2cf5 100644
--- a/components/event_manager/include/event_manager.hpp
+++ b/components/event_manager/include/event_manager.hpp
@@ -6,8 +6,8 @@
#include
#include
+#include "base_component.hpp"
#include "event_map.hpp"
-#include "logger.hpp"
#include "task.hpp"
namespace espp {
@@ -34,7 +34,7 @@ namespace espp {
* \section event_manager_ex1 Event Manager Example
* \snippet event_manager_example.cpp event manager example
*/
-class EventManager {
+class EventManager : public BaseComponent {
public:
/**
* @brief Function definition for function prototypes to be called when
@@ -110,14 +110,9 @@ class EventManager {
*/
bool remove_subscriber(const std::string &topic, const std::string &component);
- /**
- * @brief Set the logger verbosity for the EventManager.
- * @param level new Logger::Verbosity level to use.
- */
- void set_log_level(Logger::Verbosity level) { logger_.set_verbosity(level); }
-
protected:
- EventManager() : logger_({.tag = "Event Manager", .level = Logger::Verbosity::WARN}) {}
+ EventManager()
+ : BaseComponent("Event Manager") {}
struct SubscriberData {
std::mutex m;
@@ -139,7 +134,5 @@ class EventManager {
std::recursive_mutex data_mutex_;
std::unordered_map subscriber_data_;
-
- Logger logger_;
};
} // namespace espp
diff --git a/components/file_system/CMakeLists.txt b/components/file_system/CMakeLists.txt
index 8026e3c96..e91d440e7 100644
--- a/components/file_system/CMakeLists.txt
+++ b/components/file_system/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger esp_littlefs spi_flash)
+ REQUIRES base_component esp_littlefs spi_flash)
diff --git a/components/file_system/include/file_system.hpp b/components/file_system/include/file_system.hpp
index b2bd18a95..9ffb1d085 100644
--- a/components/file_system/include/file_system.hpp
+++ b/components/file_system/include/file_system.hpp
@@ -19,7 +19,7 @@
#include
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/// @brief File system class
@@ -43,7 +43,7 @@ namespace espp {
/// \snippet file_system_example.cpp file_system posix example
/// \section fs_ex3 File System Info std::filesystem Example
/// \snippet file_system_example.cpp file_system std filesystem example
-class FileSystem {
+class FileSystem : public BaseComponent {
public:
/// @brief Access the singleton instance of the file system
/// @return Reference to the file system instance
@@ -276,7 +276,10 @@ class FileSystem {
/// @brief Constructor
/// @details
/// The constructor is private to ensure that the class is a singleton.
- FileSystem() : logger_({.tag = "FileSystem", .level = Logger::Verbosity::WARN}) { init(); }
+ FileSystem()
+ : BaseComponent("FileSystem") {
+ init();
+ }
/// @brief Initialize the file system
/// @details
@@ -321,7 +324,5 @@ class FileSystem {
std::filesystem::create_directory(root_path);
}
}
-
- Logger logger_;
};
} // namespace espp
diff --git a/components/ftp/CMakeLists.txt b/components/ftp/CMakeLists.txt
index c0119cae2..bf0d7d50b 100644
--- a/components/ftp/CMakeLists.txt
+++ b/components/ftp/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger task socket)
+ REQUIRES base_component task socket)
diff --git a/components/ftp/include/ftp_client.hpp b/components/ftp/include/ftp_client.hpp
index d14f05b3b..522252288 100644
--- a/components/ftp/include/ftp_client.hpp
+++ b/components/ftp/include/ftp_client.hpp
@@ -6,14 +6,14 @@
#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "tcp_socket.hpp"
#include "udp_socket.hpp"
namespace espp {
/// \brief A class which implements a simple FTP client.
-class FtpClient {
+class FtpClient : public BaseComponent {
public:
/// \brief A struct which represents an FTP response.
struct Response {
@@ -38,7 +38,8 @@ class FtpClient {
};
/// \brief Constructs a new FtpClient object.
- FtpClient() : logger_({.tag = "FtpClient", .level = Logger::Verbosity::WARN}) {}
+ FtpClient()
+ : BaseComponent("FtpClient") {}
/// \brief Connects to the FTP server.
/// \param host The hostname or IP address of the FTP server.
@@ -291,6 +292,5 @@ class FtpClient {
std::string response_;
std::string message_;
std::unique_ptr task_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/ftp/include/ftp_client_session.hpp b/components/ftp/include/ftp_client_session.hpp
index 1b38c89b6..7a014dc36 100644
--- a/components/ftp/include/ftp_client_session.hpp
+++ b/components/ftp/include/ftp_client_session.hpp
@@ -19,7 +19,7 @@
#include
#endif
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "tcp_socket.hpp"
@@ -41,15 +41,17 @@ template std::time_t to_time_t(TP tp) {
namespace espp {
/// Class representing a client that is connected to the FTP server. This
/// class is used by the FtpServer class to handle the client's requests.
-class FtpClientSession {
+class FtpClientSession : public BaseComponent {
public:
explicit FtpClientSession(int id, std::string_view local_address,
std::unique_ptr socket,
const std::filesystem::path &root_path)
- : id_(id), local_ip_address_(local_address), current_directory_(root_path),
- socket_(std::move(socket)), passive_socket_({.log_level = Logger::Verbosity::WARN}),
- logger_(
- {.tag = "FtpClientSession " + std::to_string(id), .level = Logger::Verbosity::WARN}) {
+ : BaseComponent("FtpClientSession " + std::to_string(id))
+ , id_(id)
+ , local_ip_address_(local_address)
+ , current_directory_(root_path)
+ , socket_(std::move(socket))
+ , passive_socket_({.log_level = Logger::Verbosity::WARN}) {
logger_.debug("Client session {} created", id_);
send_welcome_message();
using namespace std::placeholders;
@@ -1163,7 +1165,6 @@ class FtpClientSession {
uint16_t data_port_{0};
std::unique_ptr task_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/ftp/include/ftp_server.hpp b/components/ftp/include/ftp_server.hpp
index 7d88f472f..42a953af7 100644
--- a/components/ftp/include/ftp_server.hpp
+++ b/components/ftp/include/ftp_server.hpp
@@ -15,7 +15,7 @@
#include
#endif
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "tcp_socket.hpp"
@@ -23,7 +23,7 @@
namespace espp {
/// \brief A class that implements a FTP server.
-class FtpServer {
+class FtpServer : public BaseComponent {
public:
/// \brief A class that implements a FTP server.
/// \note The IP Address is not currently used to select the right
@@ -33,8 +33,11 @@ class FtpServer {
/// \param port The port to listen on.
/// \param root The root directory of the FTP server.
FtpServer(std::string_view ip_address, uint16_t port, const std::filesystem::path &root)
- : ip_address_(ip_address), port_(port), server_({.log_level = Logger::Verbosity::WARN}),
- root_(root), logger_({.tag = "FtpServer", .level = Logger::Verbosity::WARN}) {}
+ : BaseComponent("FtpServer")
+ , ip_address_(ip_address)
+ , port_(port)
+ , server_({.log_level = Logger::Verbosity::WARN})
+ , root_(root) {}
/// \brief Destroy the FTP server.
~FtpServer() { stop(); }
@@ -154,7 +157,5 @@ class FtpServer {
std::mutex clients_mutex_;
std::unordered_map> clients_;
-
- Logger logger_;
};
} // namespace espp
diff --git a/components/i2c/CMakeLists.txt b/components/i2c/CMakeLists.txt
index d4ce87c49..1f7ada26d 100644
--- a/components/i2c/CMakeLists.txt
+++ b/components/i2c/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES "driver" "logger"
+ REQUIRES "driver" "base_component"
)
diff --git a/components/i2c/example/CMakeLists.txt b/components/i2c/example/CMakeLists.txt
index e887c19d4..beec22e9e 100644
--- a/components/i2c/example/CMakeLists.txt
+++ b/components/i2c/example/CMakeLists.txt
@@ -11,7 +11,7 @@ set(EXTRA_COMPONENT_DIRS
set(
COMPONENTS
- "main esptool_py i2c logger"
+ "main esptool_py cli i2c logger"
CACHE STRING
"List of components to include"
)
diff --git a/components/i2c/example/main/i2c_example.cpp b/components/i2c/example/main/i2c_example.cpp
index 384d2d0d4..35aba63e7 100644
--- a/components/i2c/example/main/i2c_example.cpp
+++ b/components/i2c/example/main/i2c_example.cpp
@@ -5,45 +5,72 @@
#include "i2c.hpp"
#include "logger.hpp"
+#include "i2c_menu.hpp"
+
using namespace std::chrono_literals;
extern "C" void app_main(void) {
espp::Logger logger({.tag = "I2C Example", .level = espp::Logger::Verbosity::INFO});
logger.info("Starting");
- //! [i2c example]
- espp::I2c i2c({
- .port = I2C_NUM_0,
- .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
- .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
+
+ {
+ //! [i2c menu example]
+ espp::I2c i2c({
+ .port = I2C_NUM_0,
+ .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
+ .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
+ .log_level = espp::Logger::Verbosity::INFO,
});
+ // now make a menu for the auth object
+ I2cMenu i2c_menu(i2c);
+ cli::Cli cli(i2c_menu.get());
+ cli::SetColor();
+ cli.ExitAction([](auto &out) { out << "Goodbye and thanks for all the fish.\n"; });
+ espp::Cli input(cli);
+ input.SetInputHistorySize(10);
- // probe the bus for all addresses and store the ones that were found /
- // responded
- std::vector found_addresses;
- for (uint8_t address = 0; address < 128; address++) {
- if (i2c.probe_device(address)) {
- found_addresses.push_back(address);
- }
+ input.Start(); // As this is in the primary thread, we hold here until cli is complete.
+ //! [i2c menu example]
}
- // print out the addresses that were found
- logger.info("Found devices at addresses: {::#02x}", found_addresses);
-
- static constexpr uint8_t device_address = CONFIG_EXAMPLE_I2C_DEVICE_ADDR;
- static constexpr uint8_t register_address = CONFIG_EXAMPLE_I2C_DEVICE_REG_ADDR;
- bool device_found = i2c.probe_device(device_address);
- if (device_found) {
- logger.info("Found device with address {:#02x}", device_address);
- std::vector read_data(CONFIG_EXAMPLE_I2C_DEVICE_REG_SIZE, 0);
- bool success = i2c.read_at_register(device_address, register_address, read_data.data(), read_data.size());
- if (success) {
- logger.info("read data: {::#02x}", read_data);
+
+ {
+ //! [i2c example]
+ espp::I2c i2c({
+ .port = I2C_NUM_0,
+ .sda_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SDA_GPIO,
+ .scl_io_num = (gpio_num_t)CONFIG_EXAMPLE_I2C_SCL_GPIO,
+ });
+
+ // probe the bus for all addresses and store the ones that were found /
+ // responded
+ std::vector found_addresses;
+ for (uint8_t address = 0; address < 128; address++) {
+ if (i2c.probe_device(address)) {
+ found_addresses.push_back(address);
+ }
+ }
+ // print out the addresses that were found
+ logger.info("Found devices at addresses: {::#02x}", found_addresses);
+
+ static constexpr uint8_t device_address = CONFIG_EXAMPLE_I2C_DEVICE_ADDR;
+ static constexpr uint8_t register_address = CONFIG_EXAMPLE_I2C_DEVICE_REG_ADDR;
+ bool device_found = i2c.probe_device(device_address);
+ if (device_found) {
+ logger.info("Found device with address {:#02x}", device_address);
+ std::vector read_data(CONFIG_EXAMPLE_I2C_DEVICE_REG_SIZE, 0);
+ bool success = i2c.read_at_register(device_address, register_address, read_data.data(),
+ read_data.size());
+ if (success) {
+ logger.info("read data: {::#02x}", read_data);
+ } else {
+ logger.error("read failed");
+ }
} else {
- logger.error("read failed");
+ logger.error("Could not find device with address {:#02x}", device_address);
}
- } else {
- logger.error("Could not find device with address {:#02x}", device_address);
+ //! [i2c example]
}
- //! [i2c example]
+
logger.info("I2C example complete!");
while (true) {
diff --git a/components/i2c/example/main/i2c_menu.hpp b/components/i2c/example/main/i2c_menu.hpp
new file mode 100644
index 000000000..4314d5080
--- /dev/null
+++ b/components/i2c/example/main/i2c_menu.hpp
@@ -0,0 +1,168 @@
+#pragma once
+
+#include
+#include
+#include
+
+#include "cli.hpp"
+#include "format.hpp"
+#include "i2c.hpp"
+
+class I2cMenu {
+public:
+ explicit I2cMenu(std::reference_wrapper i2c) : i2c_(i2c) {}
+
+ std::unique_ptr get(std::string_view name = "i2c",
+ std::string_view description = "I2c menu") {
+ auto i2c_menu = std::make_unique(std::string(name), std::string(description));
+
+ // set the log verbosity for the i2c bus
+ i2c_menu->Insert(
+ "log",
+ [this](std::ostream &out, const std::string &verbosity) -> void {
+ if (verbosity == "debug") {
+ i2c_.get().set_log_level(espp::Logger::Verbosity::DEBUG);
+ } else if (verbosity == "info") {
+ i2c_.get().set_log_level(espp::Logger::Verbosity::INFO);
+ } else if (verbosity == "warn") {
+ i2c_.get().set_log_level(espp::Logger::Verbosity::WARN);
+ } else if (verbosity == "error") {
+ i2c_.get().set_log_level(espp::Logger::Verbosity::ERROR);
+ } else if (verbosity == "none") {
+ i2c_.get().set_log_level(espp::Logger::Verbosity::NONE);
+ } else {
+ out << "Invalid log level.\n";
+ return;
+ }
+ out << fmt::format("Set I2c log level to {}.\n", verbosity);
+ },
+ "Set the log verbosity for the I2c bus.");
+
+ // scan the bus for devices
+ i2c_menu->Insert(
+ "scan",
+ [this](std::ostream &out) -> void {
+ out << "Scanning I2c bus...\n";
+ std::vector found_addresses;
+ for (uint8_t address = 1; address < 128; address++) {
+ if (i2c_.get().probe_device(address)) {
+ found_addresses.push_back(address);
+ }
+ }
+ if (found_addresses.empty()) {
+ out << "No devices found.\n";
+ } else {
+ std::string log = fmt::format("Found devices at addresses: {::#02x}", found_addresses);
+ out << log << "\n";
+ }
+ },
+ "Scan the I2c bus for devices.");
+
+ // probe for a device (hexadecimal address string)
+ i2c_menu->Insert(
+ "probe", {"address (hex)"},
+ [this](std::ostream &out, const std::string &address_string) -> void {
+ // convert address_string to a uint8_t
+ uint8_t address = std::stoi(address_string, nullptr, 16);
+ if (i2c_.get().probe_device(address)) {
+ out << fmt::format("Device found at address {:#02x}.\n", address);
+ } else {
+ out << fmt::format("No device found at address {:#02x}.\n", address);
+ }
+ },
+ "Probe for a device at a specific address, given as a hexadecimal string.");
+
+ // read from a device
+ i2c_menu->Insert(
+ "read", {"address (hex)", "register"},
+ [this](std::ostream &out, const std::string &address_string, uint8_t reg) -> void {
+ // convert address_string to a uint8_t
+ uint8_t address = std::stoi(address_string, nullptr, 16);
+ uint8_t data;
+ std::string log;
+ if (i2c_.get().read_at_register(address, reg, &data, 1)) {
+ log = fmt::format("Read from address {:#02x} at register {:#02x}: {:#02x}", address,
+ reg, data);
+ } else {
+ log =
+ fmt::format("Error reading from address {:#02x} at register {:#02x}", address, reg);
+ }
+ out << log << "\n";
+ },
+ "Read a byte from a device at a specific address and register.");
+
+ // read from a device
+ i2c_menu->Insert(
+ "read", {"address (hex)", "register", "length (number of bytes to read)"},
+ [this](std::ostream &out, const std::string &address_string, uint8_t reg,
+ uint8_t len) -> void {
+ // convert address_string to a uint8_t
+ uint8_t address = std::stoi(address_string, nullptr, 16);
+ std::vector data(len);
+ std::string log;
+ if (i2c_.get().read_at_register_vector(address, reg, data)) {
+ log = fmt::format("Read {} bytes from address {:#02x} at register {:#02x}: {::#02x}",
+ data.size(), address, reg, data);
+ } else {
+ log =
+ fmt::format("Error reading from address {:#02x} at register {:#02x}", address, reg);
+ }
+ out << log << "\n";
+ },
+ "Read len bytes from a device at a specific address and register.");
+
+ // write to a device
+ i2c_menu->Insert(
+ "write", {"address (hex)", "register", "data byte"},
+ [this](std::ostream &out, const std::string &address_string, uint8_t reg,
+ uint8_t data) -> void {
+ // convert address_string to a uint8_t
+ uint8_t address = std::stoi(address_string, nullptr, 16);
+ std::vector data_vec = {reg, data};
+ std::string log;
+ if (i2c_.get().write_vector(address, data_vec)) {
+ log = fmt::format("Wrote data {:#02x} to address {:#02x} at register {:#02x}", data,
+ address, reg);
+ } else {
+ log = fmt::format("Error writing data {:#02x} to address {:#02x} at register {:#02x}",
+ data, address, reg);
+ }
+ out << log << "\n";
+ },
+ "Write a byte to a device at a specific address and register.");
+
+ // write to a device
+ i2c_menu->Insert(
+ "write", {"address (hex)", "register (hex)", "data byte (hex)", "data byte (hex)", "..."},
+ [this](std::ostream &out, const std::vector &args) -> void {
+ // parse the args into address, reg, and data
+ if (args.size() < 3) {
+ out << "Not enough arguments.\n";
+ return;
+ }
+ // convert address_string to a uint8_t
+ uint8_t address = std::stoi(args[0], nullptr, 16);
+ // remove the address byte (first element) and convert the rest of the
+ // vector of strings into a vector of bytes
+ std::vector data;
+ std::transform(args.begin() + 1, args.end(), std::back_inserter(data),
+ [](const std::string &s) -> uint8_t { return std::stoi(s, nullptr, 0); });
+ uint8_t reg = data[0];
+ std::string log;
+ if (i2c_.get().write_vector(address, data)) {
+ log = fmt::format("Wrote {} bytes to address {:#02x} at register {:#02x}: {::#02x}",
+ data.size(), address, reg, data);
+ } else {
+ log = fmt::format("Error writing {} bytes to address {:#02x} at register {:#02x}",
+ data.size(), address, reg);
+ }
+ out << log << "\n";
+ },
+ "Write bytes to a device at a specific address and register.");
+
+ return i2c_menu;
+ }
+
+protected:
+ std::reference_wrapper i2c_;
+};
diff --git a/components/i2c/example/sdkconfig.defaults b/components/i2c/example/sdkconfig.defaults
index c3667f3e3..4ff973154 100644
--- a/components/i2c/example/sdkconfig.defaults
+++ b/components/i2c/example/sdkconfig.defaults
@@ -2,3 +2,6 @@
#
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=4096
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
+
+# the cli library requires exceptions right now...
+CONFIG_COMPILER_CXX_EXCEPTIONS=y
diff --git a/components/i2c/example/sdkconfig.defaults.esp32s3 b/components/i2c/example/sdkconfig.defaults.esp32s3
new file mode 100644
index 000000000..eaee743c2
--- /dev/null
+++ b/components/i2c/example/sdkconfig.defaults.esp32s3
@@ -0,0 +1,3 @@
+# on the ESP32S3, which has native USB, we need to set the console so that the
+# CLI can be configured correctly:
+CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
diff --git a/components/i2c/include/i2c.hpp b/components/i2c/include/i2c.hpp
index a1905b3ce..fe2136acb 100644
--- a/components/i2c/include/i2c.hpp
+++ b/components/i2c/include/i2c.hpp
@@ -1,10 +1,13 @@
#pragma once
#include
+#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
+
+#include "i2c_format_helpers.hpp"
namespace espp {
/// @brief I2C driver
@@ -13,7 +16,7 @@ namespace espp {
///
/// \section Example
/// \snippet i2c_example.cpp i2c example
-class I2c {
+class I2c : public espp::BaseComponent {
public:
/// Configuration for I2C
struct Config {
@@ -30,8 +33,7 @@ class I2c {
/// Construct I2C driver
/// \param config Configuration for I2C
- explicit I2c(const Config &config)
- : config_(config), logger_({.tag = "I2C", .level = config.log_level}) {
+ explicit I2c(const Config &config) : BaseComponent("I2C", config.log_level), config_(config) {
if (config.auto_init) {
std::error_code ec;
init(ec);
@@ -41,6 +43,15 @@ class I2c {
}
}
+ /// Destructor
+ ~I2c() {
+ std::error_code ec;
+ deinit(ec);
+ if (ec) {
+ logger_.error("deinit failed");
+ }
+ }
+
/// Initialize I2C driver
void init(std::error_code &ec) {
if (initialized_) {
@@ -71,6 +82,8 @@ class I2c {
return;
}
+ logger_.info("I2C initialized on port {}", config_.port);
+
initialized_ = true;
}
@@ -78,7 +91,8 @@ class I2c {
void deinit(std::error_code &ec) {
if (!initialized_) {
logger_.warn("not initialized");
- ec = std::make_error_code(std::errc::protocol_error);
+ // dont make this an error
+ ec.clear();
return;
}
@@ -90,6 +104,8 @@ class I2c {
return;
}
+ ec.clear();
+ logger_.info("I2C deinitialized on port {}", config_.port);
initialized_ = false;
}
@@ -98,12 +114,13 @@ class I2c {
/// \param data Data to write
/// \param data_len Length of data to write
/// \return True if successful
- bool write(uint8_t dev_addr, uint8_t *data, size_t data_len) {
+ bool write(const uint8_t dev_addr, const uint8_t *data, const size_t data_len) {
if (!initialized_) {
logger_.error("not initialized");
return false;
}
+ logger_.debug("write {} bytes to address {:#02x}", data_len, dev_addr);
std::lock_guard lock(mutex_);
auto err = i2c_master_write_to_device(config_.port, dev_addr, data, data_len,
config_.timeout_ms / portTICK_PERIOD_MS);
@@ -115,6 +132,14 @@ class I2c {
return true;
}
+ /// Write data to I2C device
+ /// \param dev_addr I2C device address
+ /// \param data Data to write
+ /// \return True if successful
+ bool write_vector(const uint8_t dev_addr, const std::vector &data) {
+ return write(dev_addr, data.data(), data.size());
+ }
+
/// Write to and read data from I2C device
/// \param dev_addr I2C device address
/// \param write_data Data to write
@@ -122,13 +147,15 @@ class I2c {
/// \param read_data Data to read
/// \param read_size Length of data to read
/// \return True if successful
- bool write_read(uint8_t dev_addr, uint8_t *write_data, size_t write_size, uint8_t *read_data,
- size_t read_size) {
+ bool write_read(const uint8_t dev_addr, const uint8_t *write_data, const size_t write_size,
+ uint8_t *read_data, size_t read_size) {
if (!initialized_) {
logger_.error("not initialized");
return false;
}
+ logger_.debug("write {} bytes and read {} bytes from address {:#02x}", write_size, read_size,
+ dev_addr);
std::lock_guard lock(mutex_);
auto err =
i2c_master_write_read_device(config_.port, dev_addr, write_data, write_size, read_data,
@@ -141,18 +168,32 @@ class I2c {
return true;
}
+ /// Write data to and read data from I2C device
+ /// \param dev_addr I2C device address
+ /// \param write_data Data to write
+ /// \param read_data Data to read
+ /// \return True if successful
+ bool write_read_vector(const uint8_t dev_addr, const std::vector &write_data,
+ std::vector &read_data) {
+ return write_read(dev_addr, write_data.data(), write_data.size(), read_data.data(),
+ read_data.size());
+ }
+
/// Read data from I2C device at register
/// \param dev_addr I2C device address
/// \param reg_addr Register address
/// \param data Data to read
/// \param data_len Length of data to read
/// \return True if successful
- bool read_at_register(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, size_t data_len) {
+ bool read_at_register(const uint8_t dev_addr, const uint8_t reg_addr, uint8_t *data,
+ size_t data_len) {
if (!initialized_) {
logger_.error("not initialized");
return false;
}
+ logger_.debug("read {} bytes from address {:#02x} at register {}", data_len, dev_addr,
+ reg_addr);
std::lock_guard lock(mutex_);
auto err = i2c_master_write_read_device(config_.port, dev_addr, ®_addr, 1, data, data_len,
config_.timeout_ms / portTICK_PERIOD_MS);
@@ -165,17 +206,28 @@ class I2c {
return true;
}
+ /// Read data from I2C device at register
+ /// \param dev_addr I2C device address
+ /// \param reg_addr Register address
+ /// \param data Data to read
+ /// \return True if successful
+ bool read_at_register_vector(const uint8_t dev_addr, const uint8_t reg_addr,
+ std::vector &data) {
+ return read_at_register(dev_addr, reg_addr, data.data(), data.size());
+ }
+
/// Read data from I2C device
/// \param dev_addr I2C device address
/// \param data Data to read
/// \param data_len Length of data to read
/// \return True if successful
- bool read(uint8_t dev_addr, uint8_t *data, size_t data_len) {
+ bool read(const uint8_t dev_addr, uint8_t *data, size_t data_len) {
if (!initialized_) {
logger_.error("not initialized");
return false;
}
+ logger_.debug("read {} bytes from address {:#02x}", data_len, dev_addr);
std::lock_guard lock(mutex_);
auto err = i2c_master_read_from_device(config_.port, dev_addr, data, data_len,
config_.timeout_ms / portTICK_PERIOD_MS);
@@ -187,6 +239,14 @@ class I2c {
return true;
}
+ /// Read data from I2C device
+ /// \param dev_addr I2C device address
+ /// \param data Data to read
+ /// \return True if successful
+ bool read_vector(const uint8_t dev_addr, std::vector &data) {
+ return read(dev_addr, data.data(), data.size());
+ }
+
/// Probe I2C device
/// \param dev_addr I2C device address
/// \return True if successful
@@ -194,8 +254,9 @@ class I2c {
/// This function sends a start condition, writes the device address, and then
/// sends a stop condition. If the device acknowledges the address, then it is
/// present on the bus.
- bool probe_device(uint8_t dev_addr) {
+ bool probe_device(const uint8_t dev_addr) {
bool success = false;
+ logger_.debug("probe device {:#02x}", dev_addr);
std::lock_guard lock(mutex_);
auto cmd = i2c_cmd_link_create();
i2c_master_start(cmd);
@@ -212,6 +273,5 @@ class I2c {
Config config_;
bool initialized_ = false;
std::mutex mutex_;
- espp::Logger logger_;
};
} // namespace espp
diff --git a/components/i2c/include/i2c_format_helpers.hpp b/components/i2c/include/i2c_format_helpers.hpp
new file mode 100644
index 000000000..66f0958f9
--- /dev/null
+++ b/components/i2c/include/i2c_format_helpers.hpp
@@ -0,0 +1,21 @@
+#pragma once
+
+#include
+
+#include "format.hpp"
+
+// for printing of i2c_port_t with libfmt
+template <> struct fmt::formatter {
+ constexpr auto parse(format_parse_context &ctx) { return ctx.begin(); }
+
+ template auto format(const i2c_port_t &p, FormatContext &ctx) {
+ switch (p) {
+ case I2C_NUM_0:
+ return fmt::format_to(ctx.out(), "I2C_NUM_0");
+ case I2C_NUM_1:
+ return fmt::format_to(ctx.out(), "I2C_NUM_1");
+ default:
+ return fmt::format_to(ctx.out(), "Unknown");
+ }
+ }
+};
diff --git a/components/input_drivers/CMakeLists.txt b/components/input_drivers/CMakeLists.txt
index f81d5861d..e2dd8771d 100644
--- a/components/input_drivers/CMakeLists.txt
+++ b/components/input_drivers/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger )
+ REQUIRES base_component )
diff --git a/components/input_drivers/include/encoder_input.hpp b/components/input_drivers/include/encoder_input.hpp
index 0f70a91ad..01d64f30f 100644
--- a/components/input_drivers/include/encoder_input.hpp
+++ b/components/input_drivers/include/encoder_input.hpp
@@ -6,14 +6,14 @@
#include "lvgl.h"
#include "sdkconfig.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
* @brief Light wrapper around LVGL input device driver, specifically
* designed for encoders with optional home buttons.
*/
-class EncoderInput {
+class EncoderInput : public BaseComponent {
public:
typedef std::function read_fn;
@@ -33,7 +33,8 @@ class EncoderInput {
* @param config Configuration structure for the EncoderInput.
*/
explicit EncoderInput(const Config &config)
- : read_(config.read), logger_({.tag = "EncoderInput", .level = config.log_level}) {
+ : BaseComponent("EncoderInput", config.log_level)
+ , read_(config.read) {
init();
}
@@ -118,6 +119,5 @@ class EncoderInput {
lv_indev_t *indev_encoder_;
lv_indev_drv_t indev_drv_btn_;
lv_indev_t *indev_button_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/input_drivers/include/keypad_input.hpp b/components/input_drivers/include/keypad_input.hpp
index 4f1a671c1..938429d17 100644
--- a/components/input_drivers/include/keypad_input.hpp
+++ b/components/input_drivers/include/keypad_input.hpp
@@ -6,14 +6,14 @@
#include "lvgl.h"
#include "sdkconfig.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
* @brief Light wrapper around LVGL input device driver, specifically
* designed for keypads.
*/
-class KeypadInput {
+class KeypadInput : public BaseComponent {
public:
typedef std::function
@@ -35,7 +35,8 @@ class KeypadInput {
* @param config Configuration structure for the KeypadInput.
*/
explicit KeypadInput(const Config &config)
- : read_(config.read), logger_({.tag = "KeypadInput", .level = config.log_level}) {
+ : BaseComponent("KeypadInput", config.log_level)
+ , read_(config.read) {
init();
}
@@ -104,6 +105,5 @@ class KeypadInput {
read_fn read_;
lv_indev_drv_t indev_drv_keypad_;
lv_indev_t *indev_keypad_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/input_drivers/include/touchpad_input.hpp b/components/input_drivers/include/touchpad_input.hpp
index 928eb84e0..1e93e204d 100644
--- a/components/input_drivers/include/touchpad_input.hpp
+++ b/components/input_drivers/include/touchpad_input.hpp
@@ -6,14 +6,14 @@
#include "lvgl.h"
#include "sdkconfig.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
* @brief Light wrapper around LVGL input device driver, specifically
* designed for touchpads with optional home buttons.
*/
-class TouchpadInput {
+class TouchpadInput : public BaseComponent {
public:
/**
* @brief Function prototype for getting the latest input data from the
@@ -48,8 +48,11 @@ class TouchpadInput {
* @param config Configuration structure for the TouchpadInput.
*/
explicit TouchpadInput(const Config &config)
- : touchpad_read_(config.touchpad_read), swap_xy_(config.swap_xy), invert_x_(config.invert_x),
- invert_y_(config.invert_y), logger_({.tag = "TouchpadInput", .level = config.log_level}) {
+ : BaseComponent("TouchpadInput", config.log_level)
+ , touchpad_read_(config.touchpad_read)
+ , swap_xy_(config.swap_xy)
+ , invert_x_(config.invert_x)
+ , invert_y_(config.invert_y) {
init();
}
@@ -155,6 +158,5 @@ class TouchpadInput {
lv_indev_t *indev_touchpad_;
lv_indev_drv_t indev_drv_btn_;
lv_indev_t *indev_button_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/joystick/CMakeLists.txt b/components/joystick/CMakeLists.txt
index 851edd130..e24070f55 100644
--- a/components/joystick/CMakeLists.txt
+++ b/components/joystick/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger math)
+ REQUIRES base_component math)
diff --git a/components/joystick/include/joystick.hpp b/components/joystick/include/joystick.hpp
index 64235f128..2d36a033e 100644
--- a/components/joystick/include/joystick.hpp
+++ b/components/joystick/include/joystick.hpp
@@ -2,7 +2,7 @@
#include
-#include "logger.hpp"
+#include "base_component.hpp"
#include "range_mapper.hpp"
#include "vector2d.hpp"
@@ -13,7 +13,7 @@ namespace espp {
* \section joystick_ex1 ADC Joystick Example
* \snippet joystick_example.cpp adc joystick example
*/
-class Joystick {
+class Joystick : public BaseComponent {
public:
/**
* @brief Types of deadzones the joystick can have.
@@ -61,9 +61,12 @@ class Joystick {
* @param config Config structure with initialization information.
*/
explicit Joystick(const Config &config)
- : x_mapper_(config.x_calibration), y_mapper_(config.y_calibration),
- deadzone_(config.deadzone), deadzone_radius_(config.deadzone_radius),
- get_values_(config.get_values), logger_({.tag = "Joystick", .level = config.log_level}) {}
+ : BaseComponent("Joystick", config.log_level)
+ , x_mapper_(config.x_calibration)
+ , y_mapper_(config.y_calibration)
+ , deadzone_(config.deadzone)
+ , deadzone_radius_(config.deadzone_radius)
+ , get_values_(config.get_values) {}
/**
* @brief Sets the deadzone type and radius.
@@ -164,7 +167,6 @@ class Joystick {
Deadzone deadzone_;
float deadzone_radius_;
get_values_fn get_values_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/led/CMakeLists.txt b/components/led/CMakeLists.txt
index 86f338bb0..4e90d84c0 100644
--- a/components/led/CMakeLists.txt
+++ b/components/led/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger driver)
+ REQUIRES base_component driver)
diff --git a/components/led/include/led.hpp b/components/led/include/led.hpp
index 88c28a125..d1228b57b 100644
--- a/components/led/include/led.hpp
+++ b/components/led/include/led.hpp
@@ -9,7 +9,7 @@
#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -21,7 +21,7 @@ namespace espp {
* \section led_ex2 Breathing LED Example
* \snippet led_example.cpp breathing led example
*/
-class Led {
+class Led : public BaseComponent {
public:
/**
* Represents one LED channel.
@@ -61,9 +61,10 @@ class Led {
* @param config The configuration structure for the LEDC subsystem.
*/
explicit Led(const Config &config)
- : duty_resolution_(config.duty_resolution),
- max_raw_duty_((uint32_t)(std::pow(2, (int)duty_resolution_) - 1)),
- channels_(config.channels), logger_({.tag = "Led", .level = config.log_level}) {
+ : BaseComponent("Led", config.log_level)
+ , duty_resolution_(config.duty_resolution)
+ , max_raw_duty_((uint32_t)(std::pow(2, (int)duty_resolution_) - 1))
+ , channels_(config.channels) {
logger_.info("Initializing timer");
ledc_timer_config_t ledc_timer;
@@ -242,6 +243,5 @@ class Led {
uint32_t max_raw_duty_;
std::vector fade_semaphores_;
std::vector channels_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/led_strip/CMakeLists.txt b/components/led_strip/CMakeLists.txt
index 6107a4e58..9faa14ad2 100644
--- a/components/led_strip/CMakeLists.txt
+++ b/components/led_strip/CMakeLists.txt
@@ -1,5 +1,5 @@
idf_component_register(
INCLUDE_DIRS "include"
SRC_DIRS "src"
- REQUIRES "logger" "color"
+ REQUIRES "base_component" "color"
)
diff --git a/components/led_strip/include/led_strip.hpp b/components/led_strip/include/led_strip.hpp
index b28dfdde9..93915f8ed 100644
--- a/components/led_strip/include/led_strip.hpp
+++ b/components/led_strip/include/led_strip.hpp
@@ -7,8 +7,8 @@
#include
#include
+#include "base_component.hpp"
#include "color.hpp"
-#include "logger.hpp"
namespace espp {
/// \brief Class to control LED strips
@@ -31,7 +31,7 @@ namespace espp {
///
/// \section led_strip_ex1 Example 1: APA102 via SPI
/// \snippet led_strip_example.cpp led strip ex1
-class LedStrip {
+class LedStrip : public BaseComponent {
public:
/// \brief Function to write data to the strip
/// \details This function is used to write data to the strip. It
@@ -75,9 +75,11 @@ class LedStrip {
/// \brief Constructor
/// \param config Configuration for the LedStrip class
explicit LedStrip(const Config &config)
- : num_leds_(config.num_leds), send_brightness_(config.send_brightness),
- byte_order_(config.byte_order), write_(config.write),
- logger_({.tag = "LedStrip", .level = config.log_level}) {
+ : BaseComponent("LedStrip", config.log_level)
+ , num_leds_(config.num_leds)
+ , send_brightness_(config.send_brightness)
+ , byte_order_(config.byte_order)
+ , write_(config.write) {
// set the color data size
pixel_size_ = send_brightness_ ? 4 : 3;
data_.resize(num_leds_ * pixel_size_ + config.start_frame.size() + config.end_frame.size());
@@ -254,6 +256,5 @@ class LedStrip {
size_t end_offset_{0};
std::vector data_;
write_fn write_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/logger/include/logger.hpp b/components/logger/include/logger.hpp
index 18481e647..25177838d 100644
--- a/components/logger/include/logger.hpp
+++ b/components/logger/include/logger.hpp
@@ -50,7 +50,9 @@ class Logger {
* @param config configuration for the logger.
*/
explicit Logger(const Config &config)
- : tag_(config.tag), rate_limit_(config.rate_limit), level_(config.level) {}
+ : tag_(config.tag)
+ , rate_limit_(config.rate_limit)
+ , level_(config.level) {}
/**
* @brief Change the verbosity for the logger. \sa Logger::Verbosity
@@ -67,6 +69,13 @@ class Logger {
tag_ = tag;
}
+ /**
+ * @brief Change the rate limit for the logger.
+ * @param rate_limit The new rate limit.
+ * @note Only calls that have _rate_limited suffixed will be rate limited.
+ */
+ void set_rate_limit(const std::chrono::duration rate_limit) { rate_limit_ = rate_limit; }
+
/**
* @brief Format args into string according to format string. From:
* https://en.cppreference.com/w/cpp/utility/format/format
diff --git a/components/monitor/CMakeLists.txt b/components/monitor/CMakeLists.txt
index 6aa80205c..6a7b3ecc5 100644
--- a/components/monitor/CMakeLists.txt
+++ b/components/monitor/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- PRIV_REQUIRES logger task)
+ PRIV_REQUIRES base_component task)
diff --git a/components/monitor/include/task_monitor.hpp b/components/monitor/include/task_monitor.hpp
index 138285d65..a74658321 100644
--- a/components/monitor/include/task_monitor.hpp
+++ b/components/monitor/include/task_monitor.hpp
@@ -4,7 +4,7 @@
#include "sdkconfig.h"
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "esp_freertos_hooks.h"
@@ -34,7 +34,7 @@ namespace espp {
* \section task_monitor_ex2 get_latest_info() Example
* \snippet monitor_example.cpp get_latest_info example
*/
-class TaskMonitor {
+class TaskMonitor : public BaseComponent {
public:
struct Config {
std::chrono::duration period; /**< Period (s) the TaskMonitor::task_callback runs at. */
@@ -43,7 +43,8 @@ class TaskMonitor {
};
explicit TaskMonitor(const Config &config)
- : period_(config.period), logger_({.tag = "TaskMonitor"}) {
+ : BaseComponent("TaskMonitor")
+ , period_(config.period) {
#if CONFIG_FREERTOS_USE_TRACE_FACILITY && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS
using namespace std::placeholders;
task_ = Task::make_unique({.name = "TaskMonitor Task",
@@ -164,7 +165,6 @@ class TaskMonitor {
}
std::chrono::duration period_;
- Logger logger_;
std::unique_ptr task_;
};
} // namespace espp
diff --git a/components/pid/CMakeLists.txt b/components/pid/CMakeLists.txt
index 1d8b9a5e8..704e9cb79 100644
--- a/components/pid/CMakeLists.txt
+++ b/components/pid/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger)
+ REQUIRES base_component)
diff --git a/components/pid/include/pid.hpp b/components/pid/include/pid.hpp
index 4fd49c685..9eda15c59 100644
--- a/components/pid/include/pid.hpp
+++ b/components/pid/include/pid.hpp
@@ -4,7 +4,7 @@
#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -19,7 +19,7 @@ namespace espp {
* \section pid_ex2 Complex PID Example
* \snippet pid_example.cpp complex pid example
*/
-class Pid {
+class Pid : public BaseComponent {
public:
struct Config {
float kp; /**< Proportional gain. */
@@ -42,8 +42,8 @@ class Pid {
* @brief Create the PID controller.
*/
explicit Pid(const Config &config)
- : prev_ts_(std::chrono::high_resolution_clock::now()),
- logger_({.tag = "PID", .level = config.log_level}) {
+ : BaseComponent("PID", config.log_level)
+ , prev_ts_(std::chrono::high_resolution_clock::now()) {
change_gains(config);
}
@@ -157,7 +157,6 @@ class Pid {
std::atomic integrator_{0};
std::chrono::time_point prev_ts_;
std::recursive_mutex mutex_; ///< For protecting the config
- Logger logger_;
};
} // namespace espp
diff --git a/components/rmt/CMakeLists.txt b/components/rmt/CMakeLists.txt
index 1e4d0cfcb..a069fc182 100644
--- a/components/rmt/CMakeLists.txt
+++ b/components/rmt/CMakeLists.txt
@@ -1,4 +1,4 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger driver
+ REQUIRES base_component driver
)
diff --git a/components/rmt/include/rmt.hpp b/components/rmt/include/rmt.hpp
index 78c275935..fa6795eec 100644
--- a/components/rmt/include/rmt.hpp
+++ b/components/rmt/include/rmt.hpp
@@ -4,7 +4,7 @@
#include
-#include "logger.hpp"
+#include "base_component.hpp"
#include "rmt_encoder.hpp"
namespace espp {
@@ -20,7 +20,7 @@ namespace espp {
///
/// \section rmt_ex1 Example 1: Transmitting data
/// \snippet rmt_example.cpp rmt example
-class Rmt {
+class Rmt : public BaseComponent {
public:
/// \brief Configuration for the RMT class
struct Config {
@@ -39,7 +39,8 @@ class Rmt {
/// \brief Constructor
/// \param config Configuration for this class
- explicit Rmt(const Config &config) : logger_({.tag = "RMT", .level = config.log_level}) {
+ explicit Rmt(const Config &config)
+ : BaseComponent("RMT", config.log_level) {
init(config);
}
@@ -118,7 +119,5 @@ class Rmt {
rmt_channel_handle_t channel_; ///< RMT channel handle
std::unique_ptr encoder_;
-
- Logger logger_; ///< Logger for this class
};
} // namespace espp
diff --git a/components/rtsp/CMakeLists.txt b/components/rtsp/CMakeLists.txt
index c0119cae2..bf0d7d50b 100644
--- a/components/rtsp/CMakeLists.txt
+++ b/components/rtsp/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger task socket)
+ REQUIRES base_component task socket)
diff --git a/components/rtsp/include/rtsp_client.hpp b/components/rtsp/include/rtsp_client.hpp
index 2d8fb5c6d..30b3c3685 100644
--- a/components/rtsp/include/rtsp_client.hpp
+++ b/components/rtsp/include/rtsp_client.hpp
@@ -5,7 +5,7 @@
#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
#include "tcp_socket.hpp"
#include "udp_socket.hpp"
@@ -25,7 +25,7 @@ namespace espp {
///
/// \section RtspClient Example
/// \snippet rtsp_example.cpp rtsp_client_example
-class RtspClient {
+class RtspClient : public BaseComponent {
public:
/// Function type for the callback to call when a JPEG frame is received
using jpeg_frame_callback_t = std::function jpeg_frame)>;
@@ -45,13 +45,15 @@ class RtspClient {
/// Constructor
/// \param config The configuration for the RTSP client
explicit RtspClient(const Config &config)
- : server_address_(config.server_address), rtsp_port_(config.rtsp_port),
- rtsp_socket_({.log_level = espp::Logger::Verbosity::WARN}),
- rtp_socket_({.log_level = espp::Logger::Verbosity::WARN}),
- rtcp_socket_({.log_level = espp::Logger::Verbosity::WARN}),
- on_jpeg_frame_(config.on_jpeg_frame), cseq_(0),
- path_("rtsp://" + server_address_ + ":" + std::to_string(rtsp_port_) + config.path),
- logger_({.tag = "RtspClient", .level = config.log_level}) {}
+ : BaseComponent("RtspClient", config.log_level)
+ , server_address_(config.server_address)
+ , rtsp_port_(config.rtsp_port)
+ , rtsp_socket_({.log_level = espp::Logger::Verbosity::WARN})
+ , rtp_socket_({.log_level = espp::Logger::Verbosity::WARN})
+ , rtcp_socket_({.log_level = espp::Logger::Verbosity::WARN})
+ , on_jpeg_frame_(config.on_jpeg_frame)
+ , cseq_(0)
+ , path_("rtsp://" + server_address_ + ":" + std::to_string(rtsp_port_) + config.path) {}
/// Destructor
/// Disconnects from the RTSP server
@@ -480,8 +482,6 @@ class RtspClient {
int video_payload_type_ = 0;
std::string path_;
std::string session_id_;
-
- espp::Logger logger_;
};
} // namespace espp
diff --git a/components/rtsp/include/rtsp_server.hpp b/components/rtsp/include/rtsp_server.hpp
index 15d40eec5..205a74d8a 100644
--- a/components/rtsp/include/rtsp_server.hpp
+++ b/components/rtsp/include/rtsp_server.hpp
@@ -11,7 +11,7 @@
#include
#endif
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "tcp_socket.hpp"
#include "udp_socket.hpp"
@@ -32,7 +32,7 @@ namespace espp {
///
/// \section RtspServer example
/// \snippet rtsp_example.cpp rtsp_server_example
-class RtspServer {
+class RtspServer : public BaseComponent {
public:
/// @brief Configuration for the RTSP server
struct Config {
@@ -50,10 +50,12 @@ class RtspServer {
/// @brief Construct an RTSP server
/// @param config The configuration for the RTSP server
explicit RtspServer(const Config &config)
- : server_address_(config.server_address), port_(config.port), path_(config.path),
- rtsp_socket_({.log_level = espp::Logger::Verbosity::WARN}),
- max_data_size_(config.max_data_size),
- logger_({.tag = "RTSP Server", .level = config.log_level}) {
+ : BaseComponent("RTSP Server", config.log_level)
+ , server_address_(config.server_address)
+ , port_(config.port)
+ , path_(config.path)
+ , rtsp_socket_({.log_level = espp::Logger::Verbosity::WARN})
+ , max_data_size_(config.max_data_size) {
// generate a random ssrc
#if defined(ESP_PLATFORM)
ssrc_ = esp_random();
@@ -327,7 +329,6 @@ class RtspServer {
std::mutex session_mutex_;
std::unordered_map> sessions_;
- Logger logger_;
std::unique_ptr accept_task_;
std::unique_ptr session_task_;
};
diff --git a/components/rtsp/include/rtsp_session.hpp b/components/rtsp/include/rtsp_session.hpp
index 443a138f5..51b61d826 100644
--- a/components/rtsp/include/rtsp_session.hpp
+++ b/components/rtsp/include/rtsp_session.hpp
@@ -11,7 +11,7 @@
#include
#endif
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
#include "tcp_socket.hpp"
#include "udp_socket.hpp"
@@ -22,7 +22,7 @@
namespace espp {
/// Class that reepresents an RTSP session, which is uniquely identified by a
/// session id and sends frame data over RTP and RTCP to the client
-class RtspSession {
+class RtspSession : public BaseComponent {
public:
/// Configuration for the RTSP session
struct Config {
@@ -35,12 +35,16 @@ class RtspSession {
/// @param control_socket The control socket of the session
/// @param config The configuration of the session
explicit RtspSession(std::unique_ptr control_socket, const Config &config)
- : control_socket_(std::move(control_socket)),
- rtp_socket_({.log_level = Logger::Verbosity::WARN}),
- rtcp_socket_({.log_level = Logger::Verbosity::WARN}), session_id_(generate_session_id()),
- server_address_(config.server_address), rtsp_path_(config.rtsp_path),
- client_address_(control_socket_->get_remote_info().address),
- logger_({.tag = "RtspSession " + std::to_string(session_id_), .level = config.log_level}) {
+ : BaseComponent("RtspSession", config.log_level)
+ , control_socket_(std::move(control_socket))
+ , rtp_socket_({.log_level = Logger::Verbosity::WARN})
+ , rtcp_socket_({.log_level = Logger::Verbosity::WARN})
+ , session_id_(generate_session_id())
+ , server_address_(config.server_address)
+ , rtsp_path_(config.rtsp_path)
+ , client_address_(control_socket_->get_remote_info().address) {
+ // set the logger tag to include the session id
+ logger_.set_tag("RtspSession " + std::to_string(session_id_));
// start the session task to handle RTSP commands
using namespace std::placeholders;
control_task_ = std::make_unique(Task::Config{
@@ -515,7 +519,5 @@ class RtspSession {
int client_rtcp_port_;
std::unique_ptr control_task_;
-
- Logger logger_;
};
} // namespace espp
diff --git a/components/socket/CMakeLists.txt b/components/socket/CMakeLists.txt
index 07bc8baa9..dd3a9d46e 100644
--- a/components/socket/CMakeLists.txt
+++ b/components/socket/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- PRIV_REQUIRES logger task lwip)
+ PRIV_REQUIRES base_component task lwip)
diff --git a/components/socket/include/socket.hpp b/components/socket/include/socket.hpp
index bfde73e1f..728cf4e8e 100644
--- a/components/socket/include/socket.hpp
+++ b/components/socket/include/socket.hpp
@@ -16,15 +16,15 @@
#include
+#include "base_component.hpp"
#include "format.hpp"
-#include "logger.hpp"
namespace espp {
/**
* @brief Class for a generic socket with some helper functions for
* configuring the socket.
*/
-class Socket {
+class Socket : public BaseComponent {
public:
enum class Type : int {
RAW = SOCK_RAW, /**< Only IP headers, no TCP or UDP headers as well. */
@@ -156,7 +156,8 @@ class Socket {
* @param logger_config configuration for the logger associated with the
* socket.
*/
- explicit Socket(int socket_fd, const Logger::Config &logger_config) : logger_(logger_config) {
+ explicit Socket(int socket_fd, const Logger::Config &logger_config)
+ : BaseComponent(logger_config) {
socket_ = socket_fd;
}
@@ -166,7 +167,8 @@ class Socket {
* @param logger_config configuration for the logger associated with the
* socket.
*/
- explicit Socket(Type type, const Logger::Config &logger_config) : logger_(logger_config) {
+ explicit Socket(Type type, const Logger::Config &logger_config)
+ : BaseComponent(logger_config) {
init(type);
}
@@ -416,7 +418,6 @@ class Socket {
static constexpr int ip_protocol_{IPPROTO_IP};
int socket_;
- Logger logger_;
};
} // namespace espp
diff --git a/components/task/CMakeLists.txt b/components/task/CMakeLists.txt
index e31f5e4b2..0d74279ec 100644
--- a/components/task/CMakeLists.txt
+++ b/components/task/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger pthread)
+ REQUIRES base_component pthread)
diff --git a/components/task/include/task.hpp b/components/task/include/task.hpp
index 785b0ccc4..5415a7b0c 100644
--- a/components/task/include/task.hpp
+++ b/components/task/include/task.hpp
@@ -12,7 +12,7 @@
#include
#endif
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
@@ -32,7 +32,7 @@ namespace espp {
* \section task_ex5 Task Request Stop Example
* \snippet task_example.cpp Task Request Stop example
*/
-class Task {
+class Task : public BaseComponent {
public:
/**
* @brief Task callback function signature.
@@ -104,18 +104,24 @@ class Task {
* @param config Config struct to initialize the Task with.
*/
explicit Task(const Config &config)
- : name_(config.name), callback_(config.callback), stack_size_bytes_(config.stack_size_bytes),
- priority_(config.priority), core_id_(config.core_id),
- logger_({.tag = name_, .level = config.log_level}) {}
+ : BaseComponent(config.name, config.log_level)
+ , name_(config.name)
+ , callback_(config.callback)
+ , stack_size_bytes_(config.stack_size_bytes)
+ , priority_(config.priority)
+ , core_id_(config.core_id) {}
/**
* @brief Construct a new Task object using the SimpleConfig struct.
* @param config SimpleConfig struct to initialize the Task with.
*/
explicit Task(const SimpleConfig &config)
- : name_(config.name), simple_callback_(config.callback),
- stack_size_bytes_(config.stack_size_bytes), priority_(config.priority),
- core_id_(config.core_id), logger_({.tag = name_, .level = config.log_level}) {}
+ : BaseComponent(config.name, config.log_level)
+ , name_(config.name)
+ , simple_callback_(config.callback)
+ , stack_size_bytes_(config.stack_size_bytes)
+ , priority_(config.priority)
+ , core_id_(config.core_id) {}
/**
* @brief Get a unique pointer to a new task created with \p config.
@@ -324,8 +330,6 @@ class Task {
*/
int core_id_;
- Logger logger_;
-
std::atomic started_{false};
std::condition_variable cv_;
std::mutex cv_m_;
diff --git a/components/thermistor/CMakeLists.txt b/components/thermistor/CMakeLists.txt
index 851edd130..e24070f55 100644
--- a/components/thermistor/CMakeLists.txt
+++ b/components/thermistor/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger math)
+ REQUIRES base_component math)
diff --git a/components/thermistor/include/thermistor.hpp b/components/thermistor/include/thermistor.hpp
index ef3bcf22c..fdc0ac974 100644
--- a/components/thermistor/include/thermistor.hpp
+++ b/components/thermistor/include/thermistor.hpp
@@ -2,8 +2,8 @@
#include
+#include "base_component.hpp"
#include "fast_math.hpp"
-#include "logger.hpp"
namespace espp {
/// @brief Thermistor class
@@ -19,7 +19,7 @@ namespace espp {
///
/// \section thermistor_ex2 ADC Example
/// \snippet thermistor_example.cpp thermistor adc example
-class Thermistor {
+class Thermistor : public BaseComponent {
public:
/// @brief Function type for reading voltage
/// @return Voltage in millivolts
@@ -46,10 +46,13 @@ class Thermistor {
/// @brief Constructor
/// @param config Configuration struct
explicit Thermistor(const Config &config)
- : divider_config_(config.divider_config), b_(config.beta),
- r0_(config.nominal_resistance_ohms), r2_(config.fixed_resistance_ohms),
- supply_mv_(config.supply_mv), read_mv_(config.read_mv),
- logger_({.tag = "Thermistor", .level = config.log_level}) {
+ : BaseComponent("Thermistor", config.log_level)
+ , divider_config_(config.divider_config)
+ , b_(config.beta)
+ , r0_(config.nominal_resistance_ohms)
+ , r2_(config.fixed_resistance_ohms)
+ , supply_mv_(config.supply_mv)
+ , read_mv_(config.read_mv) {
if (b_ == 0.0f) {
logger_.error("b_ is 0");
} else {
@@ -138,6 +141,5 @@ class Thermistor {
float r2_; ///< Resistance of the fixed resistor in the voltage divider
float supply_mv_; ///< Supply voltage of the voltage divider (in mv)
read_mv_fn read_mv_{nullptr}; ///< Function for reading voltage (in mv)
- Logger logger_;
};
} // namespace espp
diff --git a/components/timer/CMakeLists.txt b/components/timer/CMakeLists.txt
index b9596b4ef..7114c1f57 100644
--- a/components/timer/CMakeLists.txt
+++ b/components/timer/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- REQUIRES logger task)
+ REQUIRES base_component task)
diff --git a/components/timer/include/timer.hpp b/components/timer/include/timer.hpp
index 31c9b0ef3..f219a5dce 100644
--- a/components/timer/include/timer.hpp
+++ b/components/timer/include/timer.hpp
@@ -4,7 +4,7 @@
#include
#include
-#include "logger.hpp"
+#include "base_component.hpp"
#include "task.hpp"
namespace espp {
@@ -45,7 +45,7 @@ namespace espp {
/// \snippet timer_example.cpp timer cancel itself example
/// \section timer_ex5 Oneshot Timer Cancel Itself Then Start again with Delay Example
/// \snippet timer_example.cpp timer oneshot restart example
-class Timer {
+class Timer : public BaseComponent {
public:
typedef std::function
callback_fn; ///< The callback function type. Return true to cancel the timer.
@@ -69,11 +69,12 @@ class Timer {
/// @brief Construct a new Timer object
/// @param config The configuration for the timer.
explicit Timer(const Config &config)
- : period_(std::chrono::duration_cast(config.period)),
- delay_(std::chrono::duration_cast(config.delay)),
- callback_(config.callback), logger_({.tag = config.name,
- .rate_limit = std::chrono::milliseconds(100),
- .level = config.log_level}) {
+ : BaseComponent(config.name, config.log_level)
+ , period_(std::chrono::duration_cast(config.period))
+ , delay_(std::chrono::duration_cast(config.delay))
+ , callback_(config.callback) {
+ // set the logger rate limit
+ logger_.set_rate_limit(std::chrono::milliseconds(100));
// make the task
task_ = espp::Task::make_unique({
.name = std::string(config.name) + "_task",
@@ -211,6 +212,5 @@ class Timer {
float delay_float;
callback_fn callback_; ///< The callback function to call when the timer expires.
std::unique_ptr task_; ///< The task that runs the timer.
- espp::Logger logger_; ///< The logger for the timer.
};
} // namespace espp
diff --git a/components/wifi/CMakeLists.txt b/components/wifi/CMakeLists.txt
index 5f61cca10..e8872079a 100644
--- a/components/wifi/CMakeLists.txt
+++ b/components/wifi/CMakeLists.txt
@@ -1,3 +1,3 @@
idf_component_register(
INCLUDE_DIRS "include"
- PRIV_REQUIRES logger esp_wifi)
+ PRIV_REQUIRES base_component esp_wifi)
diff --git a/components/wifi/include/wifi.hpp b/components/wifi/include/wifi.hpp
new file mode 100644
index 000000000..74360bc22
--- /dev/null
+++ b/components/wifi/include/wifi.hpp
@@ -0,0 +1,66 @@
+#pragma once
+
+#include "esp_wifi.h"
+
+#include "wifi_ap.hpp"
+#include "wifi_sta.hpp"
+
+namespace espp {
+
+/// @brief The Wifi class provides access to the ESP32 Wifi functionality.
+/// @details The Wifi class is a singleton class that provides access to the
+/// ESP32 Wifi functionality. The Wifi class is a wrapper around the ESP32
+/// Wifi API. The Wifi class provides access to the Wifi AP and Wifi STA
+/// functionality.
+class Wifi {
+public:
+ /// @brief Access the singleton instance of the Wifi class.
+ /// @return The singleton instance of the Wifi class.
+ static Wifi &instance() {
+ static Wifi wifi;
+ return wifi;
+ }
+
+ Wifi(const Wifi &) = delete;
+ Wifi &operator=(const Wifi &) = delete;
+ Wifi(Wifi &&) = delete;
+ Wifi &operator=(Wifi &&) = delete;
+
+ /// @brief Get the IP address of the Wifi AP or Wifi STA interface.
+ /// @param ip_address The IP address of the Wifi AP or Wifi STA interface.
+ /// @return True if the IP address was retrieved, false otherwise.
+ bool get_ip_address(std::string &ip_address) {
+ esp_netif_ip_info_t ip;
+ if (esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_AP), &ip) != ESP_OK) {
+ if (esp_netif_get_ip_info(get_esp_interface_netif(ESP_IF_WIFI_STA), &ip) != ESP_OK) {
+ return false;
+ }
+ }
+
+ ip_address = ip4addr_ntoa(&ip.ip);
+ return true;
+ }
+
+protected:
+ /// @brief Construct a new Wifi object.
+ /// @details The Wifi object is a singleton object and can only be
+ /// constructed once.
+ Wifi() {
+ /*
+ esp_netif_init();
+ esp_event_loop_create_default();
+ esp_netif_create_default_wifi_ap();
+ esp_netif_create_default_wifi_sta();
+ wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
+ esp_wifi_init(&cfg);
+ esp_wifi_set_storage(WIFI_STORAGE_RAM);
+ esp_wifi_set_mode(WIFI_MODE_APSTA);
+ esp_wifi_start();
+ */
+ }
+
+ std::unique_ptr ap_;
+ std::unique_ptr sta_;
+};
+
+} // namespace espp
diff --git a/components/wifi/include/wifi_ap.hpp b/components/wifi/include/wifi_ap.hpp
index de4fa3302..b3f572688 100644
--- a/components/wifi/include/wifi_ap.hpp
+++ b/components/wifi/include/wifi_ap.hpp
@@ -7,7 +7,7 @@
#include "esp_wifi.h"
#include "nvs_flash.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -23,7 +23,7 @@ namespace espp {
* \section wifiap_ex1 WiFi Access Point Example
* \snippet wifi_example.cpp wifi ap example
*/
-class WifiAp {
+class WifiAp : public BaseComponent {
public:
struct Config {
std::string ssid; /**< SSID for the access point. */
@@ -38,7 +38,8 @@ class WifiAp {
* @brief Initialize the WiFi Access Point (AP)
* @param config WifiAp::Config structure with initialization information.
*/
- explicit WifiAp(const Config &config) : logger_({.tag = "WifiAp", .level = config.log_level}) {
+ explicit WifiAp(const Config &config)
+ : BaseComponent("WifiAp", config.log_level) {
// Code below is modified from:
// https://github.com/espressif/esp-idf/blob/master/examples/wifi/getting_started/softAP/main/softap_example_main.c
// NOTE: Init phase
@@ -149,7 +150,6 @@ class WifiAp {
}
}
- Logger logger_;
esp_event_handler_instance_t *event_handler_instance_{nullptr};
};
} // namespace espp
diff --git a/components/wifi/include/wifi_sta.hpp b/components/wifi/include/wifi_sta.hpp
index a60f1e7d4..edd511c92 100644
--- a/components/wifi/include/wifi_sta.hpp
+++ b/components/wifi/include/wifi_sta.hpp
@@ -9,7 +9,7 @@
#include "esp_wifi.h"
#include "nvs_flash.h"
-#include "logger.hpp"
+#include "base_component.hpp"
namespace espp {
/**
@@ -25,7 +25,7 @@ namespace espp {
* \section wifista_ex1 WiFi Station Example
* \snippet wifi_example.cpp wifi sta example
*/
-class WifiSta {
+class WifiSta : public BaseComponent {
public:
/**
* @brief called when the WiFi station connects to an access point.
@@ -66,9 +66,11 @@ class WifiSta {
* @param config WifiSta::Config structure with initialization information.
*/
explicit WifiSta(const Config &config)
- : num_retries_(config.num_connect_retries), connect_callback_(config.on_connected),
- disconnect_callback_(config.on_disconnected), ip_callback_(config.on_got_ip),
- logger_({.tag = "WifiSta", .level = config.log_level}) {
+ : BaseComponent("WifiSta", config.log_level)
+ , num_retries_(config.num_connect_retries)
+ , connect_callback_(config.on_connected)
+ , disconnect_callback_(config.on_disconnected)
+ , ip_callback_(config.on_got_ip) {
// Code below is modified from:
// https://github.com/espressif/esp-idf/blob/1c84cfde14dcffdc77d086a5204ce8a548dce935/examples/wifi/getting_started/station/main/station_example_main.c
esp_err_t err;
@@ -215,7 +217,6 @@ class WifiSta {
disconnect_callback disconnect_callback_{nullptr};
ip_callback ip_callback_{nullptr};
std::atomic connected_{false};
- Logger logger_;
esp_event_handler_instance_t *event_handler_instance_any_id_{nullptr};
esp_event_handler_instance_t *event_handler_instance_got_ip_{nullptr};
};
diff --git a/doc/Doxyfile b/doc/Doxyfile
index ae2f6f6d7..32a7edceb 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -84,6 +84,7 @@ INPUT += $(PROJECT_PATH)/components/ads1x15/include/ads1x15.hpp
INPUT += $(PROJECT_PATH)/components/ads7138/include/ads7138.hpp
INPUT += $(PROJECT_PATH)/components/as5600/include/as5600.hpp
INPUT += $(PROJECT_PATH)/components/aw9523/include/aw9523.hpp
+INPUT += $(PROJECT_PATH)/components/base_component/include/base_component.hpp
INPUT += $(PROJECT_PATH)/components/bldc_driver/include/bldc_driver.hpp
INPUT += $(PROJECT_PATH)/components/bldc_haptics/include/bldc_haptics.hpp
INPUT += $(PROJECT_PATH)/components/bldc_haptics/include/detent_config.hpp
diff --git a/doc/en/base_component.rst b/doc/en/base_component.rst
new file mode 100644
index 000000000..7de4a262c
--- /dev/null
+++ b/doc/en/base_component.rst
@@ -0,0 +1,16 @@
+Base Compoenent
+***************
+
+The `espp::BaseComponent` provides a simple base class for all components in the
+ESP-CPP package. It provides a simple interface for the component to be
+initialized and to be updated.
+
+It is not required to use the `BaseComponent` class, but it is recommended to
+use as it provides a standardized API for logging and log management.
+
+.. ---------------------------- API Reference ----------------------------------
+
+API Reference
+-------------
+
+.. include-build-file:: inc/base_component.inc
diff --git a/doc/en/index.rst b/doc/en/index.rst
index eeb4db2e4..85689db81 100644
--- a/doc/en/index.rst
+++ b/doc/en/index.rst
@@ -11,6 +11,7 @@ This is the documentation for esp-idf c++ components, ESPP (`espp
-
+
@@ -90,6 +90,7 @@
+Base Compoenent
Battery APIs
BLDC APIs
Button APIs
@@ -146,7 +147,7 @@
ADC APIs »
ADC Types
- Edit on GitHub
+ Edit on GitHub
@@ -174,7 +175,7 @@ Header File Previous
- Next
+ Next
diff --git a/docs/adc/ads1x15.html b/docs/adc/ads1x15.html
index 5b9a69f98..e1970fa6a 100644
--- a/docs/adc/ads1x15.html
+++ b/docs/adc/ads1x15.html
@@ -91,6 +91,7 @@
ADC Types
+Base Compoenent
Battery APIs
BLDC APIs
Button APIs
@@ -147,7 +148,7 @@
ADC APIs »
ADS1x15 I2C ADC
- Edit on GitHub
+ Edit on GitHub
@@ -164,7 +165,7 @@ API Reference
+
+Parameters
+level – The verbosity level to use for the logger
+
+
+
+
+
+
+inline void set_log_verbosity ( Logger :: Verbosity level )
+Set the log verbosity for the logger
+
+
+
+
+
Note
+
This is a convenience method that calls set_log_level
+
+
+Parameters
+level – The verbosity level to use for the logger
+
+
+
+
+
+
+inline void set_log_rate_limit ( std :: chrono :: duration < float > rate_limit )
+Set the rate limit for the logger
+
+
+
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
+
+
+
+
diff --git a/docs/adc/index.html b/docs/adc/index.html
index 07dd150a1..625745817 100644
--- a/docs/adc/index.html
+++ b/docs/adc/index.html
@@ -84,6 +84,7 @@
ADC Types
+Base Compoenent
Battery APIs
BLDC APIs
Button APIs
@@ -139,7 +140,7 @@
»
ADC APIs
- Edit on GitHub
+ Edit on GitHub
diff --git a/docs/adc/oneshot_adc.html b/docs/adc/oneshot_adc.html
index 92892379a..c5213c5ed 100644
--- a/docs/adc/oneshot_adc.html
+++ b/docs/adc/oneshot_adc.html
@@ -91,6 +91,7 @@
ADC Types
+Base Compoenent
Battery APIs
BLDC APIs
Button APIs
@@ -147,7 +148,7 @@
ADC APIs »
Oneshot ADC
- Edit on GitHub
+ Edit on GitHub
@@ -168,14 +169,14 @@ API Reference
OneshotAdc provides a wrapper around the ESP-IDF oneshot adc subsystem, enabling simple, direct (blocking / slow) measurements of analog values. The read_mv()
function will always take a new measurement (therefore it is blocking).
Oneshot ADC Example
@@ -258,6 +259,82 @@ Oneshot ADC Example
+
+
+
+inline void set_log_level ( Logger :: Verbosity level )
+Set the log level for the logger
+
+
+
+Parameters
+level – The verbosity level to use for the logger
+
+
+
+
+
+
+inline void set_log_verbosity ( Logger :: Verbosity level )
+Set the log verbosity for the logger
+
+
+
+
+
Note
+
This is a convenience method that calls set_log_level
+
+
+Parameters
+level – The verbosity level to use for the logger
+
+
+
+
+
+
+inline void set_log_rate_limit ( std :: chrono :: duration < float > rate_limit )
+Set the rate limit for the logger
+
+
+
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
+
+
+
+
diff --git a/docs/adc/tla2528.html b/docs/adc/tla2528.html
index dd983da15..92b911a5f 100644
--- a/docs/adc/tla2528.html
+++ b/docs/adc/tla2528.html
@@ -91,6 +91,7 @@
ADC Types
+Base Compoenent
Battery APIs
BLDC APIs
Button APIs
@@ -147,7 +148,7 @@
ADC APIs »
TLA2528 I2C ADC
- Edit on GitHub
+ Edit on GitHub
@@ -169,7 +170,7 @@ API Reference