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

Commit b81a1e5

Browse files
authored
Add files via upload
1 parent 01ab4a7 commit b81a1e5

File tree

10 files changed

+745
-13
lines changed

10 files changed

+745
-13
lines changed

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ https://www.arduino.cc/reference/en/language/functions/external-interrupts/attac
2626
2. Typically global variables are used to pass data between an ISR and the main program. To make sure variables shared between an ISR and the main program are updated correctly, declare them as `volatile`.
2727

2828
## Installation
29+
30+
It's better to use `Arduino Library Manager` to install this library.
31+
32+
Otherwise, you can install it using the following steps:
33+
2934
1. Navigate to (https://github.com/khoih-prog/ESP8266_ISR_Servo) page.
3035
2. Download the latest release `ESP8266_ISR_Servo-master.zip`.
3136
3. Extract the zip file to `ESP8266_ISR_Servo-master` directory
@@ -136,7 +141,11 @@ void loop()
136141

137142
## DONE
138143

139-
For current version v1.0.1
144+
#### For current version v1.0.2
145+
146+
1. Add example using [Blynk] (http://docs.blynk.cc/) to control servos. Change example names to avoid duplication.
147+
148+
#### For current version v1.0.1
140149

141150
1. Basic 16 ISR-based servo controllers using 1 hardware timer for ESP8266.
142151

Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
/****************************************************************************************************************************
2+
* examples/ESP8266_BlynkServoControl.ino
3+
* For ESP8266 boards
4+
* Written by Khoi Hoang
5+
*
6+
* Built by Khoi Hoang https://github.com/khoih-prog/ESP8266_ISR_Servo
7+
* Licensed under MIT license
8+
* Version: v1.0.2
9+
*
10+
* The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
11+
* The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
12+
* The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short.
13+
* Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
14+
*
15+
* Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
16+
* The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
17+
* Therefore, their executions are not blocked by bad-behaving functions / tasks.
18+
* This important feature is absolutely necessary for mission-critical tasks.
19+
*
20+
* Notes:
21+
* Special design is necessary to share data between interrupt code and the rest of your program.
22+
* Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
23+
* variable can not spontaneously change. Because your function may change variables while your program is using them,
24+
* the compiler needs this hint. But volatile alone is often not enough.
25+
* When accessing shared variables, usually interrupts must be disabled. Even with volatile,
26+
* if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
27+
* If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
28+
* or the entire sequence of your code which accesses the data.
29+
*
30+
* Version Modified By Date Comments
31+
* ------- ----------- ---------- -----------
32+
* 1.0.0 K Hoang 04/12/2019 Initial release
33+
* 1.0.1 K Hoang 13/12/2019 Add more features getPosition and getPulseWidth. Optimize.
34+
* 1.0.2 K Hoang 20/12/2019 Add more Blynk examples.Change example names to avoid duplication.
35+
*****************************************************************************************************************************/
36+
37+
/****************************************************************************************************************************
38+
* This example will demonstrate the nearly perfect accuracy compared to software timers by printing the actual elapsed millisecs.
39+
* Being ISR-based timers, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet
40+
* and Blynk services. You can also have many (up to 16) timers to use.
41+
* This non-being-blocked important feature is absolutely necessary for mission-critical tasks.
42+
* You'll see blynkTimer is blocked while connecting to WiFi / Internet / Blynk, and elapsed time is very unaccurate
43+
* In this super simple example, you don't see much different after Blynk is connected, because of no competing task is
44+
* written
45+
*
46+
* From ESP32 Servo Example Using Arduino ESP32 Servo Library
47+
* John K. Bennett
48+
* March, 2017
49+
*
50+
* Different servos require different pulse widths to vary servo angle, but the range is
51+
* an approximately 500-2500 microsecond pulse every 20ms (50Hz). In general, hobbyist servos
52+
* sweep 180 degrees, so the lowest number in the published range for a particular servo
53+
* represents an angle of 0 degrees, the middle of the range represents 90 degrees, and the top
54+
* of the range represents 180 degrees. So for example, if the range is 1000us to 2000us,
55+
* 1000us would equal an angle of 0, 1500us would equal 90 degrees, and 2000us would equal 1800
56+
* degrees.
57+
*
58+
* Circuit:
59+
* Servo motors have three wires: power, ground, and signal. The power wire is typically red,
60+
* the ground wire is typically black or brown, and the signal wire is typically yellow,
61+
* orange or white. Since the ESP32 can supply limited current at only 3.3V, and servos draw
62+
* considerable power, we will connect servo power to the VBat pin of the ESP32 (located
63+
* near the USB connector). THIS IS ONLY APPROPRIATE FOR SMALL SERVOS.
64+
*
65+
* We could also connect servo power to a separate external
66+
* power source (as long as we connect all of the grounds (ESP32, servo, and external power).
67+
* In this example, we just connect ESP32 ground to servo ground. The servo signal pins
68+
* connect to any available GPIO pins on the ESP32 (in this example, we use pins
69+
* 22, 19, 23, & 18).
70+
*
71+
* In this example, we assume four Tower Pro SG90 small servos.
72+
* The published min and max for this servo are 500 and 2400, respectively.
73+
* These values actually drive the servos a little past 0 and 180, so
74+
* if you are particular, adjust the min and max values to match your needs.
75+
* Experimentally, 550 and 2350 are pretty close to 0 and 180.*
76+
*****************************************************************************************************************************/
77+
78+
#ifndef ESP8266
79+
#error This code is designed to run on ESP8266 platform, not Arduino nor ESP32! Please check your Tools->Board setting.
80+
#endif
81+
82+
#define BLYNK_PRINT Serial
83+
84+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
85+
#define LED_BUILTIN 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
86+
//PIN_D0 can't be used for PWM/I2C
87+
#define PIN_D0 16 // Pin D0 mapped to pin GPIO16/USER/WAKE of ESP8266. This pin is also used for Onboard-Blue LED. PIN_D0 = 0 => LED ON
88+
#define PIN_D1 5 // Pin D1 mapped to pin GPIO5 of ESP8266
89+
#define PIN_D2 4 // Pin D2 mapped to pin GPIO4 of ESP8266
90+
#define PIN_D3 0 // Pin D3 mapped to pin GPIO0/FLASH of ESP8266
91+
#define PIN_D4 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266
92+
#define PIN_LED 2 // Pin D4 mapped to pin GPIO2/TXD1 of ESP8266, NodeMCU and WeMoS, control on-board LED
93+
#define PIN_D5 14 // Pin D5 mapped to pin GPIO14/HSCLK of ESP8266
94+
#define PIN_D6 12 // Pin D6 mapped to pin GPIO12/HMISO of ESP8266
95+
#define PIN_D7 13 // Pin D7 mapped to pin GPIO13/RXD2/HMOSI of ESP8266
96+
#define PIN_D8 15 // Pin D8 mapped to pin GPIO15/TXD2/HCS of ESP8266
97+
98+
#define USE_SPIFFS true
99+
//#define USE_SPIFFS false
100+
101+
#define USE_BLYNK_WM true // https://github.com/khoih-prog/Blynk_WM
102+
//#define USE_BLYNK_WM false
103+
104+
//LIBRARIES INCLUDED
105+
#include <ESP8266WiFi.h>
106+
107+
#if USE_BLYNK_WM
108+
#include <BlynkSimpleEsp8266_WM.h> // https://github.com/khoih-prog/Blynk_WM
109+
#else
110+
#include <BlynkSimpleEsp8266.h>
111+
112+
//BLYNK AUTHENTICATION TOKEN
113+
char auth[] = "******";
114+
115+
116+
// MY WIFI CREDENTIALS
117+
char ssid[] = "****";
118+
char pass[] = "****";
119+
120+
#endif
121+
122+
#define TIMER_INTERRUPT_DEBUG 1
123+
#define ISR_SERVO_DEBUG 1
124+
125+
#include "ESP8266_ISR_Servo.h"
126+
127+
// MG996R servo has a running current of 500mA to 900mA @6V and a stall current of 2.5A @ 6V
128+
// Power supply must be adequate
129+
// Published values for SG90 servos; adjust if needed
130+
#define MIN_MICROS 800 //544
131+
#define MAX_MICROS 2450
132+
133+
int servoIndex1 = -1;
134+
int servoIndex2 = -1;
135+
int servoIndex3 = -1;
136+
137+
int servo1Pin = PIN_D6; //SERVO1 PIN
138+
int servo2Pin = PIN_D7; //SERVO2 PIN
139+
int servo3Pin = PIN_D8; //SERVO3 PIN
140+
141+
BlynkTimer timer;
142+
143+
// These are Blynk Slider or any Widget (STEP, Numeric Input, being able to output (unsigned) int value from 0-180.
144+
// You have to map from 0-180 inside widget or in your code. Otherwise, the library will remap the input for you.
145+
#define BLYNK_VPIN_SERVO1_CONTROL V21
146+
#define BLYNK_VPIN_SERVO2_CONTROL V22
147+
#define BLYNK_VPIN_SERVO3_CONTROL V23
148+
149+
//READING FROM VIRTUAL PINS
150+
// SERVO1
151+
BLYNK_WRITE(BLYNK_VPIN_SERVO1_CONTROL)
152+
{
153+
ISR_Servo.setPosition(servoIndex1, param.asInt());
154+
}
155+
156+
//SERVO2
157+
BLYNK_WRITE(BLYNK_VPIN_SERVO2_CONTROL)
158+
{
159+
ISR_Servo.setPosition(servoIndex2, param.asInt());
160+
}
161+
162+
//SERVO3
163+
BLYNK_WRITE(BLYNK_VPIN_SERVO3_CONTROL)
164+
{
165+
ISR_Servo.setPosition(servoIndex3, param.asInt());
166+
}
167+
168+
void heartBeatPrint(void)
169+
{
170+
static int num = 1;
171+
172+
if (WiFi.status() == WL_CONNECTED)
173+
{
174+
if (Blynk.connected())
175+
Serial.print("B"); // B means connected to Blynk
176+
else
177+
Serial.print("H"); // H means connected to WiFi but no Blynk
178+
}
179+
else
180+
Serial.print("F"); // F means not connected to WiFi and Blynk
181+
182+
if (num == 80)
183+
{
184+
Serial.println();
185+
num = 1;
186+
}
187+
else if (num++ % 10 == 0)
188+
{
189+
Serial.print(" ");
190+
}
191+
}
192+
193+
void setup()
194+
{
195+
// Debug console
196+
Serial.begin(115200);
197+
Serial.println("\nStarting");
198+
199+
#if USE_BLYNK_WM
200+
Blynk.begin();
201+
#else
202+
Blynk.begin(auth, ssid, pass);
203+
#endif
204+
205+
servoIndex1 = ISR_Servo.setupServo(servo1Pin, MIN_MICROS, MAX_MICROS);
206+
servoIndex2 = ISR_Servo.setupServo(servo2Pin, MIN_MICROS, MAX_MICROS);
207+
servoIndex3 = ISR_Servo.setupServo(servo3Pin, MIN_MICROS, MAX_MICROS);
208+
209+
if (servoIndex1 != -1)
210+
Serial.println("Setup Servo1 OK");
211+
else
212+
Serial.println("Setup Servo1 failed");
213+
214+
if (servoIndex2 != -1)
215+
Serial.println("Setup Servo2 OK");
216+
else
217+
Serial.println("Setup Servo2 failed");
218+
219+
if (servoIndex3 != -1)
220+
Serial.println("Setup Servo3 OK");
221+
else
222+
Serial.println("Setup Servo3 failed");
223+
224+
timer.setInterval(30000L, heartBeatPrint);
225+
}
226+
227+
void loop()
228+
{
229+
Blynk.run();
230+
timer.run();
231+
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/****************************************************************************************************************************
2+
* examples/ESP8266_ISR_MultiServos.ino
3+
* For ESP8266 boards
4+
* Written by Khoi Hoang
5+
*
6+
* Built by Khoi Hoang https://github.com/khoih-prog/ESP8266_ISR_Servo
7+
* Licensed under MIT license
8+
* Version: v1.0.2
9+
*
10+
* The ESP8266 timers are badly designed, using only 23-bit counter along with maximum 256 prescaler. They're only better than UNO / Mega.
11+
* The ESP8266 has two hardware timers, but timer0 has been used for WiFi and it's not advisable to use. Only timer1 is available.
12+
* The timer1's 23-bit counter terribly can count only up to 8,388,607. So the timer1 maximum interval is very short.
13+
* Using 256 prescaler, maximum timer1 interval is only 26.843542 seconds !!!
14+
*
15+
* Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
16+
* The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
17+
* Therefore, their executions are not blocked by bad-behaving functions / tasks.
18+
* This important feature is absolutely necessary for mission-critical tasks.
19+
*
20+
* Notes:
21+
* Special design is necessary to share data between interrupt code and the rest of your program.
22+
* Variables usually need to be "volatile" types. Volatile tells the compiler to avoid optimizations that assume
23+
* variable can not spontaneously change. Because your function may change variables while your program is using them,
24+
* the compiler needs this hint. But volatile alone is often not enough.
25+
* When accessing shared variables, usually interrupts must be disabled. Even with volatile,
26+
* if the interrupt changes a multi-byte variable between a sequence of instructions, it can be read incorrectly.
27+
* If your data is multiple variables, such as an array and a count, usually interrupts need to be disabled
28+
* or the entire sequence of your code which accesses the data.
29+
*
30+
* Version Modified By Date Comments
31+
* ------- ----------- ---------- -----------
32+
* 1.0.0 K Hoang 04/12/2019 Initial release
33+
* 1.0.1 K Hoang 13/12/2019 Add more features getPosition and getPulseWidth. Optimize.
34+
* 1.0.2 K Hoang 20/12/2019 Add more Blynk examples.Change example names to avoid duplication.
35+
*****************************************************************************************************************************/
36+
37+
/****************************************************************************************************************************
38+
* This example will demonstrate the nearly perfect accuracy compared to software timers by printing the actual elapsed millisecs.
39+
* Being ISR-based timers, their executions are not blocked by bad-behaving functions / tasks, such as connecting to WiFi, Internet
40+
* and Blynk services. You can also have many (up to 16) timers to use.
41+
* This non-being-blocked important feature is absolutely necessary for mission-critical tasks.
42+
* You'll see blynkTimer is blocked while connecting to WiFi / Internet / Blynk, and elapsed time is very unaccurate
43+
* In this super simple example, you don't see much different after Blynk is connected, because of no competing task is
44+
* written
45+
*
46+
* From ESP32 Servo Example Using Arduino ESP32 Servo Library
47+
* John K. Bennett
48+
* March, 2017
49+
*
50+
* Different servos require different pulse widths to vary servo angle, but the range is
51+
* an approximately 500-2500 microsecond pulse every 20ms (50Hz). In general, hobbyist servos
52+
* sweep 180 degrees, so the lowest number in the published range for a particular servo
53+
* represents an angle of 0 degrees, the middle of the range represents 90 degrees, and the top
54+
* of the range represents 180 degrees. So for example, if the range is 1000us to 2000us,
55+
* 1000us would equal an angle of 0, 1500us would equal 90 degrees, and 2000us would equal 1800
56+
* degrees.
57+
*
58+
* Circuit:
59+
* Servo motors have three wires: power, ground, and signal. The power wire is typically red,
60+
* the ground wire is typically black or brown, and the signal wire is typically yellow,
61+
* orange or white. Since the ESP32 can supply limited current at only 3.3V, and servos draw
62+
* considerable power, we will connect servo power to the VBat pin of the ESP32 (located
63+
* near the USB connector). THIS IS ONLY APPROPRIATE FOR SMALL SERVOS.
64+
*
65+
* We could also connect servo power to a separate external
66+
* power source (as long as we connect all of the grounds (ESP32, servo, and external power).
67+
* In this example, we just connect ESP32 ground to servo ground. The servo signal pins
68+
* connect to any available GPIO pins on the ESP32 (in this example, we use pins
69+
* 22, 19, 23, & 18).
70+
*
71+
* In this example, we assume four Tower Pro SG90 small servos.
72+
* The published min and max for this servo are 500 and 2400, respectively.
73+
* These values actually drive the servos a little past 0 and 180, so
74+
* if you are particular, adjust the min and max values to match your needs.
75+
* Experimentally, 550 and 2350 are pretty close to 0 and 180.*
76+
*****************************************************************************************************************************/
77+
78+
#define TIMER_INTERRUPT_DEBUG 1
79+
#define ISR_SERVO_DEBUG 1
80+
81+
#include "ESP8266_ISR_Servo.h"
82+
83+
// Published values for SG90 servos; adjust if needed
84+
#define MIN_MICROS 800 //544
85+
#define MAX_MICROS 2450
86+
87+
int servoIndex1 = -1;
88+
int servoIndex2 = -1;
89+
90+
void setup()
91+
{
92+
Serial.begin(115200);
93+
Serial.println("\nStarting");
94+
95+
servoIndex1 = ISR_Servo.setupServo(D8, MIN_MICROS, MAX_MICROS);
96+
servoIndex2 = ISR_Servo.setupServo(D7, MIN_MICROS, MAX_MICROS);
97+
98+
if (servoIndex1 != -1)
99+
Serial.println("Setup Servo1 OK");
100+
else
101+
Serial.println("Setup Servo1 failed");
102+
103+
if (servoIndex2 != -1)
104+
Serial.println("Setup Servo2 OK");
105+
else
106+
Serial.println("Setup Servo2 failed");
107+
}
108+
109+
void loop()
110+
{
111+
int position;
112+
113+
if ( ( servoIndex1 != -1) && ( servoIndex2 != -1) )
114+
{
115+
for (position = 0; position <= 180; position++)
116+
{
117+
// goes from 0 degrees to 180 degrees
118+
// in steps of 1 degree
119+
ISR_Servo.setPosition(servoIndex1, position);
120+
ISR_Servo.setPosition(servoIndex2, 180 - position);
121+
// waits 15ms for the servo to reach the position
122+
delay(50 /*15*/);
123+
}
124+
125+
for (position = 180; position >= 0; position--)
126+
{
127+
// goes from 180 degrees to 0 degrees
128+
ISR_Servo.setPosition(servoIndex1, position);
129+
ISR_Servo.setPosition(servoIndex2, 180 - position);
130+
// waits 15ms for the servo to reach the position
131+
delay(50 /*15*/);
132+
}
133+
}
134+
}

0 commit comments

Comments
 (0)