Skip to content
This repository was archived by the owner on Jan 29, 2023. It is now read-only.

Commit 01ab4a7

Browse files
authored
Add files via upload
1 parent 4ae98f7 commit 01ab4a7

File tree

6 files changed

+134
-27
lines changed

6 files changed

+134
-27
lines changed

README.md

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,11 @@ Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
4040

4141
The timer1 counters can be configured to support automatic reload.
4242

43-
## New from v1.0.0
43+
## New from v1.0.1
44+
45+
1. Add functions `getPosition()` and `getPulseWidth()`
46+
2. Optimize the code
47+
3. Add more complicated example
4448

4549
Now these new `16 ISR-based Servo controllers` just use one ESP8266 Hardware Timer. The number 16 is just arbitrarily chosen, and depending
4650
on application, you can increase that number to 32, 48, etc. without problem.
@@ -70,6 +74,10 @@ How to use:
7074
7175
#include "ESP8266_ISR_Servo.h"
7276
77+
// Published values for SG90 servos; adjust if needed
78+
#define MIN_MICROS 800 //544
79+
#define MAX_MICROS 2450
80+
7381
int servoIndex1 = -1;
7482
int servoIndex2 = -1;
7583
@@ -78,8 +86,8 @@ void setup()
7886
Serial.begin(115200);
7987
Serial.println("\nStarting");
8088
81-
servoIndex1 = ISR_Servo.setupServo(D8);
82-
servoIndex2 = ISR_Servo.setupServo(D7);
89+
servoIndex1 = ISR_Servo.setupServo(D8, MIN_MICROS, MAX_MICROS);
90+
servoIndex2 = ISR_Servo.setupServo(D7, MIN_MICROS, MAX_MICROS);
8391
8492
if (servoIndex1 != -1)
8593
Serial.println("Setup Servo1 OK");
@@ -104,7 +112,7 @@ void loop()
104112
// in steps of 1 degree
105113
ISR_Servo.setPosition(servoIndex1, position);
106114
ISR_Servo.setPosition(servoIndex2, 180 - position);
107-
// waits 15ms for the servo to reach the position
115+
// waits 50ms for the servo to reach the position
108116
delay(50 /*15*/);
109117
}
110118
@@ -113,8 +121,8 @@ void loop()
113121
// goes from 180 degrees to 0 degrees
114122
ISR_Servo.setPosition(servoIndex1, position);
115123
ISR_Servo.setPosition(servoIndex2, 180 - position);
116-
// waits 15ms for the servo to reach the position
117-
delay(50 /*15*/);
124+
// waits 50ms for the servo to reach the position
125+
delay(50 /*15*/);
118126
}
119127
}
120128
}
@@ -128,7 +136,7 @@ void loop()
128136

129137
## DONE
130138

131-
For current version v1.0.0
139+
For current version v1.0.1
132140

133141
1. Basic 16 ISR-based servo controllers using 1 hardware timer for ESP8266.
134142

examples/MultipleRandomServos/MultipleRandomServos.ino

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,28 +120,34 @@ void loop()
120120
for (int index = 0; index < NUM_SERVOS; index++)
121121
{
122122
ISR_Servo.setPosition(ISR_servo[index].servoIndex, position );
123-
}
124-
// waits 1s for the servo to reach the position
123+
Serial.print("Servos idx = " + String(index) + ", act. pos. (deg) = " + String(ISR_Servo.getPosition(ISR_servo[index].servoIndex)) );
124+
Serial.println(", pulseWidth (us) = " + String(ISR_Servo.getPulseWidth(ISR_servo[index].servoIndex)) );
125+
}
126+
// waits 5s between test
125127
delay(5000);
126128

