1616
1717/* *************************************************************************/
1818/* !
19- @brief Constructor
20- */
21- /* *************************************************************************/
22- ServoHardware::ServoHardware () {
23-
24- }
25-
26- /* *************************************************************************/
27- /* !
28- @brief Destructor
29- */
30- /* *************************************************************************/
31- ServoHardware::~ServoHardware () {
32-
33- }
34-
35- /* *************************************************************************/
36- /* !
37- @brief Attaches a pin to a servo
19+ @brief Constructs a ServoHardware object
3820 @param pin
39- The pin to attach
40- @param frequency
41- The servo frequency (in Hz)
21+ The GPIO pin to attach the servo to
4222 @param min_pulse_width
43- The minimum pulse width ( in microseconds)
23+ The minimum pulse width, in microseconds
4424 @param max_pulse_width
45- The maximum pulse width (in microseconds)
46- @returns True if successful, False otherwise
25+ The maximum pulse width, in microseconds
26+ @param frequency
27+ The frequency of the PWM signal, in Hz (50Hz is sent from IO)
4728*/
4829/* *************************************************************************/
49- bool ServoHardware::AttachPin (uint8_t pin, uint32_t frequency, uint32_t min_pulse_width, uint32_t max_pulse_width) {
50-
30+ ServoHardware::ServoHardware (int pin, int min_pulse_width, int max_pulse_width,
31+ int frequency) {
32+ _pin = pin;
33+ _min_pulse_width = min_pulse_width;
34+ _max_pulse_width = max_pulse_width;
35+ _frequency = frequency;
36+
37+ #ifndef ARDUINO_ARCH_ESP32
38+ _servo = new Servo ();
39+ #else
40+ _is_attached = false ;
41+ #endif
5142}
5243
5344/* *************************************************************************/
5445/* !
55- @brief Detaches a pin from a servo
56- @returns True if successful, False otherwise
46+ @brief Destructor
5747*/
5848/* *************************************************************************/
59- bool ServoHardware::DetachPin () {
60-
61- }
49+ ServoHardware::~ServoHardware () {}
6250
6351/* *************************************************************************/
6452/* !
65- @brief Writes a pulse width to the servo
66- @param pulse_width
67- The pulse width (in microseconds) to write
68- @returns True if successful, False otherwise
53+ @brief Attempts to attach a servo to a GPIO pin.
54+ @returns true if successful, false otherwise.
6955*/
7056/* *************************************************************************/
71- bool ServoHardware::WritePulseWidth (uint32_t pulse_width) {
72-
57+ bool ServoHardware::ServoAttach () {
58+ uint16_t rc = 255 ;
59+
60+ // Attach the servo to the pin
61+ #ifdef ARDUINO_ARCH_ESP32
62+ if (!ledcAttach (_pin, _frequency, LEDC_TIMER_WIDTH)) {
63+ rc = 255 ;
64+ } else {
65+ rc = 1 ;
66+ _is_attached = true ;
67+ }
68+ #else
69+ rc = _servo.attach (_pin, _min_pulse_width, _max_pulse_width);
70+ #endif
71+
72+ if (rc == 255 ) {
73+ WS_DEBUG_PRINT (" [servo] Error: Failed to attach servo to pin: " );
74+ WS_DEBUG_PRINTLN (_pin);
75+ return false ;
76+ }
77+
78+ return true ;
7379}
7480
7581/* *************************************************************************/
7682/* !
77- @brief Returns the pin number
78- @returns The pin number
83+ @brief Writes a value to the servo pin
84+ @param value
85+ The value to write to the servo pin
7986*/
8087/* *************************************************************************/
81- uint8_t ServoHardware::GetPin () {
82-
88+ void ServoHardware::ServoWrite (int value) {
89+ #ifdef ARDUINO_ARCH_ESP32
90+ writeMicroseconds (value);
91+ #else
92+ _servo.writeMicroseconds (value);
93+ #endif
8394}
8495
8596#ifdef ARDUINO_ARCH_ESP32
8697/* *************************************************************************/
8798/* !
88- @brief Abstraction for ESP32's servo write API
99+ @brief Mocks writeMicroseconds() call in arduino/servo api for
100+ ESP32x's LEDC manager.
89101 @param value
90- The value to write
91- @returns True if successful, False otherwise
102+ The value to write to the servo pin.
92103*/
93104/* *************************************************************************/
94- bool ServoHardware::servoWrite (uint32_t value) {
95-
105+ void ServoHardware::writeMicroseconds (int value) {
106+ if (!_is_attached) {
107+ WS_DEBUG_PRINTLN (" [servo] Error: Servo not attached!" );
108+ return ;
109+ }
110+
111+ // Clamp value to a valid pulse_width range
112+ if (value < _min_pulse_width)
113+ value = _min_pulse_width;
114+ if (value > _max_pulse_width)
115+ value = _max_pulse_width;
116+
117+ // Formula from ESP32Servo library
118+ // https://github.com/madhephaestus/ESP32Servo/blob/master/src/ESP32Servo.cpp
119+ // count = (pulse_high_width / (pulse_period/2**timer_width))
120+ // 50Hz servo = 20ms pulse_period
121+ uint32_t count =
122+ ((double )value / ((double )20000 / (double )pow (2 , LEDC_TIMER_WIDTH)));
123+ if (!ledcWrite (_pin, count))
124+ WS_DEBUG_PRINTLN (" [servo] Error: Failed to write to servo pin!" );
96125}
97126#endif
0 commit comments