diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9b7a33d..607c039 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,27 +31,51 @@ 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. ... 3. ... 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_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_ISR_Servo_GitHub/ +xy@xy-Inspiron-3593:~/Arduino/xy/ESP32_ISR_Servo_GitHub$ +``` + +2. Issue astyle command + +``` +xy@xy-Inspiron-3593:~/Arduino/xy/ESP32_ISR_Servo_GitHub$ bash utils/restyle.sh +``` + + diff --git a/README.md b/README.md index 1a475d0..07c0528 100644 --- a/README.md +++ b/README.md @@ -6,8 +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_ISR_Servo.svg)](http://github.com/khoih-prog/ESP32_ISR_Servo/issues) + Donate to my libraries using BuyMeACoffee + + --- --- @@ -92,6 +95,7 @@ Functions using normal software timers, relying on loop() and calling millis(), This library enables you to use `1 Hardware Timer` on an ESP32, ESP32_S2, ESP32_C3-based board to control up to `16 independent servo motors`. +--- #### Important Notes about using ISR @@ -105,6 +109,7 @@ This library enables you to use `1 Hardware Timer` on an ESP32, ESP32_S2, ESP32_ [HOWTO Attach Interrupt](https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/) +--- #### Currently supported Boards @@ -121,7 +126,7 @@ This [**ESP32_ISR_Servo** library](https://github.com/khoih-prog/ESP32_ISR_Servo ## 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/) --- --- @@ -159,14 +164,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_ISR_Servo.hpp" //https://github.com/khoih-prog/ESP32_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_ISR_Servo.h" //https://github.com/khoih-prog/ESP32_ISR_Servo ``` @@ -188,22 +193,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. @@ -211,10 +216,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). --- --- @@ -232,7 +237,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 int getPosition(unsigned servoIndex); @@ -262,7 +267,7 @@ You'll see blynkTimer Software is blocked while system is connecting to WiFi / I How to use: -``` +```cpp #ifndef ESP32 #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif @@ -403,7 +408,7 @@ https://github.com/khoih-prog/ESP32_ISR_Servo/blob/f85c83625eaefcc27d89511e2d8ba ``` Starting ESP32_MultipleRandomServos on ESP32_DEV -ESP32_ISR_Servo v1.4.0 +ESP32_ISR_Servo v1.5.0 Setup OK Servo index = 0 Setup OK Servo index = 1 Setup OK Servo index = 2 @@ -465,7 +470,7 @@ Servos idx = 5, act. pos. (deg) = 180, pulseWidth (us) = 2450 ``` Starting ESP32_ISR_MultiServos on ESP32_DEV -ESP32_ISR_Servo v1.4.0 +ESP32_ISR_Servo v1.5.0 Setup Servo1 OK Setup Servo2 OK Servo1 pos = 0, Servo2 pos = 180 @@ -510,7 +515,7 @@ Servo1 pos = 150, Servo2 pos = 30 ``` Starting MultipleRandomServos on ESP32S3_DEV -ESP32_ISR_Servo v1.4.0 +ESP32_ISR_Servo v1.5.0 [ISR_SERVO] ESP32_S3_TimerInterrupt: _timerNo = 3 , _fre = 1000000 [ISR_SERVO] TIMER_BASE_CLK = 80000000 , TIMER_DIVIDER = 80 [ISR_SERVO] _timerIndex = 1 , _timerGroup = 1 @@ -604,7 +609,7 @@ Servos idx = 3, act. pos. (deg) = [ISR_SERVO] Idx = 3 ``` Starting ESP32_ISR_MultiServos on ESP32S2_DEV -ESP32_ISR_Servo v1.4.0 +ESP32_ISR_Servo v1.5.0 [ISR_SERVO] ESP32_S2_TimerInterrupt: _timerNo = 3 , _fre = 1000000 [ISR_SERVO] TIMER_BASE_CLK = 80000000 , TIMER_DIVIDER = 80 [ISR_SERVO] _timerIndex = 1 , _timerGroup = 1 @@ -691,7 +696,7 @@ Submit issues to: [ESP32_ISR_Servo issues](https://github.com/khoih-prog/ESP32_I 11. Add example [multiFileProject](examples/multiFileProject) to demo for multiple-file project 12. Fix breaking issue caused by **ESP32 core v2.0.1+** by increasing `TIMER_INTERVAL_MICRO` to `12uS` from `10uS` 13. Suppress errors and warnings for new ESP32 core v2.0.4 - +14. Use `allman astyle` and add `utils` --- --- @@ -729,5 +734,5 @@ If you want to contribute to this project: ## Copyright -Copyright 2019- Khoi Hoang +Copyright (C) 2019- Khoi Hoang diff --git a/changelog.md b/changelog.md index 3541928..38c16f3 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_ISR_Servo.svg)](http://github.com/khoih-prog/ESP32_ISR_Servo/issues) + +Donate to my libraries using BuyMeACoffee + + + + --- --- ## Table of Contents * [Changelog](#changelog) + * [Releases v1.5.0](#releases-v150) * [Releases v1.4.0](#releases-v140) * [Releases v1.3.0](#releases-v130) * [Releases v1.2.1](#releases-v121) @@ -25,6 +32,12 @@ ## Changelog +### Releases v1.5.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_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.4.0 1. Suppress errors and warnings for new ESP32 core v2.0.4+ diff --git a/examples/ESP32_ISR_MultiServos/ESP32_ISR_MultiServos.ino b/examples/ESP32_ISR_MultiServos/ESP32_ISR_MultiServos.ino index 3dd48e4..9d3ba0e 100644 --- a/examples/ESP32_ISR_MultiServos/ESP32_ISR_MultiServos.ino +++ b/examples/ESP32_ISR_MultiServos/ESP32_ISR_MultiServos.ino @@ -70,7 +70,7 @@ *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -82,9 +82,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -141,71 +144,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 ESP32_ISR_MultiServos on ")); + Serial.println(ARDUINO_BOARD); + Serial.println(ESP32_ISR_SERVO_VERSION); - Serial.print(F("\nStarting ESP32_ISR_MultiServos on ")); Serial.println(ARDUINO_BOARD); - Serial.println(ESP32_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_D4, 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_MultipleRandomServos/ESP32_MultipleRandomServos.ino b/examples/ESP32_MultipleRandomServos/ESP32_MultipleRandomServos.ino index 137bc81..93e1611 100644 --- a/examples/ESP32_MultipleRandomServos/ESP32_MultipleRandomServos.ino +++ b/examples/ESP32_MultipleRandomServos/ESP32_MultipleRandomServos.ino @@ -68,7 +68,7 @@ Experimentally, 550 and 2350 are pretty close to 0 and 180. *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -80,9 +80,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -138,161 +141,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_D1 }, { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 } + { -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_MultipleRandomServos on ")); Serial.println(ARDUINO_BOARD); - Serial.println(ESP32_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_MultipleRandomServos on ")); + Serial.println(ARDUINO_BOARD); + Serial.println(ESP32_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_MultipleServos/ESP32_MultipleServos.ino b/examples/ESP32_MultipleServos/ESP32_MultipleServos.ino index 2ce35ed..6d432b0 100644 --- a/examples/ESP32_MultipleServos/ESP32_MultipleServos.ino +++ b/examples/ESP32_MultipleServos/ESP32_MultipleServos.ino @@ -69,7 +69,7 @@ Experimentally, 550 and 2350 are pretty close to 0 and 180. *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -81,9 +81,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -139,72 +142,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_D1 }, { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 } + { -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_MultipleServos on ")); Serial.println(ARDUINO_BOARD); - Serial.println(ESP32_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_MultipleServos on ")); + Serial.println(ARDUINO_BOARD); + Serial.println(ESP32_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 a04d6fb..f85adff 100644 --- a/examples/ISR_MultiServos/ISR_MultiServos.ino +++ b/examples/ISR_MultiServos/ISR_MultiServos.ino @@ -70,7 +70,7 @@ *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -82,9 +82,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -141,71 +144,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_ISR_SERVO_VERSION); - Serial.print(F("\nStarting ISR_MultiServos on ")); Serial.println(ARDUINO_BOARD); - Serial.println(ESP32_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_D5, MIN_MICROS, MAX_MICROS); - servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D6, MIN_MICROS, MAX_MICROS); + servoIndex1 = ESP32_ISR_Servos.setupServo(PIN_D5, MIN_MICROS, MAX_MICROS); + servoIndex2 = ESP32_ISR_Servos.setupServo(PIN_D6, 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 ad01b16..884cad2 100644 --- a/examples/MultipleRandomServos/MultipleRandomServos.ino +++ b/examples/MultipleRandomServos/MultipleRandomServos.ino @@ -69,7 +69,7 @@ Experimentally, 550 and 2350 are pretty close to 0 and 180. *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -81,9 +81,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -139,161 +142,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_D1 }, { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 } + { -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_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_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 62de139..52806cf 100644 --- a/examples/MultipleServos/MultipleServos.ino +++ b/examples/MultipleServos/MultipleServos.ino @@ -69,7 +69,7 @@ Experimentally, 550 and 2350 are pretty close to 0 and 180. *****************************************************************************************************************************/ #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP8266! Please check your Tools->Board setting. #endif #define TIMER_INTERRUPT_DEBUG 1 @@ -81,9 +81,12 @@ // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_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 @@ -139,72 +142,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_D1 }, { -1, PIN_D2 }, { -1, PIN_D3 }, { -1, PIN_D4 }, { -1, PIN_D5 }, { -1, PIN_D6 } + { -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_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_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 e859643..6b74e6b 100644 --- a/examples/multiFileProject/multiFileProject.cpp +++ b/examples/multiFileProject/multiFileProject.cpp @@ -2,7 +2,7 @@ multiFileProject.cpp For ESP32 boards Written by Khoi Hoang - + Built by Khoi Hoang https://github.com/khoih-prog/ESP32_ISR_Servo Licensed under MIT license *****************************************************************************************************************************/ diff --git a/examples/multiFileProject/multiFileProject.h b/examples/multiFileProject/multiFileProject.h index 79072dd..6da53ff 100644 --- a/examples/multiFileProject/multiFileProject.h +++ b/examples/multiFileProject/multiFileProject.h @@ -2,7 +2,7 @@ multiFileProject.h For ESP32 boards Written by Khoi Hoang - + Built by Khoi Hoang https://github.com/khoih-prog/ESP32_ISR_Servo Licensed under MIT license *****************************************************************************************************************************/ diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino index 953ce1d..930493a 100644 --- a/examples/multiFileProject/multiFileProject.ino +++ b/examples/multiFileProject/multiFileProject.ino @@ -2,7 +2,7 @@ multiFileProject.ino For ESP32 boards Written by Khoi Hoang - + Built by Khoi Hoang https://github.com/khoih-prog/ESP32_ISR_Servo Licensed under MIT license *****************************************************************************************************************************/ @@ -10,35 +10,39 @@ // To demo how to include files in multi-file Projects #ifndef ESP32 - #error This code is designed to run on ESP32 platform, not Arduino nor ESP32! Please check your Tools->Board setting. + #error This code is designed to run on ESP32 platform, not Arduino nor ESP32! Please check your Tools->Board setting. #endif -#define ESP32_ISR_SERVO_VERSION_MIN_TARGET "ESP32_ISR_Servo v1.4.0" -#define ESP32_ISR_SERVO_VERSION_MIN 1004000 +#define ESP32_ISR_SERVO_VERSION_MIN_TARGET "ESP32_ISR_Servo v1.5.0" +#define ESP32_ISR_SERVO_VERSION_MIN 1005000 #include "multiFileProject.h" // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "ESP32_ISR_Servo.h" -void setup() +void setup() { - Serial.begin(115200); - while (!Serial); - - Serial.println("\nStart multiFileProject"); - Serial.println(ESP32_ISR_SERVO_VERSION); + Serial.begin(115200); + + while (!Serial && millis() < 5000); + + delay(500); + Serial.println("\nStart multiFileProject"); + Serial.println(ESP32_ISR_SERVO_VERSION); #if defined(ESP32_ISR_SERVO_VERSION_MIN) - if (ESP32_ISR_SERVO_VERSION_INT < ESP32_ISR_SERVO_VERSION_MIN) - { - Serial.print("Warning. Must use this example on Version equal or later than : "); - Serial.println(ESP32_ISR_SERVO_VERSION_MIN_TARGET); - } + + if (ESP32_ISR_SERVO_VERSION_INT < ESP32_ISR_SERVO_VERSION_MIN) + { + Serial.print("Warning. Must use this example on Version equal or later than : "); + Serial.println(ESP32_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 8e7029b..4d97bcf 100644 --- a/library.json +++ b/library.json @@ -1,8 +1,8 @@ { "name": "ESP32_ISR_Servo", - "version": "1.4.0", + "version": "1.5.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-based board to control up to 16 or more servo motors. Now supporting ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards. Tested OK with ESP32 core v2.0.4", + "description": "This library enables you to use 1 Hardware Timer on an ESP32-based board to control up to 16 or more servo motors. Now supporting ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards. Tested OK with ESP32 core v2.0.5", "authors": { "name": "Khoi Hoang", diff --git a/library.properties b/library.properties index f8fac0b..c10c188 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=ESP32_ISR_Servo -version=1.4.0 +version=1.5.0 author=Khoi Hoang maintainer=Khoi Hoang license=MIT sentence=This library enables you to use Interrupt from Hardware Timers on an ESP32 board to control multiple servo motors. -paragraph=This library enables you to use 1 Hardware Timer on an ESP32-based board to control 16 or more servo motors. Now supporting ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards. Tested OK with ESP32 core v2.0.4 +paragraph=This library enables you to use 1 Hardware Timer on an ESP32-based board to control 16 or more servo motors. Now supporting ESP32, ESP32_S2, ESP32_S3, ESP32_C3-based boards. Tested OK with ESP32 core v2.0.5 category=Device Control url=https://github.com/khoih-prog/ESP32_ISR_Servo architectures=esp32 diff --git a/src/ESP32_ISR_Servo_Debug.h b/src/ESP32_ISR_Servo_Debug.h index fb42fcb..ef8ab20 100644 --- a/src/ESP32_ISR_Servo_Debug.h +++ b/src/ESP32_ISR_Servo_Debug.h @@ -34,13 +34,13 @@ ////////////////////////////////////////// #ifndef ISR_SERVO_DEBUG - #define ISR_SERVO_DEBUG 1 + #define ISR_SERVO_DEBUG 1 #endif ////////////////////////////////////////// #if !defined(ISR_SERVO_DEBUG_OUTPUT) - #define ISR_SERVO_DEBUG_OUTPUT Serial + #define ISR_SERVO_DEBUG_OUTPUT Serial #endif ////////////////////////////////////////////////////// diff --git a/src/ESP32_ISR_Servo_Impl.h b/src/ESP32_ISR_Servo_Impl.h index f91145e..747882d 100644 --- a/src/ESP32_ISR_Servo_Impl.h +++ b/src/ESP32_ISR_Servo_Impl.h @@ -30,7 +30,7 @@ #include #ifndef ISR_SERVO_DEBUG - #define ISR_SERVO_DEBUG 1 + #define ISR_SERVO_DEBUG 1 #endif #define DEFAULT_ESP32_TIMER_NO 3 @@ -39,151 +39,151 @@ static ESP32_ISR_Servo ESP32_ISR_Servos; // create servo object to control up t void IRAM_ATTR ESP32_ISR_Servo_Handler() { - ESP32_ISR_Servos.run(); + ESP32_ISR_Servos.run(); } ESP32_ISR_Servo::ESP32_ISR_Servo() - : numServos (-1), _timerNo(DEFAULT_ESP32_TIMER_NO) + : numServos (-1), _timerNo(DEFAULT_ESP32_TIMER_NO) { } void IRAM_ATTR ESP32_ISR_Servo::run() { - static int servoIndex; - - // ESP32 is a multi core / multi processing chip. It is mandatory to disable task switches during ISR - portENTER_CRITICAL_ISR(&timerMux); - - for (servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) - { - if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) - { - if ( timerCount == servo[servoIndex].count ) - { - // PWM to LOW, will be HIGH again when timerCount = 1 - digitalWrite(servo[servoIndex].pin, LOW); - } - else if (timerCount == 1) - { - // PWM to HIGH, will be LOW again when timerCount = servo[servoIndex].count - digitalWrite(servo[servoIndex].pin, HIGH); - } - } - } - - // Reset when reaching 20000us / 10us = 2000 - if (timerCount++ >= REFRESH_INTERVAL / TIMER_INTERVAL_MICRO) - { - ISR_SERVO_LOGDEBUG("Reset count"); - - timerCount = 1; - } - - // ESP32 is a multi core / multi processing chip. It is mandatory to disable task switches during ISR - portEXIT_CRITICAL_ISR(&timerMux); + static int servoIndex; + + // ESP32 is a multi core / multi processing chip. It is mandatory to disable task switches during ISR + portENTER_CRITICAL_ISR(&timerMux); + + for (servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) + { + if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) + { + if ( timerCount == servo[servoIndex].count ) + { + // PWM to LOW, will be HIGH again when timerCount = 1 + digitalWrite(servo[servoIndex].pin, LOW); + } + else if (timerCount == 1) + { + // PWM to HIGH, will be LOW again when timerCount = servo[servoIndex].count + digitalWrite(servo[servoIndex].pin, HIGH); + } + } + } + + // Reset when reaching 20000us / 10us = 2000 + if (timerCount++ >= REFRESH_INTERVAL / TIMER_INTERVAL_MICRO) + { + ISR_SERVO_LOGDEBUG("Reset count"); + + timerCount = 1; + } + + // ESP32 is a multi core / multi processing chip. It is mandatory to disable task switches during ISR + portEXIT_CRITICAL_ISR(&timerMux); } // find the first available slot // return -1 if none found int8_t ESP32_ISR_Servo::findFirstFreeSlot() { - // all slots are used - if (numServos >= MAX_SERVOS) - return -1; - - // return the first slot with no count (i.e. free) - for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) - { - if (servo[servoIndex].enabled == false) - { - ISR_SERVO_LOGDEBUG1("Index =", servoIndex); - - return servoIndex; - } - } - - // no free slots found - return -1; + // all slots are used + if (numServos >= MAX_SERVOS) + return -1; + + // return the first slot with no count (i.e. free) + for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) + { + if (servo[servoIndex].enabled == false) + { + ISR_SERVO_LOGDEBUG1("Index =", servoIndex); + + return servoIndex; + } + } + + // no free slots found + return -1; } int8_t ESP32_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& min, const uint16_t& max) { - int servoIndex; + int servoIndex; - if (pin > ESP32_MAX_PIN) - return -1; + if (pin > ESP32_MAX_PIN) + return -1; - if (numServos < 0) - init(); + if (numServos < 0) + init(); - servoIndex = findFirstFreeSlot(); + servoIndex = findFirstFreeSlot(); - if (servoIndex < 0) - return -1; + if (servoIndex < 0) + return -1; - servo[servoIndex].pin = pin; - servo[servoIndex].min = min; - servo[servoIndex].max = max; - servo[servoIndex].count = min / TIMER_INTERVAL_MICRO; - servo[servoIndex].position = 0; - servo[servoIndex].enabled = true; + servo[servoIndex].pin = pin; + servo[servoIndex].min = min; + servo[servoIndex].max = max; + servo[servoIndex].count = min / TIMER_INTERVAL_MICRO; + servo[servoIndex].position = 0; + servo[servoIndex].enabled = true; - pinMode(pin, OUTPUT); + pinMode(pin, OUTPUT); - numServos++; + numServos++; - ISR_SERVO_LOGDEBUG3("Index =", servoIndex, ", count =", servo[servoIndex].count); - ISR_SERVO_LOGDEBUG3("min =", servo[servoIndex].min, ", max =", servo[servoIndex].max); + ISR_SERVO_LOGDEBUG3("Index =", servoIndex, ", count =", servo[servoIndex].count); + ISR_SERVO_LOGDEBUG3("min =", servo[servoIndex].min, ", max =", servo[servoIndex].max); - return servoIndex; + return servoIndex; } bool ESP32_ISR_Servo::setPosition(const uint8_t& servoIndex, const uint16_t& position) { - if (servoIndex >= MAX_SERVOS) - return false; + if (servoIndex >= MAX_SERVOS) + return false; - // Updates interval of existing specified servo - if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) - { - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); + // Updates interval of existing specified servo + if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) + { + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + 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].position = position; + 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 - portEXIT_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); - ISR_SERVO_LOGERROR1("Idx =", servoIndex); - ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGERROR1("Idx =", servoIndex); + ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =", servo[servoIndex].position); - return true; - } + return true; + } - // false return for non-used numServo or bad pin - return false; + // false return for non-used numServo or bad pin + return false; } // returns last position in degrees if success, or -1 on wrong servoIndex int ESP32_ISR_Servo::getPosition(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return -1; + if (servoIndex >= MAX_SERVOS) + return -1; - // Updates interval of existing specified servo - if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) - { - ISR_SERVO_LOGERROR1("Idx =", servoIndex); - ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =",servo[servoIndex].position); + // Updates interval of existing specified servo + if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) + { + ISR_SERVO_LOGERROR1("Idx =", servoIndex); + ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =", servo[servoIndex].position); - return (servo[servoIndex].position); - } + return (servo[servoIndex].position); + } - // return 0 for non-used numServo or bad pin - return -1; + // return 0 for non-used numServo or bad pin + return -1; } @@ -193,207 +193,207 @@ int ESP32_ISR_Servo::getPosition(const uint8_t& servoIndex) // returns true on success or -1 on wrong servoIndex bool ESP32_ISR_Servo::setPulseWidth(const uint8_t& servoIndex, uint16_t& pulseWidth) { - if (servoIndex >= MAX_SERVOS) - return false; + if (servoIndex >= MAX_SERVOS) + return false; - // Updates interval of existing specified servo - if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) - { - if (pulseWidth < servo[servoIndex].min) - pulseWidth = servo[servoIndex].min; - else if (pulseWidth > servo[servoIndex].max) - pulseWidth = servo[servoIndex].max; + // Updates interval of existing specified servo + if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) + { + if (pulseWidth < servo[servoIndex].min) + pulseWidth = servo[servoIndex].min; + else if (pulseWidth > servo[servoIndex].max) + pulseWidth = servo[servoIndex].max; - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); - servo[servoIndex].count = pulseWidth / TIMER_INTERVAL_MICRO; - servo[servoIndex].position = map(pulseWidth, servo[servoIndex].min, servo[servoIndex].max, 0, 180); + servo[servoIndex].count = pulseWidth / TIMER_INTERVAL_MICRO; + servo[servoIndex].position = map(pulseWidth, servo[servoIndex].min, servo[servoIndex].max, 0, 180); - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); - ISR_SERVO_LOGERROR1("Idx =", servoIndex); - ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGERROR1("Idx =", servoIndex); + ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =", servo[servoIndex].position); - return true; - } + return true; + } - // false return for non-used numServo or bad pin - return false; + // false return for non-used numServo or bad pin + return false; } // returns pulseWidth in microsecs (within min/max range) if success, or 0 on wrong servoIndex unsigned int ESP32_ISR_Servo::getPulseWidth(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return 0; + if (servoIndex >= MAX_SERVOS) + return 0; - // Updates interval of existing specified servo - if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) - { - ISR_SERVO_LOGERROR1("Idx =", servoIndex); - ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =",servo[servoIndex].position); + // Updates interval of existing specified servo + if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= ESP32_MAX_PIN) ) + { + ISR_SERVO_LOGERROR1("Idx =", servoIndex); + ISR_SERVO_LOGERROR3("cnt =", servo[servoIndex].count, ", pos =", servo[servoIndex].position); - return (servo[servoIndex].count * TIMER_INTERVAL_MICRO ); - } + return (servo[servoIndex].count * TIMER_INTERVAL_MICRO ); + } - // return 0 for non-used numServo or bad pin - return 0; + // return 0 for non-used numServo or bad pin + return 0; } void ESP32_ISR_Servo::deleteServo(const uint8_t& servoIndex) { - if ( (numServos == 0) || (servoIndex >= MAX_SERVOS) ) - { - return; - } - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); - - // don't decrease the number of servos if the specified slot is already empty - if (servo[servoIndex].enabled) - { - memset((void*) &servo[servoIndex], 0, sizeof (servo_t)); - - servo[servoIndex].enabled = false; - servo[servoIndex].position = 0; - servo[servoIndex].count = 0; - // Intentional bad pin, good only from 0-16 for Digital, A0=17 - servo[servoIndex].pin = ESP32_WRONG_PIN; - - // update number of servos - numServos--; - } - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); + if ( (numServos == 0) || (servoIndex >= MAX_SERVOS) ) + { + return; + } + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); + + // don't decrease the number of servos if the specified slot is already empty + if (servo[servoIndex].enabled) + { + memset((void*) &servo[servoIndex], 0, sizeof (servo_t)); + + servo[servoIndex].enabled = false; + servo[servoIndex].position = 0; + servo[servoIndex].count = 0; + // Intentional bad pin, good only from 0-16 for Digital, A0=17 + servo[servoIndex].pin = ESP32_WRONG_PIN; + + // update number of servos + numServos--; + } + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); } bool ESP32_ISR_Servo::isEnabled(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return false; - - if (servo[servoIndex].pin > ESP32_MAX_PIN) - { - // Disable if something wrong - servo[servoIndex].pin = ESP32_WRONG_PIN; - servo[servoIndex].enabled = false; - return false; - } - - return servo[servoIndex].enabled; + if (servoIndex >= MAX_SERVOS) + return false; + + if (servo[servoIndex].pin > ESP32_MAX_PIN) + { + // Disable if something wrong + servo[servoIndex].pin = ESP32_WRONG_PIN; + servo[servoIndex].enabled = false; + return false; + } + + return servo[servoIndex].enabled; } bool ESP32_ISR_Servo::enable(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return false; - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); - - if (servo[servoIndex].pin > ESP32_MAX_PIN) - { - // Disable if something wrong - servo[servoIndex].pin = ESP32_WRONG_PIN; - servo[servoIndex].enabled = false; - return false; - } - - // 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 = true; - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); - - return true; + if (servoIndex >= MAX_SERVOS) + return false; + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); + + if (servo[servoIndex].pin > ESP32_MAX_PIN) + { + // Disable if something wrong + servo[servoIndex].pin = ESP32_WRONG_PIN; + servo[servoIndex].enabled = false; + return false; + } + + // 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 = true; + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); + + return true; } bool ESP32_ISR_Servo::disable(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return false; + if (servoIndex >= MAX_SERVOS) + return false; - if (servo[servoIndex].pin > ESP32_MAX_PIN) - servo[servoIndex].pin = ESP32_WRONG_PIN; + if (servo[servoIndex].pin > ESP32_MAX_PIN) + servo[servoIndex].pin = ESP32_WRONG_PIN; - servo[servoIndex].enabled = false; + servo[servoIndex].enabled = false; - return true; + return true; } void ESP32_ISR_Servo::enableAll() { - // Enable all servos with a enabled and count != 0 (has PWM) and good pin - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); - - for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) - { - // 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) ) - { - servo[servoIndex].enabled = true; - } - } - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); + // Enable all servos with a enabled and count != 0 (has PWM) and good pin + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); + + for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) + { + // 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) ) + { + servo[servoIndex].enabled = true; + } + } + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); } void ESP32_ISR_Servo::disableAll() { - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); - - // Disable all servos - for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) - { - servo[servoIndex].enabled = false; - } - - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); + + // Disable all servos + for (int servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) + { + servo[servoIndex].enabled = false; + } + + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); } bool ESP32_ISR_Servo::toggle(const uint8_t& servoIndex) { - if (servoIndex >= MAX_SERVOS) - return false; + if (servoIndex >= MAX_SERVOS) + return false; - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portENTER_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portENTER_CRITICAL(&timerMux); - servo[servoIndex].enabled = !servo[servoIndex].enabled; + servo[servoIndex].enabled = !servo[servoIndex].enabled; - // ESP32 is a multi core / multi processing chip. - // It is mandatory to disable task switches during modifying shared vars - portEXIT_CRITICAL(&timerMux); + // ESP32 is a multi core / multi processing chip. + // It is mandatory to disable task switches during modifying shared vars + portEXIT_CRITICAL(&timerMux); - return true; + return true; } int8_t ESP32_ISR_Servo::getNumServos() { - return numServos; + return numServos; } 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 +