khoih-prog / ESP32_ISR_Servo

This library enables you to use 1 Hardware Timer on 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
MIT License
30 stars 9 forks source link

working example? #4

Closed cstoker2 closed 2 years ago

cstoker2 commented 2 years ago

I'm not able to get the example "MultipleServos" working (nor any of the other examples...) This is using library 1.2.1 on an adafruit esp32 feather. esp32 core 2.0.3 is installed on arduino ide 1.8.19 on windows 10 machine

I get no pwm output on any of the pins A0 - A5 on the oscilloscope.

Here's the serial output I get:

13:50:11.064 -> 
13:50:11.064 -> Starting MultipleServos on FEATHER_ESP32
13:50:11.064 -> ESP32_ISR_Servo v1.2.1
13:50:11.064 -> [ISR_SERVO] ESP32_TimerInterrupt: _timerNo = 3 , _fre = 1000000
13:50:11.064 -> [ISR_SERVO] TIMER_BASE_CLK = 80000000 , TIMER_DIVIDER = 80
13:50:11.064 -> [ISR_SERVO] _timerIndex = 1 , _timerGroup = 1
13:50:11.064 -> [ISR_SERVO] _count = 0 - 10
13:50:11.064 -> [ISR_SERVO] timer_set_alarm_value = 10.00

(and it just hangs there)

Is there a simpler example? perhaps just a single servo? Thanks

Here's the full code of the example: (comments and pin definitions from the top removed for brevity)

#define TIMER_INTERRUPT_DEBUG       1
#define ISR_SERVO_DEBUG             1

// Select different ESP32 timer number (0-3) to avoid conflict
#define USE_ESP32_TIMER_NO          3

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "ESP32_ISR_Servo.h"

//See file .../hardware/espressif/esp32/variants/(esp32|doitESP32devkitV1)/pins_arduino.h
#define LED_BUILTIN       2         // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED
#define PIN_LED           2         // Pin D2 mapped to pin GPIO2/ADC12 of ESP32, control on-board LED

// for feather esp32
#define PIN_A0           26         // Pin A0 mapped to pin GPIO26
#define PIN_A1           25         // Pin A1 mapped to pin GPIO25
#define PIN_A2           34         // Pin A2 mapped to pin GPIO34
#define PIN_A3           39         // Pin A3 mapped to pin GPIO39
#define PIN_A4           36         // Pin A4 mapped to pin GPIO36
#define PIN_A5            4         // Pin A5 mapped to pin GPIO4

#define PIN_RX0            3        // Pin RX0 mapped to pin GPIO3/RX0 of ESP32
#define PIN_TX0            1        // Pin TX0 mapped to pin GPIO1/TX0 of ESP32

#define PIN_SCL           22        // Pin SCL mapped to pin GPIO22/SCL of ESP32
#define PIN_SDA           21        // Pin SDA mapped to pin GPIO21/SDA of ESP32  

// Published values for SG90 servos; adjust if needed
#define MIN_MICROS      800  //544
#define MAX_MICROS      2450

#define NUM_SERVOS    6

typedef struct
{
  int     servoIndex;
  uint8_t servoPin;
} ISR_servo_t;

ISR_servo_t ISR_servo[NUM_SERVOS] =
{
  { -1, PIN_A0 }, { -1, PIN_A1 }, { -1, PIN_A2 }, { -1, PIN_A3 }, { -1, PIN_A4 }, { -1, PIN_A5 }
};

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);
    }
  }
}

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);
}
khoih-prog commented 2 years ago

The recent ESP32 core v2.0.3 has introduced some breaking changes, resulting this and the other ESP32_New_ISR_Servo library stop working.

The temporarily fix you can use now is using the ESP32_ISR_MultiServos example with the following change

https://github.com/khoih-prog/ESP32_ISR_Servo/blob/7ae4e47cf56826e1282a99d52410e6434dfd6542/examples/ESP32_ISR_MultiServos/ESP32_ISR_MultiServos.ino#L80

to

#define USE_ESP32_TIMER_NO          0

and use pins GPIO2 and GPIO4 for the servos.

It's quite simple to modify for just 1 servo, by deleting all references to servoIndex2

Also remember to change the pin usage according to your board.

I'll spend time to fix the library, if time permitted and there are more requests.

You can also go back to previous ESP32 cores and figure out which one is working. I don't have time now for that job.

khoih-prog commented 2 years ago

Hi @cstoker2

You now can use the ESP32_New_ISR_Servo releases v1.2.0 with ESP32 core v2.0.3


Releases v1.2.0

  1. Fix breaking issue caused by ESP32 core v2.0.1+ by increasing TIMER_INTERVAL_MICRO to 12uS from 10uS. Tested OK with ESP32 core v2.0.3 now)
khoih-prog commented 2 years ago

Hi @cstoker2

You now also can use the ESP32_ISR_Servo releases v1.3.0 with ESP32 core v2.0.3


Releases v1.3.0

  1. Fix breaking issue caused by ESP32 core v2.0.1+ by increasing TIMER_INTERVAL_MICRO to 12uS from 10uS. Tested OK with ESP32 core v2.0.3 now)
cstoker2 commented 2 years ago

Thanks for the update! Works!