diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 65ecfb9..d079d93 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -15,11 +15,11 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
Please ensure to specify the following:
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
-* `ESP32` Core Version (e.g. ESP32 core v2.0.4)
+* `ESP32` Core Version (e.g. ESP32 core v2.0.5)
* `ESP32` Board type (e.g. ESP32_DEV Module, etc.)
* `ESP32-S2` Board type (e.g. ESP32S2_DEV Module, ESP32_S2_Saola, etc.)
* `ESP32_S3` Board type (e.g. ESP32S3_DEV, ESP32_S3_BOX, UM TINYS3, UM PROS3, UM FEATHERS3, etc.)
-* `ESP32-C3` Board type (e.g. ESP32C3_DEV Module, etc.)
+* `ESP32-C3` Board type (e.g. ESP32C3_DEV Module, LOLIN_C3_MINI, DFROBOT_BEETLE_ESP32_C3, ADAFRUIT_QTPY_ESP32C3, AirM2M_CORE_ESP32C3, XIAO_ESP32C3, etc.)
* Contextual information (e.g. what you were trying to achieve)
* Simplest possible steps to reproduce
* Anything that might be relevant in your opinion, such as:
@@ -31,14 +31,13 @@ Please ensure to specify the following:
```
Arduino IDE version: 1.8.19
-ESP32 core v2.0.4
+ESP32 core v2.0.5
ESP32S3_DEV Module
OS: Ubuntu 20.04 LTS
-Linux xy-Inspiron-3593 5.15.0-41-generic #44~20.04.1-Ubuntu SMP Fri Jun 24 13:27:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
+Linux xy-Inspiron-3593 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Context:
-I encountered a crash while trying to use the Timer Interrupt.
-
+I encountered a crash while using this library
Steps to reproduce:
1. ...
2. ...
@@ -46,13 +45,37 @@ Steps to reproduce:
4. ...
```
+### Additional context
+
+Add any other context about the problem here.
+
+---
+
### Sending Feature Requests
Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful.
There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/ESP32_New_ISR_Servo/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them.
+---
+
### Sending Pull Requests
Pull Requests with changes and fixes are also welcome!
+Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux)
+
+1. Change directory to the library GitHub
+
+```
+xy@xy-Inspiron-3593:~$ cd Arduino/xy/ESP32_New_ISR_Servo_GitHub/
+xy@xy-Inspiron-3593:~/Arduino/xy/ESP32_New_ISR_Servo_GitHub$
+```
+
+2. Issue astyle command
+
+```
+xy@xy-Inspiron-3593:~/Arduino/xy/ESP32_New_ISR_Servo_GitHub$ bash utils/restyle.sh
+```
+
+
diff --git a/README.md b/README.md
index ad34cf6..217628a 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,11 @@
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ESP32_New_ISR_Servo.svg)](http://github.com/khoih-prog/ESP32_New_ISR_Servo/issues)
-
+
+
+
+
+
---
---
@@ -123,7 +127,7 @@ This [**ESP32_New_ISR_Servo** library](https://github.com/khoih-prog/ESP32_New_I
## Prerequisites
1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest)
-2. [`ESP32 Core 2.0.4+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
+2. [`ESP32 Core 2.0.5+`](https://github.com/espressif/arduino-esp32) for ESP32-based boards. [![Latest release](https://img.shields.io/github/release/espressif/arduino-esp32.svg)](https://github.com/espressif/arduino-esp32/releases/latest/)
---
@@ -162,14 +166,14 @@ The current library implementation, using `xyz-Impl.h` instead of standard `xyz.
You can include this `.hpp` file
-```
+```cpp
// Can be included as many times as necessary, without `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.hpp" //https://github.com/khoih-prog/ESP32_New_ISR_Servo
```
in many files. But be sure to use the following `.h` file **in just 1 `.h`, `.cpp` or `.ino` file**, which must **not be included in any other file**, to avoid `Multiple Definitions` Linker Error
-```
+```cpp
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h" //https://github.com/khoih-prog/ESP32_New_ISR_Servo
```
@@ -190,22 +194,22 @@ Please have a look at [**ESP_WiFiManager Issue 39: Not able to read analog port
#### 2. ESP32 ADCs functions
-- ADC1 controls ADC function for pins **GPIO32-GPIO39**
-- ADC2 controls ADC function for pins **GPIO0, 2, 4, 12-15, 25-27**
+- `ADC1` controls ADC function for pins **GPIO32-GPIO39**
+- `ADC2` controls ADC function for pins **GPIO0, 2, 4, 12-15, 25-27**
#### 3.. ESP32 WiFi uses ADC2 for WiFi functions
-Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master/components/driver/adc_common.c#L61)
+Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master/components/driver/adc_common.c)
-> In ADC2, there're two locks used for different cases:
+> In `ADC2`, there're two locks used for different cases:
> 1. lock shared with app and Wi-Fi:
> ESP32:
-> When Wi-Fi using the ADC2, we assume it will never stop, so app checks the lock and returns immediately if failed.
+> When Wi-Fi using the `ADC2`, we assume it will never stop, so app checks the lock and returns immediately if failed.
> ESP32S2:
> The controller's control over the ADC is determined by the arbiter. There is no need to control by lock.
>
> 2. lock shared between tasks:
-> when several tasks sharing the ADC2, we want to guarantee
+> when several tasks sharing the `ADC2`, we want to guarantee
> all the requests will be handled.
> Since conversions are short (about 31us), app returns the lock very soon,
> we use a spinlock to stand there waiting to do conversions one by one.
@@ -213,10 +217,10 @@ Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master
> adc2_spinlock should be acquired first, then adc2_wifi_lock or rtc_spinlock.
-- In order to use ADC2 for other functions, we have to **acquire complicated firmware locks and very difficult to do**
-- So, it's not advisable to use ADC2 with WiFi/BlueTooth (BT/BLE).
-- Use ADC1, and pins GPIO32-GPIO39
-- If somehow it's a must to use those pins serviced by ADC2 (**GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27**), use the **fix mentioned at the end** of [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to work with ESP32 WiFi/BlueTooth (BT/BLE).
+- In order to use `ADC2` for other functions, we have to **acquire complicated firmware locks and very difficult to do**
+- So, it's not advisable to use `ADC2` with WiFi/BlueTooth (BT/BLE).
+- Use `ADC1`, and pins `GPIO32-GPIO39`
+- If somehow it's a must to use those pins serviced by `ADC2` (**GPIO0, 2, 4, 12, 13, 14, 15, 25, 26 and 27**), use the **fix mentioned at the end** of [**ESP_WiFiManager Issue 39: Not able to read analog port when using the autoconnect example**](https://github.com/khoih-prog/ESP_WiFiManager/issues/39) to work with ESP32 WiFi/BlueTooth (BT/BLE).
---
@@ -236,7 +240,7 @@ Look in file [**adc_common.c**](https://github.com/espressif/esp-idf/blob/master
### New functions
-```
+```cpp
// returns last position in degrees if success, or -1 on wrong servoIndex
float getPosition(const uint8_t& servoIndex);
@@ -274,7 +278,7 @@ You'll see blynkTimer Software is blocked while system is connecting to WiFi / I
How to use:
-```
+```cpp
#if !defined(ESP32)
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
@@ -714,7 +718,7 @@ Submit issues to: [ESP32_New_ISR_Servo issues](https://github.com/khoih-prog/ESP
9. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project
10. Fix breaking issue caused by **ESP32 core v2.0.1+** by increasing `TIMER_INTERVAL_MICRO` to `12uS` from `10uS`
10. Suppress errors and warnings for new ESP32 core v2.0.4
-
+11. Use `allman astyle` and add `utils`
---
---
diff --git a/changelog.md b/changelog.md
index 9a11475..d29e7b8 100644
--- a/changelog.md
+++ b/changelog.md
@@ -6,12 +6,19 @@
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing)
[![GitHub issues](https://img.shields.io/github/issues/khoih-prog/ESP32_New_ISR_Servo.svg)](http://github.com/khoih-prog/ESP32_New_ISR_Servo/issues)
+
+
+
+
+
+
---
---
## Table of Contents
* [Changelog](#changelog)
+ * [Releases v1.4.0](#releases-v140)
* [Releases v1.3.0](#releases-v130)
* [Releases v1.2.1](#releases-v121)
* [Releases v1.2.0](#releases-v120)
@@ -23,6 +30,12 @@
## Changelog
+### Releases v1.4.0
+
+1. Fix doubled time for `ESP32_C3, ESP32_S2 and ESP32_S3`. Check [Error in the value defined by TIMER0_INTERVAL_MS #28](https://github.com/khoih-prog/ESP32_New_ISR_Servo/issues/28)
+2. Modify examples to avoid using `LED_BUILTIN` / `GPIO2` and `GPIO2` as they can cause crash in some boards, such as `ESP32_C3`
+3. Use `allman astyle` and add `utils`
+
### Releases v1.3.0
1. Suppress errors and warnings for new ESP32 core v2.0.4+
diff --git a/examples/ESP32_New_ISR_MultiServos/ESP32_New_ISR_MultiServos.ino b/examples/ESP32_New_ISR_MultiServos/ESP32_New_ISR_MultiServos.ino
index 9db7fac..9a34832 100644
--- a/examples/ESP32_New_ISR_MultiServos/ESP32_New_ISR_MultiServos.ino
+++ b/examples/ESP32_New_ISR_MultiServos/ESP32_New_ISR_MultiServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -63,7 +63,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 0
@@ -72,17 +72,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -107,71 +110,77 @@ int servoIndex2 = -1;
void setup()
{
- Serial.begin(115200);
- while (!Serial);
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
delay(500);
- Serial.print(F("\nStarting ESP32_New_ISR_MultiServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+ Serial.print(F("\nStarting ESP32_New_ISR_MultiServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
- servoIndex1 = ESP32_ISR_Servos.setupServo(PIN_D2, MIN_MICROS, MAX_MICROS);
- servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D3, MIN_MICROS, MAX_MICROS);
+ servoIndex1 = ESP32_ISR_Servos.setupServo(PIN_D3, MIN_MICROS, MAX_MICROS);
+ servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D4, MIN_MICROS, MAX_MICROS);
- if (servoIndex1 != -1)
- Serial.println(F("Setup Servo1 OK"));
- else
- Serial.println(F("Setup Servo1 failed"));
+ if (servoIndex1 != -1)
+ Serial.println(F("Setup Servo1 OK"));
+ else
+ Serial.println(F("Setup Servo1 failed"));
- if (servoIndex2 != -1)
- Serial.println(F("Setup Servo2 OK"));
- else
- Serial.println(F("Setup Servo2 failed"));
+ if (servoIndex2 != -1)
+ Serial.println(F("Setup Servo2 OK"));
+ else
+ Serial.println(F("Setup Servo2 failed"));
}
void loop()
{
- int position;
-
- if ( ( servoIndex1 != -1) && ( servoIndex2 != -1) )
- {
- for (position = 0; position <= 180; position++)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
-
- if (position % 30 == 0)
- {
- Serial.print(F("Servo1 pos = ")); Serial.print(position);
- Serial.print(F(", Servo2 pos = ")); Serial.println(180 - position);
- }
-
- ESP32_ISR_Servos.setPosition(servoIndex1, position);
- ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
- // waits 30ms for the servo to reach the position
- delay(30);
- }
-
- delay(5000);
-
- for (position = 180; position >= 0; position--)
- {
- // goes from 180 degrees to 0 degrees
- if (position % 30 == 0)
- {
- Serial.print(F("Servo1 pos = ")); Serial.print(position);
- Serial.print(F(", Servo2 pos = ")); Serial.println(180 - position);
- }
-
- ESP32_ISR_Servos.setPosition(servoIndex1, position);
- ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
- // waits 30ms for the servo to reach the position
- delay(30);
- }
-
- delay(5000);
- }
+ int position;
+
+ if ( ( servoIndex1 != -1) && ( servoIndex2 != -1) )
+ {
+ for (position = 0; position <= 180; position++)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+
+ if (position % 30 == 0)
+ {
+ Serial.print(F("Servo1 pos = "));
+ Serial.print(position);
+ Serial.print(F(", Servo2 pos = "));
+ Serial.println(180 - position);
+ }
+
+ ESP32_ISR_Servos.setPosition(servoIndex1, position);
+ ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
+ // waits 30ms for the servo to reach the position
+ delay(30);
+ }
+
+ delay(5000);
+
+ for (position = 180; position >= 0; position--)
+ {
+ // goes from 180 degrees to 0 degrees
+ if (position % 30 == 0)
+ {
+ Serial.print(F("Servo1 pos = "));
+ Serial.print(position);
+ Serial.print(F(", Servo2 pos = "));
+ Serial.println(180 - position);
+ }
+
+ ESP32_ISR_Servos.setPosition(servoIndex1, position);
+ ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
+ // waits 30ms for the servo to reach the position
+ delay(30);
+ }
+
+ delay(5000);
+ }
}
diff --git a/examples/ESP32_New_MultipleRandomServos/ESP32_New_MultipleRandomServos.ino b/examples/ESP32_New_MultipleRandomServos/ESP32_New_MultipleRandomServos.ino
index 156159d..841927d 100644
--- a/examples/ESP32_New_MultipleRandomServos/ESP32_New_MultipleRandomServos.ino
+++ b/examples/ESP32_New_MultipleRandomServos/ESP32_New_MultipleRandomServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -62,7 +62,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 1
@@ -71,17 +71,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -105,161 +108,166 @@
typedef struct
{
- int servoIndex;
- uint8_t servoPin;
+ int servoIndex;
+ uint8_t servoPin;
} ISR_servo_t;
ISR_servo_t ISR_servo[NUM_SERVOS] =
{
- { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }
+ { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }, { -1, PIN_D8 }
};
void setup()
{
- Serial.begin(115200);
- while (!Serial);
-
- delay(200);
-
- Serial.print(F("\nStarting ESP32_New_MultipleRandomServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
-
- if (ISR_servo[index].servoIndex != -1)
- {
- Serial.print(F("Setup OK Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- else
- {
- Serial.print(F("Setup Failed Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- }
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
+
+ Serial.print(F("\nStarting ESP32_New_MultipleRandomServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
+
+ if (ISR_servo[index].servoIndex != -1)
+ {
+ Serial.print(F("Setup OK Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ else
+ {
+ Serial.print(F("Setup Failed Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ }
}
void printServoInfo(int indexServo)
{
- Serial.print(F("Servos idx = "));
- Serial.print(indexServo);
- Serial.print(F(", act. pos. (deg) = "));
- Serial.print(ESP32_ISR_Servos.getPosition(ISR_servo[indexServo].servoIndex) );
- Serial.print(F(", pulseWidth (us) = "));
- Serial.println(ESP32_ISR_Servos.getPulseWidth(ISR_servo[indexServo].servoIndex));
+ Serial.print(F("Servos idx = "));
+ Serial.print(indexServo);
+ Serial.print(F(", act. pos. (deg) = "));
+ Serial.print(ESP32_ISR_Servos.getPosition(ISR_servo[indexServo].servoIndex) );
+ Serial.print(F(", pulseWidth (us) = "));
+ Serial.println(ESP32_ISR_Servos.getPulseWidth(ISR_servo[indexServo].servoIndex));
}
void loop()
{
- int position; // position in degrees
-
- position = 0;
- Serial.println(F("Servos @ 0 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
- // waits 5s between test
- delay(5000);
-
- position = 90;
- Serial.println(F("Servos @ 90 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
-
- // waits 5s between test
- delay(5000);
-
- position = 180;
- Serial.println(F("Servos @ 180 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos sweeps from 0-180 degress"));
-
- for (position = 0; position <= 180; position += 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos sweeps from 180-0 degress"));
-
- for (position = 180; position >= 0; position -= 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos, index depending, be somewhere from 0-180 degress"));
-
- for (position = 0; position <= 180; position += 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- delay(5000);
-
- Serial.println(F("Servos, index depending, be somewhere from 180-0 degress"));
-
- for (position = 180; position >= 0; position -= 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
+ int position; // position in degrees
+
+ position = 0;
+ Serial.println(F("Servos @ 0 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ position = 90;
+ Serial.println(F("Servos @ 90 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ position = 180;
+ Serial.println(F("Servos @ 180 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos sweeps from 0-180 degress"));
+
+ for (position = 0; position <= 180; position += 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos sweeps from 180-0 degress"));
+
+ for (position = 180; position >= 0; position -= 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos, index depending, be somewhere from 0-180 degress"));
+
+ for (position = 0; position <= 180; position += 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ delay(5000);
+
+ Serial.println(F("Servos, index depending, be somewhere from 180-0 degress"));
+
+ for (position = 180; position >= 0; position -= 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
}
diff --git a/examples/ESP32_New_MultipleServos/ESP32_New_MultipleServos.ino b/examples/ESP32_New_MultipleServos/ESP32_New_MultipleServos.ino
index fc11491..ac9f4e5 100644
--- a/examples/ESP32_New_MultipleServos/ESP32_New_MultipleServos.ino
+++ b/examples/ESP32_New_MultipleServos/ESP32_New_MultipleServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -63,7 +63,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 0
@@ -72,17 +72,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -106,72 +109,76 @@
typedef struct
{
- int servoIndex;
- uint8_t servoPin;
+ int servoIndex;
+ uint8_t servoPin;
} ISR_servo_t;
ISR_servo_t ISR_servo[NUM_SERVOS] =
{
- { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }
+ { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }, { -1, PIN_D8 }
};
void setup()
{
- Serial.begin(115200);
- while (!Serial);
-
- delay(200);
-
- Serial.print(F("\nStarting ESP32_New_MultipleServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
-
- if (ISR_servo[index].servoIndex != -1)
- {
- Serial.print(F("Setup OK Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- else
- {
- Serial.print(F("Setup Failed Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- }
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
+
+ Serial.print(F("\nStarting ESP32_New_MultipleServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
+
+ if (ISR_servo[index].servoIndex != -1)
+ {
+ Serial.print(F("Setup OK Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ else
+ {
+ Serial.print(F("Setup Failed Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ }
}
void loop()
{
- int position; // position in degrees
-
- for (position = 0; position <= 180; position += 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 1s for the servo to reach the position
- delay(1000);
- }
-
- for (position = 180; position >= 0; position -= 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180);
- }
-
- // waits 1s for the servo to reach the position
- delay(1000);
- }
-
- delay(5000);
+ int position; // position in degrees
+
+ for (position = 0; position <= 180; position += 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 1s for the servo to reach the position
+ delay(1000);
+ }
+
+ for (position = 180; position >= 0; position -= 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180);
+ }
+
+ // waits 1s for the servo to reach the position
+ delay(1000);
+ }
+
+ delay(5000);
}
diff --git a/examples/ISR_MultiServos/ISR_MultiServos.ino b/examples/ISR_MultiServos/ISR_MultiServos.ino
index 136f412..e757249 100644
--- a/examples/ISR_MultiServos/ISR_MultiServos.ino
+++ b/examples/ISR_MultiServos/ISR_MultiServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -63,7 +63,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 0
@@ -72,17 +72,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -107,71 +110,77 @@ int servoIndex2 = -1;
void setup()
{
- Serial.begin(115200);
- while (!Serial);
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
- delay(200);
+ Serial.print(F("\nStarting ISR_MultiServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
- Serial.print(F("\nStarting ISR_MultiServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
- servoIndex1 = ESP32_ISR_Servos.setupServo(PIN_D2, MIN_MICROS, MAX_MICROS);
- servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D3, MIN_MICROS, MAX_MICROS);
+ servoIndex1 = ESP32_ISR_Servos.setupServo(PIN_D3, MIN_MICROS, MAX_MICROS);
+ servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D4, MIN_MICROS, MAX_MICROS);
- if (servoIndex1 != -1)
- Serial.println(F("Setup Servo1 OK"));
- else
- Serial.println(F("Setup Servo1 failed"));
+ if (servoIndex1 != -1)
+ Serial.println(F("Setup Servo1 OK"));
+ else
+ Serial.println(F("Setup Servo1 failed"));
- if (servoIndex2 != -1)
- Serial.println(F("Setup Servo2 OK"));
- else
- Serial.println(F("Setup Servo2 failed"));
+ if (servoIndex2 != -1)
+ Serial.println(F("Setup Servo2 OK"));
+ else
+ Serial.println(F("Setup Servo2 failed"));
}
void loop()
{
- int position;
-
- if ( ( servoIndex1 != -1) && ( servoIndex2 != -1) )
- {
- for (position = 0; position <= 180; position++)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
-
- if (position % 30 == 0)
- {
- Serial.print(F("Servo1 pos = ")); Serial.print(position);
- Serial.print(F(", Servo2 pos = ")); Serial.println(180 - position);
- }
-
- ESP32_ISR_Servos.setPosition(servoIndex1, position);
- ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
- // waits 30ms for the servo to reach the position
- delay(30);
- }
-
- delay(5000);
-
- for (position = 180; position >= 0; position--)
- {
- // goes from 180 degrees to 0 degrees
- if (position % 30 == 0)
- {
- Serial.print(F("Servo1 pos = ")); Serial.print(position);
- Serial.print(F(", Servo2 pos = ")); Serial.println(180 - position);
- }
-
- ESP32_ISR_Servos.setPosition(servoIndex1, position);
- ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
- // waits 30ms for the servo to reach the position
- delay(30);
- }
-
- delay(5000);
- }
+ int position;
+
+ if ( ( servoIndex1 != -1) && ( servoIndex2 != -1) )
+ {
+ for (position = 0; position <= 180; position++)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+
+ if (position % 30 == 0)
+ {
+ Serial.print(F("Servo1 pos = "));
+ Serial.print(position);
+ Serial.print(F(", Servo2 pos = "));
+ Serial.println(180 - position);
+ }
+
+ ESP32_ISR_Servos.setPosition(servoIndex1, position);
+ ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
+ // waits 30ms for the servo to reach the position
+ delay(30);
+ }
+
+ delay(5000);
+
+ for (position = 180; position >= 0; position--)
+ {
+ // goes from 180 degrees to 0 degrees
+ if (position % 30 == 0)
+ {
+ Serial.print(F("Servo1 pos = "));
+ Serial.print(position);
+ Serial.print(F(", Servo2 pos = "));
+ Serial.println(180 - position);
+ }
+
+ ESP32_ISR_Servos.setPosition(servoIndex1, position);
+ ESP32_ISR_Servos.setPosition(servoIndex2, 180 - position);
+ // waits 30ms for the servo to reach the position
+ delay(30);
+ }
+
+ delay(5000);
+ }
}
diff --git a/examples/MultipleRandomServos/MultipleRandomServos.ino b/examples/MultipleRandomServos/MultipleRandomServos.ino
index 93c81d5..46bf240 100644
--- a/examples/MultipleRandomServos/MultipleRandomServos.ino
+++ b/examples/MultipleRandomServos/MultipleRandomServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -63,7 +63,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 0
@@ -72,17 +72,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -106,161 +109,165 @@
typedef struct
{
- int servoIndex;
- uint8_t servoPin;
+ int servoIndex;
+ uint8_t servoPin;
} ISR_servo_t;
ISR_servo_t ISR_servo[NUM_SERVOS] =
{
- { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }
+ { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }, { -1, PIN_D8 }
};
void setup()
{
- Serial.begin(115200);
- while (!Serial);
-
- delay(200);
-
- Serial.print(F("\nStarting MultipleRandomServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
-
- if (ISR_servo[index].servoIndex != -1)
- {
- Serial.print(F("Setup OK Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- else
- {
- Serial.print(F("Setup Failed Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- }
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
+
+ Serial.print(F("\nStarting MultipleRandomServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
+
+ if (ISR_servo[index].servoIndex != -1)
+ {
+ Serial.print(F("Setup OK Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ else
+ {
+ Serial.print(F("Setup Failed Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ }
}
void printServoInfo(int indexServo)
{
- Serial.print(F("Servos idx = "));
- Serial.print(indexServo);
- Serial.print(F(", act. pos. (deg) = "));
- Serial.print(ESP32_ISR_Servos.getPosition(ISR_servo[indexServo].servoIndex) );
- Serial.print(F(", pulseWidth (us) = "));
- Serial.println(ESP32_ISR_Servos.getPulseWidth(ISR_servo[indexServo].servoIndex));
+ Serial.print(F("Servos idx = "));
+ Serial.print(indexServo);
+ Serial.print(F(", act. pos. (deg) = "));
+ Serial.print(ESP32_ISR_Servos.getPosition(ISR_servo[indexServo].servoIndex) );
+ Serial.print(F(", pulseWidth (us) = "));
+ Serial.println(ESP32_ISR_Servos.getPulseWidth(ISR_servo[indexServo].servoIndex));
}
void loop()
{
- int position; // position in degrees
-
- position = 0;
- Serial.println(F("Servos @ 0 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
-
- // waits 5s between test
- delay(5000);
-
- position = 90;
- Serial.println(F("Servos @ 90 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
-
- // waits 5s between test
- delay(5000);
-
- position = 180;
- Serial.println(F("Servos @ 180 degree"));
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- printServoInfo(index);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos sweeps from 0-180 degress"));
-
- for (position = 0; position <= 180; position += 1)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos sweeps from 180-0 degress"));
-
- for (position = 180; position >= 0; position -= 1)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
-
- Serial.println(F("Servos, index depending, be somewhere from 0-180 degress"));
-
- for (position = 0; position <= 180; position += 1)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- delay(5000);
-
- Serial.println(F("Servos, index depending, be somewhere from 180-0 degress"));
-
- for (position = 180; position >= 0; position -= 1)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 50ms for the servo to reach the position
- delay(50);
- }
-
- // waits 5s between test
- delay(5000);
+ int position; // position in degrees
+
+ position = 0;
+ Serial.println(F("Servos @ 0 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ position = 90;
+ Serial.println(F("Servos @ 90 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ position = 180;
+ Serial.println(F("Servos @ 180 degree"));
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ printServoInfo(index);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos sweeps from 0-180 degress"));
+
+ for (position = 0; position <= 180; position += 1)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos sweeps from 180-0 degress"));
+
+ for (position = 180; position >= 0; position -= 1)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
+
+ Serial.println(F("Servos, index depending, be somewhere from 0-180 degress"));
+
+ for (position = 0; position <= 180; position += 1)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ delay(5000);
+
+ Serial.println(F("Servos, index depending, be somewhere from 180-0 degress"));
+
+ for (position = 180; position >= 0; position -= 1)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 50ms for the servo to reach the position
+ delay(50);
+ }
+
+ // waits 5s between test
+ delay(5000);
}
diff --git a/examples/MultipleServos/MultipleServos.ino b/examples/MultipleServos/MultipleServos.ino
index 7bf508d..3dbf5a2 100644
--- a/examples/MultipleServos/MultipleServos.ino
+++ b/examples/MultipleServos/MultipleServos.ino
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -63,7 +63,7 @@
*****************************************************************************************************************************/
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define TIMER_INTERRUPT_DEBUG 0
@@ -72,17 +72,20 @@
// For ESP32_C3, select ESP32 timer number (0-1)
// For ESP32 and ESP32_S2, select ESP32 timer number (0-3)
#if defined( ARDUINO_ESP32C3_DEV )
- #define USE_ESP32_TIMER_NO 1
+ #define USE_ESP32_TIMER_NO 1
#else
- #define USE_ESP32_TIMER_NO 3
+ #define USE_ESP32_TIMER_NO 3
#endif
-
+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
+// Don't use PIN_D1 in core v2.0.0 and v2.0.1. Check https://github.com/espressif/arduino-esp32/issues/5868
+// Don't use PIN_D2 with ESP32_C3 (crash)
+
//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#if !defined(LED_BUILTIN)
- #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
+ #define LED_BUILTIN 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#endif
#define PIN_LED 2 // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
@@ -106,72 +109,76 @@
typedef struct
{
- int servoIndex;
- uint8_t servoPin;
+ int servoIndex;
+ uint8_t servoPin;
} ISR_servo_t;
ISR_servo_t ISR_servo[NUM_SERVOS] =
{
- { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }
+ { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 }, { -1, PIN_D7 }, { -1, PIN_D8 }
};
void setup()
{
- Serial.begin(115200);
- while (!Serial);
-
- delay(200);
-
- Serial.print(F("\nStarting MultipleServos on ")); Serial.println(ARDUINO_BOARD);
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
-
- //Select ESP32 timer USE_ESP32_TIMER_NO
- ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
-
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
-
- if (ISR_servo[index].servoIndex != -1)
- {
- Serial.print(F("Setup OK Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- else
- {
- Serial.print(F("Setup Failed Servo index = ")); Serial.println(ISR_servo[index].servoIndex);
- }
- }
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
+
+ Serial.print(F("\nStarting MultipleServos on "));
+ Serial.println(ARDUINO_BOARD);
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+
+ //Select ESP32 timer USE_ESP32_TIMER_NO
+ ESP32_ISR_Servos.useTimer(USE_ESP32_TIMER_NO);
+
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ISR_servo[index].servoIndex = ESP32_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS);
+
+ if (ISR_servo[index].servoIndex != -1)
+ {
+ Serial.print(F("Setup OK Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ else
+ {
+ Serial.print(F("Setup Failed Servo index = "));
+ Serial.println(ISR_servo[index].servoIndex);
+ }
+ }
}
void loop()
{
- int position; // position in degrees
-
- for (position = 0; position <= 180; position += 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
- }
-
- // waits 1s for the servo to reach the position
- delay(1000);
- }
-
- for (position = 180; position >= 0; position -= 5)
- {
- // goes from 0 degrees to 180 degrees
- // in steps of 1 degree
- for (int index = 0; index < NUM_SERVOS; index++)
- {
- ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180);
- }
-
- // waits 1s for the servo to reach the position
- delay(1000);
- }
-
- delay(5000);
+ int position; // position in degrees
+
+ for (position = 0; position <= 180; position += 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180 );
+ }
+
+ // waits 1s for the servo to reach the position
+ delay(1000);
+ }
+
+ for (position = 180; position >= 0; position -= 5)
+ {
+ // goes from 0 degrees to 180 degrees
+ // in steps of 1 degree
+ for (int index = 0; index < NUM_SERVOS; index++)
+ {
+ ESP32_ISR_Servos.setPosition(ISR_servo[index].servoIndex, (position + index * (180 / NUM_SERVOS)) % 180);
+ }
+
+ // waits 1s for the servo to reach the position
+ delay(1000);
+ }
+
+ delay(5000);
}
diff --git a/examples/multiFileProject/multiFileProject.cpp b/examples/multiFileProject/multiFileProject.cpp
index e4f7fb0..fcc3065 100644
--- a/examples/multiFileProject/multiFileProject.cpp
+++ b/examples/multiFileProject/multiFileProject.cpp
@@ -1,6 +1,6 @@
/****************************************************************************************************************************
multiFileProject.cpp
-
+
For ESP32, ESP32_S2, ESP32_C3 boards with ESP32 core v2.0.0-rc1+
Written by Khoi Hoang
diff --git a/examples/multiFileProject/multiFileProject.h b/examples/multiFileProject/multiFileProject.h
index 58c28a9..484ede8 100644
--- a/examples/multiFileProject/multiFileProject.h
+++ b/examples/multiFileProject/multiFileProject.h
@@ -1,6 +1,6 @@
/****************************************************************************************************************************
multiFileProject.h
-
+
For ESP32, ESP32_S2, ESP32_C3 boards with ESP32 core v2.0.0-rc1+
Written by Khoi Hoang
diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino
index 9bd7e66..27e3d14 100644
--- a/examples/multiFileProject/multiFileProject.ino
+++ b/examples/multiFileProject/multiFileProject.ino
@@ -1,6 +1,6 @@
/****************************************************************************************************************************
multiFileProject.ino
-
+
For ESP32, ESP32_S2, ESP32_C3 boards with ESP32 core v2.0.0-rc1+
Written by Khoi Hoang
@@ -11,7 +11,7 @@
// To demo how to include files in multi-file Projects
#if !defined(ESP32)
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+ #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
#define ESP32_NEW_ISR_SERVO_VERSION_MIN_TARGET "ESP32_New_ISR_Servo v1.3.0"
@@ -22,24 +22,29 @@
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_New_ISR_Servo.h"
-void setup()
+void setup()
{
- Serial.begin(115200);
- while (!Serial);
-
- Serial.println("\nStart multiFileProject");
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
+ Serial.begin(115200);
+
+ while (!Serial && millis() < 5000);
+
+ delay(500);
+
+ Serial.println("\nStart multiFileProject");
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION);
#if defined(ESP32_NEW_ISR_SERVO_VERSION_MIN)
- if (ESP32_NEW_ISR_SERVO_VERSION_INT < ESP32_NEW_ISR_SERVO_VERSION_MIN)
- {
- Serial.print("Warning. Must use this example on Version equal or later than : ");
- Serial.println(ESP32_NEW_ISR_SERVO_VERSION_MIN_TARGET);
- }
+
+ if (ESP32_NEW_ISR_SERVO_VERSION_INT < ESP32_NEW_ISR_SERVO_VERSION_MIN)
+ {
+ Serial.print("Warning. Must use this example on Version equal or later than : ");
+ Serial.println(ESP32_NEW_ISR_SERVO_VERSION_MIN_TARGET);
+ }
+
#endif
}
-void loop()
+void loop()
{
- // put your main code here, to run repeatedly:
+ // put your main code here, to run repeatedly:
}
diff --git a/library.json b/library.json
index aa0288b..11251b0 100644
--- a/library.json
+++ b/library.json
@@ -1,8 +1,8 @@
{
"name": "ESP32_New_ISR_Servo",
- "version": "1.3.0",
+ "version": "1.4.0",
"keywords": "timer, interrupt, isr, hardware, servo, isr-based-servo, servo-control, esp32, esp32-s2, esp32-s3, esp32-c3, mission-critical, precise, non-blocking",
- "description": "This library enables you to use 1 Hardware Timer on an ESP32, ESP32_S2, ESP32_C3-based board to control up to 16 or more servo motors. Tested OK with ESP32 core v2.0.4",
+ "description": "This library enables you to use 1 Hardware Timer on an ESP32, ESP32_S2, ESP32_C3-based board to control up to 16 or more servo motors. Tested OK with ESP32 core v2.0.5",
"authors":
{
"name": "Khoi Hoang",
diff --git a/library.properties b/library.properties
index 1607c2e..5d9f295 100644
--- a/library.properties
+++ b/library.properties
@@ -1,10 +1,10 @@
name=ESP32_New_ISR_Servo
-version=1.3.0
+version=1.4.0
author=Khoi Hoang
maintainer=Khoi Hoang
license=MIT
sentence=This library enables you to use Interrupt from Hardware Timers on ESP32, ESP32_S2, ESP32_S3, ESP32_C3 boards to control multiple servo motors.
-paragraph=This library enables you to use 1 Hardware Timer on ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards to control 16 or more servo motors. Tested OK with ESP32 core v2.0.4
+paragraph=This library enables you to use 1 Hardware Timer on ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards to control 16 or more servo motors. Tested OK with ESP32 core v2.0.5
category=Device Control
url=https://github.com/khoih-prog/ESP32_New_ISR_Servo
architectures=esp32
diff --git a/src/ESP32_New_FastTimerInterrupt.h b/src/ESP32_New_FastTimerInterrupt.h
index 9fa15e8..64a6dd4 100644
--- a/src/ESP32_New_FastTimerInterrupt.h
+++ b/src/ESP32_New_FastTimerInterrupt.h
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -27,7 +27,7 @@
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
- Version: 1.3.0
+ Version: 1.4.0
Version Modified By Date Comments
------- ----------- ---------- -----------
@@ -36,6 +36,7 @@
1.2.0 K Hoang 08/05/2022 Fix issue with core v2.0.1+
1.2.1 K Hoang 16/06/2022 Add support to new Adafruit boards
1.3.0 K Hoang 03/08/2022 Suppress errors and warnings for new ESP32 core
+ 1.4.0 K Hoang 16/11/2022 Fix doubled time for ESP32_C3, ESP32_S2 and ESP32_S3
*****************************************************************************************************************************/
#pragma once
@@ -43,112 +44,134 @@
#ifndef ESP32_New_FastTimerInterrupt_h
#define ESP32_New_FastTimerInterrupt_h
+////////////////////////////////////////
+
#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \
ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \
ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM || ARDUINO_ADAFRUIT_QTPY_ESP32S2)
- #define USING_ESP32_S2_NEW_ISR_SERVO true
+#define USING_ESP32_S2_NEW_ISR_SERVO true
+#define USING_ESP32_S2_TIMERINTERRUPT true
+
+////////////////////////////////////////
+
#elif ( defined(ARDUINO_ESP32S3_DEV) || defined(ARDUINO_ESP32_S3_BOX) || defined(ARDUINO_TINYS3) || \
defined(ARDUINO_PROS3) || defined(ARDUINO_FEATHERS3) || defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM))
- #define USING_ESP32_S3_NEW_ISR_SERVO true
+#define USING_ESP32_S3_NEW_ISR_SERVO true
+#define USING_ESP32_S3_TIMERINTERRUPT true
+
+////////////////////////////////////////
+
#elif ( ARDUINO_ESP32C3_DEV )
- #define USING_ESP32_C3_NEW_ISR_SERVO true
+#define USING_ESP32_C3_NEW_ISR_SERVO true
+#define USING_ESP32_C3_TIMERINTERRUPT true
+
+////////////////////////////////////////
+
#elif defined(ESP32)
- #define USING_ESP32_NEW_ISR_SERVO true
+#define USING_ESP32_NEW_ISR_SERVO true
+#define USING_ESP32_TIMERINTERRUPT true
+
+////////////////////////////////////////
+
#else
- #error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
+#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
+////////////////////////////////////////
+
#include "ESP32_New_ISR_Servo_Debug.h"
#include
+////////////////////////////////////////
+
/*
//ESP32 core v1.0.6, hw_timer_t defined in esp32/tools/sdk/include/driver/driver/timer.h:
- #define TIMER_BASE_CLK (APB_CLK_FREQ) //Frequency of the clock on the input of the timer groups
+ #define TIMER_BASE_CLK (APB_CLK_FREQ) //Frequency of the clock on the input of the timer groups
- //@brief Selects a Timer-Group out of 2 available groups
-
-typedef enum
-{
+ //@brief Selects a Timer-Group out of 2 available groups
+
+ typedef enum
+ {
TIMER_GROUP_0 = 0, // Hw timer group 0
TIMER_GROUP_1 = 1, // Hw timer group 1
TIMER_GROUP_MAX,
-} timer_group_t;
+ } timer_group_t;
- //@brief Select a hardware timer from timer groups
-
-typedef enum
-{
+ //@brief Select a hardware timer from timer groups
+
+ typedef enum
+ {
TIMER_0 = 0, // Select timer0 of GROUPx
TIMER_1 = 1, // Select timer1 of GROUPx
TIMER_MAX,
-} timer_idx_t;
+ } timer_idx_t;
- //@brief Decides the direction of counter
-
-typedef enum
-{
+ //@brief Decides the direction of counter
+
+ typedef enum
+ {
TIMER_COUNT_DOWN = 0, //Descending Count from cnt.high|cnt.low
TIMER_COUNT_UP = 1, //Ascending Count from Zero
TIMER_COUNT_MAX
-} timer_count_dir_t;
+ } timer_count_dir_t;
- //@brief Decides whether timer is on or paused
-
-typedef enum
-{
+ //@brief Decides whether timer is on or paused
+
+ typedef enum
+ {
TIMER_PAUSE = 0, //Pause timer counter
TIMER_START = 1, //Start timer counter
-} timer_start_t;
+ } timer_start_t;
- //@brief Decides whether to enable alarm mode
-
-typedef enum
-{
+ //@brief Decides whether to enable alarm mode
+
+ typedef enum
+ {
TIMER_ALARM_DIS = 0, //Disable timer alarm
TIMER_ALARM_EN = 1, //Enable timer alarm
TIMER_ALARM_MAX
-} timer_alarm_t;
+ } timer_alarm_t;
- //@brief Select interrupt type if running in alarm mode.
-
-typedef enum
-{
+ //@brief Select interrupt type if running in alarm mode.
+
+ typedef enum
+ {
TIMER_INTR_LEVEL = 0, //Interrupt mode: level mode
//TIMER_INTR_EDGE = 1, //Interrupt mode: edge mode, Not supported Now
TIMER_INTR_MAX
-} timer_intr_mode_t;
+ } timer_intr_mode_t;
- //@brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
-
-typedef enum
-{
+ //@brief Select if Alarm needs to be loaded by software or automatically reload by hardware.
+
+ typedef enum
+ {
TIMER_AUTORELOAD_DIS = 0, //Disable auto-reload: hardware will not load counter value after an alarm event
TIMER_AUTORELOAD_EN = 1, //Enable auto-reload: hardware will load counter value after an alarm event
TIMER_AUTORELOAD_MAX,
-} timer_autoreload_t;
+ } timer_autoreload_t;
- //@brief Data structure with timer's configuration settings
-
-typedef struct
-{
- bool alarm_en; //Timer alarm enable
- bool counter_en; //Counter enable
- timer_intr_mode_t intr_type; //Interrupt mode
- timer_count_dir_t counter_dir; //Counter direction
- bool auto_reload; //Timer auto-reload
- uint32_t divider; //Counter clock divider. The divider's range is from from 2 to 65536.
-} timer_config_t;
+ //@brief Data structure with timer's configuration settings
+
+ typedef struct
+ {
+ bool alarm_en; //Timer alarm enable
+ bool counter_en; //Counter enable
+ timer_intr_mode_t intr_type; //Interrupt mode
+ timer_count_dir_t counter_dir; //Counter direction
+ bool auto_reload; //Timer auto-reload
+ uint32_t divider; //Counter clock divider. The divider's range is from from 2 to 65536.
+ } timer_config_t;
*/
@@ -174,32 +197,39 @@ typedef struct
*/
+////////////////////////////////////////
+
#ifndef USE_ESP32_TIMER_NO
#define USE_ESP32_TIMER_NO 1
#endif
-#if USING_ESP32_C3_NEW_ISR_SERVO
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
#ifndef USE_ESP32_TIMER_NO
#define USE_ESP32_TIMER_NO 1
#endif
-
+
#define MAX_ESP32_NUM_TIMERS 2
#else
#ifndef USE_ESP32_TIMER_NO
#define USE_ESP32_TIMER_NO 3
#endif
-
+
#define MAX_ESP32_NUM_TIMERS 4
#endif
+////////////////////////////////////////
+
class ESP32FastTimerInterrupt;
typedef ESP32FastTimerInterrupt ESP32FastTimer;
+////////////////////////////////////////
+
#define TIMER_DIVIDER 80 // Hardware timer clock divider
// TIMER_BASE_CLK = APB_CLK_FREQ = Frequency of the clock on the input of the timer groups
#define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
+////////////////////////////////////////
// In esp32/1.0.6/tools/sdk/esp32s2/include/driver/include/driver/timer.h
// typedef bool (*timer_isr_t)(void *);
@@ -209,14 +239,19 @@ typedef ESP32FastTimerInterrupt ESP32FastTimer;
//esp_err_t timer_group_intr_enable(timer_group_t group_num, timer_intr_t intr_mask);
//esp_err_t timer_group_intr_disable(timer_group_t group_num, timer_intr_t intr_mask);
+////////////////////////////////////////
typedef bool (*esp32_timer_callback) (void *);
+////////////////////////////////////////
+
class ESP32FastTimerInterrupt
{
private:
-
- timer_config_t stdConfig =
+
+ ////////////////////////////////////////
+
+ timer_config_t stdConfig =
{
.alarm_en = TIMER_ALARM_EN, //enable timer alarm
.counter_en = TIMER_START, //starts counting counter once timer_init called
@@ -224,15 +259,21 @@ class ESP32FastTimerInterrupt
.counter_dir = TIMER_COUNT_UP, //counts from 0 to counter value
.auto_reload = TIMER_AUTORELOAD_EN, //reloads counter automatically
.divider = TIMER_DIVIDER,
-#if SOC_TIMER_GROUP_SUPPORT_XTAL
+#if (SOC_TIMER_GROUP_SUPPORT_XTAL)
+#if ( USING_ESP32_NEW_ISR_SERVO || USING_ESP32_TIMERINTERRUPT )
.clk_src = TIMER_SRC_CLK_XTAL //Use XTAL as source clock
-#endif
+#else
+ .clk_src = TIMER_SRC_CLK_APB //Use APB as source clock
+#endif
+#endif
};
+ ////////////////////////////////////////
+
timer_idx_t _timerIndex;
timer_group_t _timerGroup;
uint32_t interruptFlag; // either TIMER_INTR_T0 or TIMER_INTR_T1
-
+
uint8_t _timerNo;
esp32_timer_callback _callback; // pointer to the callback function
@@ -241,108 +282,114 @@ class ESP32FastTimerInterrupt
public:
+ ////////////////////////////////////////
+
ESP32FastTimerInterrupt(uint8_t timerNo)
- {
+ {
if (timerNo < MAX_ESP32_NUM_TIMERS)
{
_timerNo = timerNo;
-#if USING_ESP32_C3_NEW_ISR_SERVO
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
// Always using TIMER_INTR_T0
_timerIndex = (timer_idx_t) ( (uint32_t) 0 );
-
+
// timerNo == 0 => Group 0, timerNo == 1 => Group 1
_timerGroup = (timer_group_t) ( (uint32_t) timerNo);
-
+
#else
-
+
_timerIndex = (timer_idx_t) (_timerNo % TIMER_MAX);
-
+
_timerGroup = (timer_group_t) (_timerNo / TIMER_MAX);
-
-#endif
+
+#endif
}
else
{
_timerNo = MAX_ESP32_NUM_TIMERS;
}
-
+
_frequency = 0;
_timerCount = 0;
- _callback = NULL;
+ _callback = NULL;
};
+ ////////////////////////////////////////
+
// frequency (in hertz)
// No params and duration now. To be added in the future by adding similar functions here or to esp32-hal-timer.c
bool setFrequency(const float& frequency, esp32_timer_callback callback)
{
if (_timerNo < MAX_ESP32_NUM_TIMERS)
- {
+ {
// select timer frequency is 1MHz for better accuracy. We don't use 16-bit prescaler for now.
// Will use later if very low frequency is needed.
_frequency = TIMER_BASE_CLK / TIMER_DIVIDER; //1000000;
_timerCount = (uint64_t) _frequency / frequency;
// count up
-#if USING_ESP32_C3_NEW_ISR_SERVO
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
ISR_SERVO_LOGERROR3(F("ESP32_C3_TimerInterrupt: _timerNo ="), _timerNo, F(", _fre ="), TIMER_BASE_CLK / TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("TIMER_BASE_CLK ="), TIMER_BASE_CLK, F(", TIMER_DIVIDER ="), TIMER_DIVIDER);
-#elif USING_ESP32_S2_NEW_ISR_SERVO
+#elif (USING_ESP32_S2_NEW_ISR_SERVO || USING_ESP32_S2_TIMERINTERRUPT)
ISR_SERVO_LOGERROR3(F("ESP32_S2_TimerInterrupt: _timerNo ="), _timerNo, F(", _fre ="), TIMER_BASE_CLK / TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("TIMER_BASE_CLK ="), TIMER_BASE_CLK, F(", TIMER_DIVIDER ="), TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("_timerIndex ="), _timerIndex, F(", _timerGroup ="), _timerGroup);
- ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32) , F("-"), (uint32_t) (_timerCount));
+ ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32), F("-"), (uint32_t) (_timerCount));
ISR_SERVO_LOGERROR1(F("timer_set_alarm_value ="), TIMER_SCALE / frequency);
-#elif USING_ESP32_S3_NEW_ISR_SERVO
+#elif (USING_ESP32_S3_NEW_ISR_SERVO || USING_ESP32_S3_TIMERINTERRUPT)
// ESP32-S3 is embedded with four 54-bit general-purpose timers, which are based on 16-bit prescalers
// and 54-bit auto-reload-capable up/down-timers
ISR_SERVO_LOGERROR3(F("ESP32_S3_TimerInterrupt: _timerNo ="), _timerNo, F(", _fre ="), TIMER_BASE_CLK / TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("TIMER_BASE_CLK ="), TIMER_BASE_CLK, F(", TIMER_DIVIDER ="), TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("_timerIndex ="), _timerIndex, F(", _timerGroup ="), _timerGroup);
- ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32) , F("-"), (uint32_t) (_timerCount));
- ISR_SERVO_LOGERROR1(F("timer_set_alarm_value ="), TIMER_SCALE / frequency);
+ ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32), F("-"), (uint32_t) (_timerCount));
+ ISR_SERVO_LOGERROR1(F("timer_set_alarm_value ="), TIMER_SCALE / frequency);
#else
ISR_SERVO_LOGERROR3(F("ESP32_TimerInterrupt: _timerNo ="), _timerNo, F(", _fre ="), TIMER_BASE_CLK / TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("TIMER_BASE_CLK ="), TIMER_BASE_CLK, F(", TIMER_DIVIDER ="), TIMER_DIVIDER);
ISR_SERVO_LOGERROR3(F("_timerIndex ="), _timerIndex, F(", _timerGroup ="), _timerGroup);
- ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32) , F("-"), (uint32_t) (_timerCount));
+ ISR_SERVO_LOGERROR3(F("_count ="), (uint32_t) (_timerCount >> 32), F("-"), (uint32_t) (_timerCount));
ISR_SERVO_LOGERROR1(F("timer_set_alarm_value ="), TIMER_SCALE / frequency);
#endif
-
+
timer_init(_timerGroup, _timerIndex, &stdConfig);
-
+
// Counter value to 0 => counting up to alarm value as .counter_dir == TIMER_COUNT_UP
- timer_set_counter_value(_timerGroup, _timerIndex , 0x00000000ULL);
-
+ timer_set_counter_value(_timerGroup, _timerIndex, 0x00000000ULL);
+
timer_set_alarm_value(_timerGroup, _timerIndex, TIMER_SCALE / frequency);
-
+
// enable interrupts for _timerGroup, _timerIndex
timer_enable_intr(_timerGroup, _timerIndex);
-
+
_callback = callback;
-
- // Register the ISR handler
+
+ // Register the ISR handler
// If the intr_alloc_flags value ESP_INTR_FLAG_IRAM is set, the handler function must be declared with IRAM_ATTR attribute
// and can only call functions in IRAM or ROM. It cannot call other timer APIs.
timer_isr_callback_add(_timerGroup, _timerIndex, _callback, (void *) (uint32_t) _timerNo, 0);
timer_start(_timerGroup, _timerIndex);
-
+
return true;
}
else
{
-#if USING_ESP32_C3_NEW_ISR_SERVO
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
ISR_SERVO_LOGERROR(F("Error. Timer must be 0-1"));
-#else
+#else
ISR_SERVO_LOGERROR(F("Error. Timer must be 0-3"));
-#endif
-
+#endif
+
return false;
}
}
+ ////////////////////////////////////////
+
// interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
// No params and duration now. To be addes in the future by adding similar functions here or to esp32-hal-timer.c
bool attachInterruptInterval(const unsigned long& interval, esp32_timer_callback callback)
@@ -350,27 +397,34 @@ class ESP32FastTimerInterrupt
return setFrequency( (float) ( 1000000.0f / interval), callback);
}
+ ////////////////////////////////////////
+
void detachInterrupt()
{
-#if USING_ESP32_C3_NEW_ISR_SERVO
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
timer_group_intr_disable(_timerGroup, TIMER_INTR_T0);
-#else
+#else
timer_group_intr_disable(_timerGroup, (_timerIndex == 0) ? TIMER_INTR_T0 : TIMER_INTR_T1);
#endif
}
+ ////////////////////////////////////////
+
// Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
void reattachInterrupt()
{
if ( (_frequency != 0) && (_timerCount != 0) && (_callback != NULL) )
{
-#if USING_ESP32_C3_NEW_ISR_SERVO
- timer_group_intr_enable(_timerGroup, TIMER_INTR_T0);
-#else
- timer_group_intr_enable(_timerGroup, (_timerIndex == 0) ? TIMER_INTR_T0 : TIMER_INTR_T1);
-#endif
+#if (USING_ESP32_C3_NEW_ISR_SERVO || USING_ESP32_C3_TIMERINTERRUPT)
+ timer_group_intr_enable(_timerGroup, TIMER_INTR_T0);
+#else
+ timer_group_intr_enable(_timerGroup, (_timerIndex == 0) ? TIMER_INTR_T0 : TIMER_INTR_T1);
+#endif
}
}
+
+ ////////////////////////////////////////
+
}; // class ESP32FastTimerInterrupt
diff --git a/src/ESP32_New_ISR_Servo.h b/src/ESP32_New_ISR_Servo.h
index 9317ea9..67b262f 100644
--- a/src/ESP32_New_ISR_Servo.h
+++ b/src/ESP32_New_ISR_Servo.h
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -27,7 +27,7 @@
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
- Version: 1.3.0
+ Version: 1.4.0
Version Modified By Date Comments
------- ----------- ---------- -----------
@@ -36,6 +36,7 @@
1.2.0 K Hoang 08/05/2022 Fix issue with core v2.0.1+
1.2.1 K Hoang 16/06/2022 Add support to new Adafruit boards
1.3.0 K Hoang 03/08/2022 Suppress errors and warnings for new ESP32 core
+ 1.4.0 K Hoang 16/11/2022 Fix doubled time for ESP32_C3, ESP32_S2 and ESP32_S3
*****************************************************************************************************************************/
#pragma once
@@ -43,7 +44,11 @@
#ifndef ESP32_New_ISR_Servo_H
#define ESP32_New_ISR_Servo_H
+////////////////////////////////////////
+
#include "ESP32_New_ISR_Servo.hpp"
#include "ESP32_New_ISR_Servo_Impl.h"
+////////////////////////////////////////
+
#endif
diff --git a/src/ESP32_New_ISR_Servo.hpp b/src/ESP32_New_ISR_Servo.hpp
index 18111d5..df3bcb8 100644
--- a/src/ESP32_New_ISR_Servo.hpp
+++ b/src/ESP32_New_ISR_Servo.hpp
@@ -27,7 +27,7 @@
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
- Version: 1.3.0
+ Version: 1.4.0
Version Modified By Date Comments
------- ----------- ---------- -----------
@@ -36,6 +36,7 @@
1.2.0 K Hoang 08/05/2022 Fix issue with core v2.0.1+
1.2.1 K Hoang 16/06/2022 Add support to new Adafruit boards
1.3.0 K Hoang 03/08/2022 Suppress errors and warnings for new ESP32 core
+ 1.4.0 K Hoang 16/11/2022 Fix doubled time for ESP32_C3, ESP32_S2 and ESP32_S3
*****************************************************************************************************************************/
#pragma once
@@ -43,36 +44,54 @@
#ifndef ESP32_New_ISR_Servo_HPP
#define ESP32_New_ISR_Servo_HPP
+////////////////////////////////////////
+
#if ( ARDUINO_ESP32S2_DEV || ARDUINO_FEATHERS2 || ARDUINO_ESP32S2_THING_PLUS || ARDUINO_MICROS2 || \
ARDUINO_METRO_ESP32S2 || ARDUINO_MAGTAG29_ESP32S2 || ARDUINO_FUNHOUSE_ESP32S2 || \
ARDUINO_ADAFRUIT_FEATHER_ESP32S2_NOPSRAM || ARDUINO_ADAFRUIT_QTPY_ESP32S2)
#warning Using ESP32_S2-based board
#define USING_ESP32_S2_ISR_SERVO true
+
+////////////////////////////////////////
+
#elif ( defined(ARDUINO_ESP32S3_DEV) || defined(ARDUINO_ESP32_S3_BOX) || defined(ARDUINO_TINYS3) || \
defined(ARDUINO_PROS3) || defined(ARDUINO_FEATHERS3) || defined(ARDUINO_ADAFRUIT_FEATHER_ESP32S3_NOPSRAM) || \
defined(ARDUINO_ADAFRUIT_QTPY_ESP32S3_NOPSRAM))
#warning Using ESP32_S3-based board
#define USING_ESP32_S3_ISR_SERVO true
+
+////////////////////////////////////////
+
#elif ( ARDUINO_ESP32C3_DEV )
#warning Using ESP32_C3-based board
#define USING_ESP32_C3_ISR_SERVO true
+
+////////////////////////////////////////
+
#elif defined(ESP32)
#warning Using ESP32-based board
#define USING_ESP32_ISR_SERVO true
+
+////////////////////////////////////////
+
#else
#error This code is intended to run on the ESP32 platform! Please check your Tools->Board setting.
#endif
+////////////////////////////////////////
+
#ifndef ESP32_NEW_ISR_SERVO_VERSION
- #define ESP32_NEW_ISR_SERVO_VERSION "ESP32_New_ISR_Servo v1.3.0"
+ #define ESP32_NEW_ISR_SERVO_VERSION "ESP32_New_ISR_Servo v1.4.0"
#define ESP32_NEW_ISR_SERVO_VERSION_MAJOR 1
- #define ESP32_NEW_ISR_SERVO_VERSION_MINOR 3
+ #define ESP32_NEW_ISR_SERVO_VERSION_MINOR 4
#define ESP32_NEW_ISR_SERVO_VERSION_PATCH 0
- #define ESP32_NEW_ISR_SERVO_VERSION_INT 1003000
+ #define ESP32_NEW_ISR_SERVO_VERSION_INT 1004000
#endif
+////////////////////////////////////////
+
#include
#include
@@ -88,6 +107,8 @@
#include "ESP32_New_ISR_Servo_Debug.h"
#include "ESP32_New_FastTimerInterrupt.h"
+////////////////////////////////////////
+
#if defined(NUM_DIGITAL_PINS)
#if (ISR_SERVO_DEBUG > 1)
#warning Using default NUM_DIGITAL_PINS
@@ -107,6 +128,8 @@
#define ESP32_WRONG_PIN 255
+////////////////////////////////////////
+
// From Servo.h - Copyright (c) 2009 Michael Margolis. All right reserved.
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
@@ -114,11 +137,14 @@
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
+////////////////////////////////////////
+
extern bool IRAM_ATTR ESP32_ISR_Servo_Handler(void * timerNo);
+////////////////////////////////////////
+
class ESP32_ISR_Servo
{
-
public:
// maximum number of servos
const static uint8_t MAX_SERVOS = 16;
@@ -126,6 +152,8 @@ class ESP32_ISR_Servo
// constructor
ESP32_ISR_Servo();
+ ////////////////////////////////////////
+
// destructor
~ESP32_ISR_Servo()
{
@@ -136,8 +164,12 @@ class ESP32_ISR_Servo
}
}
+ ////////////////////////////////////////
+
void IRAM_ATTR run();
+ ////////////////////////////////////////
+
// useTimer select which timer (0-3) of ESP32 to use for Servos
//Return true if timerN0 in range
bool useTimer(const uint8_t& timerNo)
@@ -151,6 +183,8 @@ class ESP32_ISR_Servo
return false;
}
+ ////////////////////////////////////////
+
// Bind servo to the timer and pin, return servoIndex
int8_t setupServo(const uint8_t& pin, const uint16_t& min = MIN_PULSE_WIDTH, const uint16_t& max = MAX_PULSE_WIDTH);
@@ -196,6 +230,8 @@ class ESP32_ISR_Servo
// returns the number of used servos
int8_t getNumServos();
+ ////////////////////////////////////////
+
// returns the number of available servos
int8_t getNumAvailableServos()
{
@@ -205,12 +241,16 @@ class ESP32_ISR_Servo
return MAX_SERVOS - numServos;
}
+ ////////////////////////////////////////
+
private:
// Use 10 microsecs timer => not working from core v2.0.1+
// Use 12 microsecs timer now, just fine enough to control Servo, normally requiring pulse width (PWM) 500-2000us in 20ms.
#define TIMER_INTERVAL_MICRO 12
+ ////////////////////////////////////////
+
void init()
{
ESP32_ITimer = new ESP32FastTimer(_timerNo);
@@ -241,9 +281,13 @@ class ESP32_ISR_Servo
timerMux = portMUX_INITIALIZER_UNLOCKED;
}
+ ////////////////////////////////////////
+
// find the first available slot
int8_t findFirstFreeSlot();
+ ////////////////////////////////////////
+
typedef struct
{
uint8_t pin; // pin servo connected to
@@ -254,6 +298,8 @@ class ESP32_ISR_Servo
uint16_t max;
} servo_t;
+ ////////////////////////////////////////
+
volatile servo_t servo[MAX_SERVOS];
// actual number of servos in use (-1 means uninitialized)
@@ -272,5 +318,6 @@ class ESP32_ISR_Servo
ESP32FastTimer* ESP32_ITimer;
};
+////////////////////////////////////////
#endif // ESP32_New_ISR_Servo_HPP
diff --git a/src/ESP32_New_ISR_Servo_Debug.h b/src/ESP32_New_ISR_Servo_Debug.h
index 6cb4a27..ae8962c 100644
--- a/src/ESP32_New_ISR_Servo_Debug.h
+++ b/src/ESP32_New_ISR_Servo_Debug.h
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -27,7 +27,7 @@
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
- Version: 1.3.0
+ Version: 1.4.0
Version Modified By Date Comments
------- ----------- ---------- -----------
@@ -36,6 +36,7 @@
1.2.0 K Hoang 08/05/2022 Fix issue with core v2.0.1+
1.2.1 K Hoang 16/06/2022 Add support to new Adafruit boards
1.3.0 K Hoang 03/08/2022 Suppress errors and warnings for new ESP32 core
+ 1.4.0 K Hoang 16/11/2022 Fix doubled time for ESP32_C3, ESP32_S2 and ESP32_S3
*****************************************************************************************************************************/
#pragma once
@@ -43,7 +44,7 @@
#ifndef ESP32_New_ISR_Servo_Debug_h
#define ESP32_New_ISR_Servo_Debug_h
-//////////////////////////////////////////
+////////////////////////////////////////
#ifndef TIMER_INTERRUPT_DEBUG
#define TIMER_INTERRUPT_DEBUG 1
@@ -59,7 +60,7 @@
#define ISR_SERVO_DEBUG_OUTPUT Serial
#endif
-//////////////////////////////////////////////////////
+////////////////////////////////////////
const char ISR_SERVO_MARK[] = "[ISR_SERVO] ";
const char ISR_SERVO_SP[] = " ";
@@ -71,7 +72,7 @@ const char ISR_SERVO_SP[] = " ";
#define ISR_SERVO_PRINT_MARK ISR_SERVO_PRINT(ISR_SERVO_MARK)
#define ISR_SERVO_PRINT_SP ISR_SERVO_PRINT(ISR_SERVO_SP)
-//////////////////////////////////////////////////////
+////////////////////////////////////////
#define ISR_SERVO_LOGERROR(x) if(ISR_SERVO_DEBUG>0) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINTLN(x); }
#define ISR_SERVO_LOGERROR0(x) if(ISR_SERVO_DEBUG>0) { ISR_SERVO_PRINT(x); }
@@ -79,8 +80,7 @@ const char ISR_SERVO_SP[] = " ";
#define ISR_SERVO_LOGERROR2(x,y,z) if(ISR_SERVO_DEBUG>0) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(z); }
#define ISR_SERVO_LOGERROR3(x,y,z,w) if(ISR_SERVO_DEBUG>0) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(z); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(w); }
-
-///////////////////////////////////////
+////////////////////////////////////////
#define ISR_SERVO_LOGWARN(x) if(ISR_SERVO_DEBUG>1) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINTLN(x); }
#define ISR_SERVO_LOGWARN0(x) if(ISR_SERVO_DEBUG>1) { ISR_SERVO_PRINT(x); }
@@ -89,7 +89,7 @@ const char ISR_SERVO_SP[] = " ";
#define ISR_SERVO_LOGWARN2(x,y,z) if(ISR_SERVO_DEBUG>1) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(z); }
#define ISR_SERVO_LOGWARN3(x,y,z,w) if(ISR_SERVO_DEBUG>1) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(z); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(w); }
-///////////////////////////////////////
+////////////////////////////////////////
#define ISR_SERVO_LOGINFO(x) if(ISR_SERVO_DEBUG>2) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINTLN(x); }
#define ISR_SERVO_LOGINFO0(x) if(ISR_SERVO_DEBUG>2) { ISR_SERVO_PRINT(x); }
@@ -98,7 +98,7 @@ const char ISR_SERVO_SP[] = " ";
#define ISR_SERVO_LOGINFO2(x,y,z) if(ISR_SERVO_DEBUG>2) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(z); }
#define ISR_SERVO_LOGINFO3(x,y,z,w) if(ISR_SERVO_DEBUG>2) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINT(x); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(y); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINT(z); ISR_SERVO_PRINT_SP; ISR_SERVO_PRINTLN(w); }
-//////////////////////////////////////////////////////
+////////////////////////////////////////
#define ISR_SERVO_LOGDEBUG(x) if(ISR_SERVO_DEBUG>3) { ISR_SERVO_PRINT_MARK; ISR_SERVO_PRINTLN(x); }
#define ISR_SERVO_LOGDEBUG0(x) if(ISR_SERVO_DEBUG>3) { ISR_SERVO_PRINT(x); }
@@ -108,5 +108,4 @@ const char ISR_SERVO_SP[] = " ";
//////////////////////////////////////////
-
#endif // ESP32_New_ISR_Servo_Debug_h
diff --git a/src/ESP32_New_ISR_Servo_Impl.h b/src/ESP32_New_ISR_Servo_Impl.h
index 4c986e1..05c2015 100644
--- a/src/ESP32_New_ISR_Servo_Impl.h
+++ b/src/ESP32_New_ISR_Servo_Impl.h
@@ -9,10 +9,10 @@
The ESP32, ESP32_S2, ESP32_S3, ESP32_C3 have two timer groups, TIMER_GROUP_0 and TIMER_GROUP_1
1) each group of ESP32, ESP32_S2, ESP32_S3 has two general purpose hardware timers, TIMER_0 and TIMER_1
2) each group of ESP32_C3 has ony one general purpose hardware timer, TIMER_0
-
- All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
- The timer counters can be configured to count up or down and support automatic reload and software reload.
- They can also generate alarms when they reach a specific value, defined by the software.
+
+ All the timers are based on 64-bit counters (except 54-bit counter for ESP32_S3 counter) and 16 bit prescalers.
+ The timer counters can be configured to count up or down and support automatic reload and software reload.
+ They can also generate alarms when they reach a specific value, defined by the software.
The value of the counter can be read by the software program.
Now these new 16 ISR-based PWM servo contro uses only 1 hardware timer.
@@ -27,7 +27,7 @@
Based on BlynkTimer.h
Author: Volodymyr Shymanskyy
- Version: 1.3.0
+ Version: 1.4.0
Version Modified By Date Comments
------- ----------- ---------- -----------
@@ -36,6 +36,7 @@
1.2.0 K Hoang 08/05/2022 Fix issue with core v2.0.1+
1.2.1 K Hoang 16/06/2022 Add support to new Adafruit boards
1.3.0 K Hoang 03/08/2022 Suppress errors and warnings for new ESP32 core
+ 1.4.0 K Hoang 16/11/2022 Fix doubled time for ESP32_C3, ESP32_S2 and ESP32_S3
*****************************************************************************************************************************/
#pragma once
@@ -65,9 +66,9 @@ static ESP32_ISR_Servo ESP32_ISR_Servos; // create servo object to control up t
bool IRAM_ATTR ESP32_ISR_Servo_Handler(void * timerNo)
-{
+{
ESP32_ISR_Servos.run();
-
+
return true;
}
@@ -180,7 +181,8 @@ bool ESP32_ISR_Servo::setPosition(const uint8_t& servoIndex, const float& positi
portENTER_CRITICAL(&timerMux);
servo[servoIndex].position = position;
- servo[servoIndex].count = map(position, 0, 180, servo[servoIndex].min, servo[servoIndex].max) / TIMER_INTERVAL_MICRO;
+ servo[servoIndex].count = map(position, 0, 180, servo[servoIndex].min,
+ servo[servoIndex].max) / TIMER_INTERVAL_MICRO;
// ESP32 is a multi core / multi processing chip.
// It is mandatory to disable task switches during modifying shared vars
@@ -375,8 +377,8 @@ void ESP32_ISR_Servo::enableAll()
{
// Bug fix. See "Fixed count >= min comparison for servo enable."
// (https://github.com/khoih-prog/ESP32_ISR_Servo/pull/1)
- if ( (servo[servoIndex].count >= servo[servoIndex].min / TIMER_INTERVAL_MICRO ) && !servo[servoIndex].enabled
- && (servo[servoIndex].pin <= ESP32_MAX_PIN) )
+ if ( (servo[servoIndex].count >= servo[servoIndex].min / TIMER_INTERVAL_MICRO ) && !servo[servoIndex].enabled
+ && (servo[servoIndex].pin <= ESP32_MAX_PIN) )
{
servo[servoIndex].enabled = true;
}
diff --git a/utils/astyle_library.conf b/utils/astyle_library.conf
new file mode 100644
index 0000000..8a73bc2
--- /dev/null
+++ b/utils/astyle_library.conf
@@ -0,0 +1,70 @@
+# Code formatting rules for Arduino libraries, modified from for KH libraries:
+#
+# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf
+#
+
+# astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino
+
+--mode=c
+--lineend=linux
+--style=allman
+
+# -r or -R
+#--recursive
+
+# -c => Converts tabs into spaces
+convert-tabs
+
+# -s2 => 2 spaces indentation
+--indent=spaces=2
+
+# -t2 => tab =2 spaces
+#--indent=tab=2
+
+# -C
+--indent-classes
+
+# -S
+--indent-switches
+
+# -xW
+--indent-preproc-block
+
+# -Y => indent classes, switches (and cases), comments starting at column 1
+--indent-col1-comments
+
+# -M120 => maximum of 120 spaces to indent a continuation line
+--max-continuation-indent=120
+
+# -xC120 => max‑code‑length will break a line if the code exceeds # characters
+--max-code-length=120
+
+# -f =>
+--break-blocks
+
+# -p => put a space around operators
+--pad-oper
+
+# -xg => Insert space padding after commas
+--pad-comma
+
+# -H => put a space after if/for/while
+pad-header
+
+# -xb => Break one line headers (e.g. if/for/while)
+--break-one-line-headers
+
+# -c => Converts tabs into spaces
+#--convert-tabs
+
+# if you like one-liners, keep them
+#keep-one-line-statements
+
+# -xV
+--attach-closing-while
+
+#unpad-paren
+
+# -xp
+remove-comment-prefix
+
diff --git a/utils/restyle.sh b/utils/restyle.sh
new file mode 100644
index 0000000..bcd846f
--- /dev/null
+++ b/utils/restyle.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+for dir in . ; do
+ find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \;
+done
+