127129
position = 90;
128130
Serial.println("Servos @ 90 degree");
129131
for (int index = 0; index < NUM_SERVOS; index++)
130132
{
131133
ISR_Servo.setPosition(ISR_servo[index].servoIndex, position );
134+
Serial.print("Servos idx = " + String(index) + ", act. pos. (deg) = " + String(ISR_Servo.getPosition(ISR_servo[index].servoIndex)) );
135+
Serial.println(", pulseWidth (us) = " + String(ISR_Servo.getPulseWidth(ISR_servo[index].servoIndex)) );
132136
}
133-
// waits 1s for the servo to reach the position
137+
// waits 5s between test
134138
delay(5000);
135139

136140
position = 180;
137141
Serial.println("Servos @ 180 degree");
138142
for (int index = 0; index < NUM_SERVOS; index++)
139143
{
140144
ISR_Servo.setPosition(ISR_servo[index].servoIndex, position );
145+
Serial.print("Servos idx = " + String(index) + ", act. pos. (deg) = " + String(ISR_Servo.getPosition(ISR_servo[index].servoIndex)) );
146+
Serial.println(", pulseWidth (us) = " + String(ISR_Servo.getPulseWidth(ISR_servo[index].servoIndex)) );
141147
}
142-
// waits 1s for the servo to reach the position
148+
// waits 5s between test
143149
delay(5000);
144-
150+
145151
Serial.println("Servos sweeps from 0-180 degress");
146152
for (position = 0; position <= 180; position += 1)
147153
{
@@ -151,9 +157,10 @@ void loop()
151157
{
152158
ISR_Servo.setPosition(ISR_servo[index].servoIndex, position );
153159
}
154-
// waits 1s for the servo to reach the position
160+
// waits 50ms for the servo to reach the position
155161
delay(50);
156162
}
163+
// waits 5s between test
157164
delay(5000);
158165

159166
Serial.println("Servos sweeps from 180-0 degress");
@@ -165,9 +172,10 @@ void loop()
165172
{
166173
ISR_Servo.setPosition(ISR_servo[index].servoIndex, position );
167174
}
168-
// waits 1s for the servo to reach the position
175+
// waits 50ms for the servo to reach the position
169176
delay(50);
170177
}
178+
// waits 5s between test
171179
delay(5000);
172180

173181
Serial.println("Servos, index depending, be somewhere from 0-180 degress");
@@ -179,7 +187,7 @@ void loop()
179187
{
180188
ISR_Servo.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
181189
}
182-
// waits 1s for the servo to reach the position
190+
// waits 50ms for the servo to reach the position
183191
delay(50);
184192
}
185193
delay(5000);
@@ -193,9 +201,10 @@ void loop()
193201
{
194202
ISR_Servo.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
195203
}
196-
// waits 1s for the servo to reach the position
204+
// waits 50ms for the servo to reach the position
197205
delay(50);
198206
}
207+
// waits 5s between test
199208
delay(5000);
200209

201210
}

keywords.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ init KEYWORD2
1010
run KEYWORD2
1111
setupServo KEYWORD2
1212
setPosition KEYWORD2
13+
getPosition KEYWORD2
14+
setPulseWidth KEYWORD2
15+
getPulseWidth KEYWORD2
1316
deleteServo KEYWORD2
1417
isEnabled KEYWORD2
1518
enable KEYWORD2

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name=ESP8266_ISR_Servo
2-
version=1.0.0
2+
version=1.0.1
33
author=Khoi Hoang
44
maintainer=Khoi Hoang
55
license=MIT
66
maintainer=Khoi Hoang <[email protected]>
7-
sentence=This library enables you to use Interrupt from Hardware Timers on an ESP8266.
7+
sentence=This library enables you to use Interrupt from Hardware Timers on an ESP8266 to control servo motors.
88
paragraph=This library enables you to use 1 Hardware Timer on an ESP8266-based board to control up to 16 or more servo motors.
99
category=Timing
1010
url=https://github.com/khoih-prog/ESP8266_ISR_Servo

