XIAO ESP32-C3 servo

Hi, has anyone tried piloting some servos with the XIAO ESP32-C3 ?

I tried some libraries but the only way i found so far is to use the ledc example.

Any help is appreciated.

You can get some help from this thread. Somebody faced a similar issue and solved it by using the ESP32 ESP32S2 AnalogWrite library library.

By the way, in case you ever use a generic ESP32, it’s always recommended to use a servo controller like this:

Are there pins on the ESP32-C3 that are better than others for the AnalogWrite library? Pin 9 seems to work, but 10 doesn’t for some reason - running same code, just switching pin #, etc.

See post 2/3 of the link below.
XIAO-ESP32C3 PWM Supported Pins

New update for the ESP32 ESP32S2 AnalogWrite library (4.3.2) adds support for GPIO 10, 20 and 21.
Now supporting 15 PWM pins on the ESP32-C3: GPIO 0 to 10 and 18 to 21.

Also supports Servo Easing:

Wokwi_badge Servo Easing Controls three servos with different easing settings.

Using the ESP32Servo library and this sketch:


#include <ESP32Servo.h>

Servo myservo, myservo1, myservo2, myservo3, myservo4, myservo5, myservo6, myservo7, myservo8, myservo9, myservo10;

int pos = 0; 

void setup() {
  
  /*
  ESP32PWM::allocateTimer(0);
  ESP32PWM::allocateTimer(1);
  ESP32PWM::allocateTimer(2);
  ESP32PWM::allocateTimer(3);
  
  myservo.setPeriodHertz(50);
  myservo1.setPeriodHertz(50);    
  myservo2.setPeriodHertz(50);
  myservo3.setPeriodHertz(50);
  myservo4.setPeriodHertz(50);
  myservo5.setPeriodHertz(50);
  myservo6.setPeriodHertz(50);
  myservo7.setPeriodHertz(50);
  myservo8.setPeriodHertz(50);
  myservo9.setPeriodHertz(50);
  */
  myservo.attach(0, 750, 2250);
  myservo1.attach(1, 750, 2250); 
  myservo2.attach(2, 750, 2250);
  myservo3.attach(3, 750, 2250);
  myservo4.attach(4, 750, 2250);
  myservo5.attach(5, 750, 2250);
  myservo6.attach(6, 750, 2250);
  myservo7.attach(7, 750, 2250);
  myservo8.attach(8, 750, 2250);
  myservo9.attach(9, 750, 2250);
  myservo10.attach(10, 750, 2250);
  
  
  
}

void loop() {
  
  myservo.write(180);
  myservo1.write(180);
  myservo2.write(180);
  myservo3.write(180);
  myservo4.write(180);
  myservo5.write(180);
  myservo6.write(180);
  myservo7.write(180);
  myservo8.write(180);
  myservo9.write(180);
  myservo10.write(180);
  delay(3000);                      

  
  myservo.write(0);
  myservo1.write(0);
  myservo2.write(0);
  myservo3.write(0);
  myservo4.write(0);
  myservo5.write(0);
  myservo6.write(0);
  myservo7.write(0);
  myservo8.write(0);
  myservo9.write(0);
  myservo10.write(0);
  delay(3000);                      
  
}

My servo moved on pin 0 and pin 2 only.

When i upgraded to last version i get pin 0,3,4,7,9,10 working.

Does someone have the same results ?

I think there is a problem when using to many pins as pwm at the same time.

In addition to my previous post, when i use the ESP32S2 AnalogWrite library with this sketch :

/*
  Controls servo position from 0-180 degrees and back
  https://wokwi.com/projects/350037178957431378
  by dlloydev, December 2022.
*/

#include <pwmWrite.h>

Pwm pwm = Pwm();


void setup() {
}

