16
16
17
17
/* *************************************************************************/
18
18
/* !
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
38
20
@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
42
22
@param min_pulse_width
43
- The minimum pulse width ( in microseconds)
23
+ The minimum pulse width, in microseconds
44
24
@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)
47
28
*/
48
29
/* *************************************************************************/
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
51
42
}
52
43
53
44
/* *************************************************************************/
54
45
/* !
55
- @brief Detaches a pin from a servo
56
- @returns True if successful, False otherwise
46
+ @brief Destructor
57
47
*/
58
48
/* *************************************************************************/
59
- bool ServoHardware::DetachPin () {
60
-
61
- }
49
+ ServoHardware::~ServoHardware () {}
62
50
63
51
/* *************************************************************************/
64
52
/* !
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.
69
55
*/
70
56
/* *************************************************************************/
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 ;
73
79
}
74
80
75
81
/* *************************************************************************/
76
82
/* !
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
79
86
*/
80
87
/* *************************************************************************/
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
83
94
}
84
95
85
96
#ifdef ARDUINO_ARCH_ESP32
86
97
/* *************************************************************************/
87
98
/* !
88
- @brief Abstraction for ESP32's servo write API
99
+ @brief Mocks writeMicroseconds() call in arduino/servo api for
100
+ ESP32x's LEDC manager.
89
101
@param value
90
- The value to write
91
- @returns True if successful, False otherwise
102
+ The value to write to the servo pin.
92
103
*/
93
104
/* *************************************************************************/
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!" );
96
125
}
97
126
#endif
0 commit comments