src/ESP8266_ISR_Servo.cpp

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Built by Khoi Hoang https://github.com/khoih-prog/ESP8266_ISR_Servo
77
* Licensed under MIT license
8-
* Version: 1.0.0
8+
* Version: 1.0.1
99
*
1010
* The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
1111
* The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
@@ -27,13 +27,14 @@
2727
* Version Modified By Date Comments
2828
* ------- ----------- ---------- -----------
2929
* 1.0.0 K Hoang 04/12/2019 Initial coding
30-
*****************************************************************************************************************************/
30+
* 1.0.1 K Hoang 05/12/2019 Add more features getPosition and getPulseWidth. Optimize.
31+
*****************************************************************************************************************************/
3132

3233
#include "ESP8266_ISR_Servo.h"
3334
#include <string.h>
3435

3536
#ifndef ISR_SERVO_DEBUG
36-
#define ISR_SERVO_DEBUG 1
37+
#define ISR_SERVO_DEBUG 0
3738
#endif
3839

3940
//extern void ICACHE_RAM_ATTR ESP8266_ISR_Servo_Handler(void);
@@ -175,7 +176,7 @@ int ESP8266_ISR_Servo::setupServo(uint8_t pin, int min, int max)
175176
return servoIndex;
176177
}
177178

178-
bool ESP8266_ISR_Servo::setPosition(unsigned servoIndex, unsigned long position)
179+
bool ESP8266_ISR_Servo::setPosition(unsigned servoIndex, int position)
179180
{
180181
if (servoIndex >= MAX_SERVOS)
181182
return false;
@@ -197,6 +198,79 @@ bool ESP8266_ISR_Servo::setPosition(unsigned servoIndex, unsigned long position)
197198
return false;
198199
}
199200

