# Servo Component
This component provides a professional-grade driver for hobby servos using the ESP32 MCPWM peripheral.
## Features
- Simple MCPWM configuration for controlling a hobby servo on a single GPIO pin.
- Configurable angle range.
- Configurable pulse-width range (microseconds).
- Configurable PWM frequency.
- Consistent error handling using `esp_err_t`.
## Requirements
This component depends on the following ESP-IDF modules:
- `esp_driver_mcpwm`
- `esp_driver_gpio`
(These provide the MCPWM and GPIO driver APIs used by the component.)
## Usage
Include the component header and create an instance:
```cpp
#include "Servo.hpp"
Servo servo(GPIO_NUM_4);
```
Configure the angle range before initializing the servo:
```cpp
servo.setAngleRange(-90.0f, 90.0f);
```
Start the component and move the servo:
```cpp
esp_err_t err = servo.begin();
if (err != ESP_OK) {
ESP_LOGE("MAIN", "Failed to initialize servo: %s", esp_err_to_name(err));
return;
}
servo.write(0.0f);
servo.write(45.0f);
servo.writeMicroseconds(1500);
```
## API
- `Servo(gpio_num_t pin, uint32_t frequencyHz = 50)`
- Constructor that sets the output pin and default PWM frequency.
- `esp_err_t begin()`
- Configures MCPWM and starts the PWM signal.
- Returns `ESP_OK` on success or an ESP-IDF error code on failure.
- `esp_err_t write(float angle)`
- Moves the servo to the desired angle within the configured range.
- Values outside the range are automatically clamped.
- `esp_err_t writeMicroseconds(uint32_t pulseWidthUs)`
- Sets the pulse width in microseconds directly.
- The value is clamped to the configured pulse-width range.
- `esp_err_t setAngleRange(float minAngle, float maxAngle)`
- Defines the valid angle range for the servo.
- `esp_err_t setPulseWidthRange(uint32_t minPulseUs, uint32_t maxPulseUs)`
- Defines the valid pulse-width range for the servo.
- `esp_err_t setFrequency(uint32_t frequencyHz)`
- Sets the PWM frequency (should be called before `begin`).
- `bool isReady() const noexcept`
- Returns `true` if the servo has been initialized successfully.
## Full example
```cpp
#include "Servo.hpp"
#include <esp_err.h>
#include <esp_log.h>
static const char *TAG = "SERVO_EXAMPLE";
Servo servo(GPIO_NUM_4);
extern "C" void app_main()
{
servo.setAngleRange(-90.0f, 90.0f);
esp_err_t err = servo.begin();
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize servo: %s", esp_err_to_name(err));
return;
}
servo.write(0.0f);
vTaskDelay(pdMS_TO_TICKS(1000));
servo.write(90.0f);
}
```
idf.py add-dependency "jor4000/easyservo^1.0.2"