feat!: main structure of handle changed to double pointer

This commit is contained in:
aZholtikov committed 2026-09-05 08:22:39 +03:00
1 parent e05bc424cf
commit 459ab3c356
5 files changed
+202 -107

No files matched your search

+92 -46
View File
@@ -1,5 +1,21 @@
/**
* @file zh_inclinometer.h
*
* @brief Header file for the zh_inclinometer library providing encoder-based
* angle measurement and position tracking functionality.
*
* This library implements an inclinometer interface based on a quadrature
* encoder connected to two GPIO pins. It uses the ESP-IDF pulse counter
* (pcnt) driver to count encoder pulses and calculate the current angular
* position. The library supports configurable GPIO pins, pull-up enablement,
* rotation direction, and pulses per revolution.
*
* Key features:
* - Quadrature encoder support with configurable GPIO pins
* - Configurable pull-up resistor enablement
* - Support for both clockwise and counter-clockwise rotation directions
* - Configurable pulses per revolution for accurate angle calculation
* - Position tracking with get and reset operations
*/
#pragma once
@@ -10,9 +26,6 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
/**
* @brief Inclinometer initial default values.
*/
#define ZH_INCLINOMETER_INIT_CONFIG_DEFAULT() \
{ \
.a_gpio_number = GPIO_NUM_MAX, \
@@ -27,73 +40,106 @@ extern "C"
#endif
/**
* @brief Structure for initial initialization of inclinometer.
* @brief Opaque handle to the inclinometer internal state.
*
* This handle is returned by zh_inclinometer_init() and must be passed
* to all subsequent API functions to operate on the same inclinometer
* instance. The handle is freed by zh_inclinometer_deinit().
*/
typedef struct _zh_inclinometer_handle_t zh_inclinometer_handle_t;
/**
* @brief Structure for initial configuration of the inclinometer.
*
* This structure holds all parameters required to initialize the
* inclinometer, including GPIO pin assignments, electrical configuration,
* rotation direction, and encoder resolution.
*
* @note Both GPIO pins must be assigned before initialization.
* Use GPIO_NUM_MAX to indicate an unassigned pin.
* @warning The encoder_pulses field must be set to a non-zero value
* representing the actual number of pulses per one full rotation
* of the encoder shaft.
*/
typedef struct
{
uint8_t a_gpio_number; /*!< Encoder A GPIO number. */
uint8_t b_gpio_number; /*!< Encoder B GPIO number. */
bool pullup; /*!< Pullup GPIO enable/disable. */
bool rotation; /*!< Encoder rotation (true - positive for CW rotation, false - positive for CCW rotation). */
uint16_t encoder_pulses; /*!< Number of pulses per one rotation. */
uint8_t a_gpio_number; /*!< Encoder A channel GPIO number */
uint8_t b_gpio_number; /*!< Encoder B channel GPIO number */
bool pullup; /*!< GPIO pull-up resistor enable (true) or disable (false) */
bool rotation; /*!< Rotation direction: true - positive for CW, false - positive for CCW */
uint16_t encoder_pulses; /*!< Number of encoder pulses per one full rotation */
} zh_inclinometer_init_config_t;
/**
* @brief Inclinometer handle.
* @brief Initialize the inclinometer.
*
* Allocates memory for the inclinometer handle, validates the configuration,
* initializes the PCNT unit with two channels for quadrature decoding,
* and starts the pulse counter.
*
* @param[in] config Pointer to the inclinometer initialization configuration
* structure. Can point to a temporary variable (must not be NULL)
* @param[out] handle Pointer to the unique inclinometer handle (must be NULL)
*
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if config or handle is NULL
* @return ESP_ERR_INVALID_STATE if the inclinometer is already initialized
* @return ESP_ERR_NO_MEM if memory allocation failed
* @return ESP_FAIL if PCNT initialization or configuration failed
*/
typedef struct
{
pcnt_unit_handle_t pcnt_unit_handle; /*!< Inclinometer unique pcnt unit handle. */
pcnt_channel_handle_t pcnt_channel_a_handle; /*!< Inclinometer unique pcnt channel handle. */
pcnt_channel_handle_t pcnt_channel_b_handle; /*!< Inclinometer unique pcnt channel handle. */
float degrees_per_pulse; /*!< Number of degrees per pulse. */
bool rotation; /*!< Encoder rotation. */
bool is_initialized; /*!< Inclinometer initialization flag. */
} zh_inclinometer_handle_t;
esp_err_t zh_inclinometer_init(const zh_inclinometer_init_config_t *config, zh_inclinometer_handle_t **handle);
/**
* @brief Initialize inclinometer.
* @brief Deinitialize the inclinometer.
*
* @param[in] config Pointer to inclinometer initialized configuration structure. Can point to a temporary variable.
* @param[out] handle Pointer to unique inclinometer handle.
* Stops and disables the PCNT unit, deletes both encoder channels and the
* PCNT unit, frees the inclinometer handle memory, and sets the handle to
* NULL.
*
* @note Before initialize the inclinometer recommend initialize zh_inclinometer_init_config_t structure with default values.
* @param[in, out] handle Pointer to the unique inclinometer handle (must not be NULL)
*
* @code zh_inclinometer_init_config_t config = ZH_INCLINOMETER_INIT_CONFIG_DEFAULT() @endcode
* @note After deinitialization, the handle is invalidated and must not be
* used. Call zh_inclinometer_init() again to reinitialize.
*
* @return ESP_OK if success or an error code otherwise.
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if handle or *handle is NULL
* @return ESP_FAIL if PCNT stop, disable, or deletion failed
*/
esp_err_t zh_inclinometer_init(const zh_inclinometer_init_config_t *config, zh_inclinometer_handle_t *handle);
esp_err_t zh_inclinometer_deinit(zh_inclinometer_handle_t **handle);
/**
* @brief Deinitialize inclinometer.
* @brief Get the current inclinometer position.
*
* @param[in, out] handle Pointer to unique inclinometer handle.
* Reads the PCNT counter value and converts it to an angle in degrees
* using the configured degrees-per-pulse factor. The sign of the angle
* depends on the configured rotation direction.
*
* @return ESP_OK if success or an error code otherwise.
* @param[in] handle Pointer to the unique inclinometer handle (must not be NULL)
* @param[out] angle Pointer to a float variable that receives the current
* angle in degrees (must not be NULL)
*
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if handle, *handle, or angle is NULL
* @return ESP_FAIL if reading the PCNT counter failed
*/
esp_err_t zh_inclinometer_deinit(zh_inclinometer_handle_t *handle);
esp_err_t zh_inclinometer_get(zh_inclinometer_handle_t **handle, float *angle);
/**
* @brief Get inclinometer position.
* @brief Reset the inclinometer position to zero.
*
* @param[in] handle Pointer to unique inclinometer handle.
* @param[out] position Inclinometer position.
* Clears the PCNT counter, setting the current position to 0 degrees.
* The inclinometer continues counting from the new zero position.
*
* @return ESP_OK if success or an error code otherwise.
* @param[in] handle Pointer to the unique inclinometer handle (must not be NULL)
*
* @note This does not affect the PCNT unit state (enabled/disabled).
* The unit remains running after reset.
*
* @return ESP_OK on success
* @return ESP_ERR_INVALID_ARG if handle or *handle is NULL
* @return ESP_FAIL if clearing the PCNT counter failed
*/
esp_err_t zh_inclinometer_get(zh_inclinometer_handle_t *handle, float *angle);
/**
* @brief Reset inclinometer position.
*
* @note The inclinometer will be set to 0 position.
*
* @param[in] handle Pointer to unique inclinometer handle.
*
* @return ESP_OK if success or an error code otherwise.
*/
esp_err_t zh_inclinometer_reset(zh_inclinometer_handle_t *handle);
esp_err_t zh_inclinometer_reset(zh_inclinometer_handle_t **handle);
#ifdef __cplusplus
}