void loop() {
  for (int pos = 0; pos <= 180; pos++) {  // go from 0-180 degrees
    pwm.writeServo(0, pos); 
    pwm.writeServo(1, pos);
    pwm.writeServo(2, pos);
    pwm.writeServo(3, pos);
    pwm.writeServo(4, pos);
    pwm.writeServo(5, pos);
    pwm.writeServo(6, pos);
    pwm.writeServo(7, pos);
    pwm.writeServo(8, pos); 
    pwm.writeServo(9, pos);
    pwm.writeServo(10, pos);
    delay(15);
  }
  for (int pos = 180; pos >= 0; pos--) {  // go from 180-0 degrees
    pwm.writeServo(0, pos); 
    pwm.writeServo(1, pos);
    pwm.writeServo(2, pos);
    pwm.writeServo(3, pos);
    pwm.writeServo(4, pos);
    pwm.writeServo(5, pos);
    pwm.writeServo(6, pos);
    pwm.writeServo(7, pos);
    pwm.writeServo(8, pos); 
    pwm.writeServo(9, pos);
    pwm.writeServo(10, pos);
    delay(15);
  }
}

I get pin0,1,2,3 working but no other.

If i comment them in code like this :

/*
  Controls servo position from 0-180 degrees and back
  https://wokwi.com/projects/350037178957431378
  by dlloydev, December 2022.
*/

#include <pwmWrite.h>

Pwm pwm = Pwm();


void setup() {
}

void loop() {
  for (int pos = 0; pos <= 180; pos++) {  // go from 0-180 degrees
    /*pwm.writeServo(0, pos); 
    pwm.writeServo(1, pos);
    pwm.writeServo(2, pos);
    pwm.writeServo(3, pos);*/
    pwm.writeServo(4, pos);
    pwm.writeServo(5, pos);
    pwm.writeServo(6, pos);
    pwm.writeServo(7, pos);
    pwm.writeServo(8, pos); 
    pwm.writeServo(9, pos);
    pwm.writeServo(10, pos);
    delay(15);
  }
  for (int pos = 180; pos >= 0; pos--) {  // go from 180-0 degrees
    /*pwm.writeServo(0, pos); 
    pwm.writeServo(1, pos);
    pwm.writeServo(2, pos);
    pwm.writeServo(3, pos);*/
    pwm.writeServo(4, pos);
    pwm.writeServo(5, pos);
    pwm.writeServo(6, pos);
    pwm.writeServo(7, pos);
    pwm.writeServo(8, pos); 
    pwm.writeServo(9, pos);
    pwm.writeServo(10, pos);
    delay(15);
  }
}

I get pin 2,3,4,5,8,9 working !

@Dlloydev Did you have similar problems in your library or with other boards ?

It’s the first time that i have those problems with an esp32, i used 3 other types of board without much problems.

Any helop is appreciated.

@2ant,

Thank you for reporting this. I have the issue resolved and hope to get the update published later today. The Arduino library registry may take up to a few days to update. In the meantime, here’s the latest code in a Wokwi example.

There are 15 servos connected … you can choose any 6 PWM pins at a time that are available on your board.

Is there an easy way to configure the library to specific PWM?

  1. Pulse width range: 500 to 2400 microseconds.
  2. Frequency: 50 Hz.

before the library update I was working with:

#include <pwmWrite.h>

Pwm pwm = Pwm();

const int servoPin4 = 8;
const int servoPin5 = 9;
const int freq = 50; // Frequency in Hz (50 Hz is common for most hobby servos)

void setup() {
  // Set the frequency for timer 4, which corresponds to channel pair 8 and 9
  pwm.setFrequency(4, freq);
}

void loop() {
  int position; // position in degrees
  for (position = 0; position <= 180; position += 30) {
    int pulseWidth4 = map(position, 0, 180, 500, 2400);
    int pulseWidth5 = map(180 - position, 0, 180, 500, 2400);
    int dutyCycle4 = map(pulseWidth4, 0, 20000, 0, (1 << 12) - 1);
    int dutyCycle5 = map(pulseWidth5, 0, 20000, 0, (1 << 12) - 1);

    pwm.write(servoPin4, dutyCycle4);
    pwm.write(servoPin5, dutyCycle5);
    delay(1000);
  }
}

Yes, I’ve started a discussion with example here on GitHub.
Wokwi Example