ABI Encoder

The AbiEncoder allow the user a configurable container wrapping the pulse count ESP peripheral api as it would be configured for an incremental encoder with quadrature output (see Wikipedia). The AbiEncoder can be configured to be either LINEAR or ROTATIONAL, and provides access to the current count of the encoder (including the overflow underflow conditions).

Code examples for the ABI Encoder are provided in the encoder example folder.

API Reference

Header File

Classes

template<EncoderType T = EncoderType::ROTATIONAL>
class AbiEncoder : public espp::BaseComponent

Class providing ABI/Z encoder functionality using the pulse count hardware in the ESP chips. Can be configured to measure purely linear (EncoderType::LINEAR) position or rotational (EncoderType::ROTATIONAL) position.

AbiEncoder (ROTATIONAL) Example

    espp::AbiEncoder<espp::EncoderType::ROTATIONAL> encoder({
        .a_gpio = 9,
        .b_gpio = 10,
        .high_limit = 8192,
        .low_limit = -8192,
        .counts_per_revolution = 4096,
    });
    encoder.start();
    auto task_fn = [&encoder](std::mutex &m, std::condition_variable &cv) {
      auto count = encoder.get_count();
      auto radians = encoder.get_radians();
      auto degrees = encoder.get_degrees();
      fmt::print("CRD: [{}, {:.3f}, {:.1f}]\n", count, radians, degrees);
      // NOTE: sleeping in this way allows the sleep to exit early when the
      // task is being stopped / destroyed
      {
        std::unique_lock<std::mutex> lk(m);
        cv.wait_for(lk, 250ms);
      }
      // don't want to stop the task
      return false;
    };
    auto task = espp::Task({.callback = task_fn,
                            .task_config = {.name = "Abi Encoder"},
                            .log_level = espp::Logger::Verbosity::INFO});
    task.start();

AbiEncoder (LINEAR) Example

    espp::AbiEncoder<espp::EncoderType::LINEAR> encoder({
        .a_gpio = 9,
        .b_gpio = 10,
        .high_limit = 8192,
        .low_limit = -8192,
    });
    encoder.start();
    auto task_fn = [&encoder](std::mutex &m, std::condition_variable &cv) {
      // EncoderType::LINEAR only supports get_count
      auto count = encoder.get_count();
      fmt::print("Count: {}\n", count);
      // NOTE: sleeping in this way allows the sleep to exit early when the
      // task is being stopped / destroyed
      {
        std::unique_lock<std::mutex> lk(m);
        cv.wait_for(lk, 250ms);
      }
      // don't want to stop the task
      return false;
    };
    auto task = espp::Task({.callback = task_fn,
                            .task_config = {.name = "Abi Encoder"},
                            .log_level = espp::Logger::Verbosity::INFO});
    task.start();

Public Functions

template<EncoderType type = T>
inline explicit AbiEncoder(const Config &config)

Initialize the pulse count hardware for the ABI encoder.

Note

This does not start the pulse count hardware, for that you must call the start() method at least once.

inline ~AbiEncoder()

Stop the pulse count hardware then disable and delete the channels / units associated with this AbiEncoder.

inline int get_count()

Get the total count (including under/overflows) since it was created or clear()-ed last.

Returns

Total count as a signed integer.

float get_revolutions () requires(T

Get the total number of revolutions this ABI encoder has measured since it was created or clear()-ed last.

Note

This is only available if the AbiEncoder is EncoderType::ROTATIONAL.

Returns

Number of revolutions, as a floating point number.

inline const std::string &get_name() const

Get the name of the component

Note

This is the tag of the logger

Returns

A const reference to the name of the component

inline void set_log_tag(const std::string_view &tag)

Set the tag for the logger

Parameters

tag – The tag to use for the logger

inline espp::Logger::Verbosity get_log_level() const

Get the log level for the logger

Returns

The verbosity level of the logger

inline void set_log_level(espp::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(espp::Logger::Verbosity level)

Set the log verbosity for the logger

See also

set_log_level

Note

This is a convenience method that calls set_log_level

Parameters

level – The verbosity level to use for the logger

inline espp::Logger::Verbosity get_log_verbosity() const

Get the log verbosity for the logger

See also

get_log_level

Note

This is a convenience method that calls get_log_level

Returns

The verbosity level of the logger

inline void set_log_rate_limit(std::chrono::duration<float> rate_limit)

Set the rate limit for the logger

Note

Only calls to the logger that have _rate_limit suffix will be rate limited

Parameters

rate_limit – The rate limit to use for the logger

struct Config

Public Members

int a_gpio

GPIO number for the a channel pulse.

int b_gpio

GPIO number for the b channel pulse.

int i_gpio = {-1}

GPIO number for the index (I/Z) pulse).

Note

This is currently unused.

int16_t high_limit

High limit for the hardware counter before it resets to 0. Lowering (to zero) this value increases the number of interrupts / overflows of the counter.

int16_t low_limit

Low limit for the hardware counter before it resets to 0. Lowering (to zero) this value increases the number of interrupts / overflows of the counter.

size_t counts_per_revolution = {0}

How many counts equate to a single revolution.

Note

this unused if the type is not EncoderType::ROTATIONAL.

size_t max_glitch_ns = {1000}

Max glitch witdth in nanoseconds that is ignored. 0 will disable the glitch filter.

espp::Logger::Verbosity log_level = {espp::Logger::Verbosity::WARN}

Verbosity for the adc logger.