201+
// returns last position in degrees if success, or -1 on wrong servoIndex
202+
int ESP8266_ISR_Servo::getPosition(unsigned servoIndex)
203+
{
204+
if (servoIndex >= MAX_SERVOS)
205+
return -1;
206+
207+
// Updates interval of existing specified servo
208+
if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP8266_MAX_PIN) )
209+
{
210+
#if (ISR_SERVO_DEBUG > 0)
211+
Serial.println("Idx = " + String(servoIndex) + ", cnt = " + String(servo[servoIndex].count) + ", pos = " + String(servo[servoIndex].position));
212+
#endif
213+
214+
return (servo[servoIndex].position);
215+
}
216+
217+
// return 0 for non-used numServo or bad pin
218+
return -1;
219+
}
220+
221+
222+
// setPulseWidth will set servo PWM Pulse Width in microseconds, correcponding to certain position in degrees
223+
// by using PWM, turn HIGH 'pulseWidth' microseconds within REFRESH_INTERVAL (20000us)
224+
// min and max for each individual servo are enforced
225+
// returns true on success or -1 on wrong servoIndex
226+
bool ESP8266_ISR_Servo::setPulseWidth(unsigned servoIndex, unsigned int pulseWidth)
227+
{
228+
if (servoIndex >= MAX_SERVOS)
229+
return false;
230+
231+
// Updates interval of existing specified servo
232+
if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP8266_MAX_PIN) )
233+
{
234+
if (pulseWidth < servo[servoIndex].min)
235+
pulseWidth = servo[servoIndex].min;
236+
else if (pulseWidth > servo[servoIndex].max)
237+
pulseWidth = servo[servoIndex].max;
238+
239+
servo[servoIndex].count = pulseWidth / TIMER_INTERVAL_MICRO;
240+
servo[servoIndex].position = map(pulseWidth, servo[servoIndex].min, servo[servoIndex].max, 0, 180);
241+
242+
#if (ISR_SERVO_DEBUG > 0)
243+
Serial.println("Idx = " + String(servoIndex) + ", cnt = " + String(servo[servoIndex].count) + ", pos = " + String(servo[servoIndex].position));
244+
#endif
245+
246+
return true;
247+
}
248+
249+
// false return for non-used numServo or bad pin
250+
return false;
251+
}
252+
253+
// returns pulseWidth in microsecs (within min/max range) if success, or 0 on wrong servoIndex
254+
unsigned int ESP8266_ISR_Servo::getPulseWidth(unsigned servoIndex)
255+
{
256+
if (servoIndex >= MAX_SERVOS)
257+
return 0;
258+
259+
// Updates interval of existing specified servo
260+
if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP8266_MAX_PIN) )
261+
{
262+
#if (ISR_SERVO_DEBUG > 0)
263+
Serial.println("Idx = " + String(servoIndex) + ", cnt = " + String(servo[servoIndex].count) + ", pos = " + String(servo[servoIndex].position));
264+
#endif
265+
266+
return (servo[servoIndex].count * TIMER_INTERVAL_MICRO );
267+
}
268+
269+
// return 0 for non-used numServo or bad pin
270+
return 0;
271+
}
272+
273+
200274
void ESP8266_ISR_Servo::deleteServo(unsigned servoIndex)
201275
{
202276
if ( (numServos == 0) || (servoIndex >= MAX_SERVOS) )

src/ESP8266_ISR_Servo.h

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Built by Khoi Hoang https://github.com/khoih-prog/ESP8266_ISR_Servo
77
* Licensed under MIT license
8-
* Version: 1.0.0
8+
* Version: 1.0.1
99
*
1010
* The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
1111
* The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
@@ -27,7 +27,8 @@
2727
* Version Modified By Date Comments
2828
* ------- ----------- ---------- -----------
2929
* 1.0.0 K Hoang 04/12/2019 Initial coding
30-
*****************************************************************************************************************************/
30+
* 1.0.1 K Hoang 05/12/2019 Add more features getPosition and getPulseWidth. Optimize.
31+
*****************************************************************************************************************************/
3132

3233

3334
#ifndef ESP8266_ISR_SERVO_H
@@ -56,7 +57,7 @@
5657
#include "ESP8266FastTimerInterrupt.h"
5758

5859
#ifndef ISR_SERVO_DEBUG
59-
#define ISR_SERVO_DEBUG 1
60+
#define ISR_SERVO_DEBUG 0
6061
#endif
6162

6263
//#define ESP8266_ISR_Servo ESP8266ISRServo
@@ -96,8 +97,20 @@ class ESP8266_ISR_Servo
9697
// setPosition will set servo to position in degrees
9798
// by using PWM, turn HIGH 'duration' microseconds within REFRESH_INTERVAL (20000us)
9899
// returns true on success or -1 on wrong servoIndex
99-
bool setPosition(unsigned servoIndex, unsigned long position);
100+
bool setPosition(unsigned servoIndex, int position);
101+
102+
// returns last position in degrees if success, or -1 on wrong servoIndex
103+
int getPosition(unsigned servoIndex);
100104

105+
// setPulseWidth will set servo PWM Pulse Width in microseconds, correcponding to certain position in degrees
106+
// by using PWM, turn HIGH 'pulseWidth' microseconds within REFRESH_INTERVAL (20000us)
107+
// min and max for each individual servo are enforced
108+
// returns true on success or -1 on wrong servoIndex
109+
bool setPulseWidth(unsigned servoIndex, unsigned int pulseWidth);
110+
111+
// returns pulseWidth in microsecs (within min/max range) if success, or 0 on wrong servoIndex
112+
unsigned int getPulseWidth(unsigned servoIndex);
113+
101114
// destroy the specified servo
102115
void deleteServo(unsigned servoIndex);
103116

@@ -137,7 +150,7 @@ class ESP8266_ISR_Servo
137150
{
138151
uint8_t pin; // pin servo connected to
139152
unsigned long count; // In microsecs
140-
unsigned long position; // In degrees
153+
int position; // In degrees
141154
bool enabled; // true if enabled
142155
int16_t min;
143156
int16_t max;

0 commit comments

Comments
 (0)