madhephaestus / ESP32Servo

Arduino-compatible servo library for the ESP32
140 stars 55 forks source link

How to reduce from 20us resolution 1us? #62

Closed nuitvolgit closed 4 months ago

nuitvolgit commented 4 months ago

Hello,

I use Arduino Nano ESP32 board and just measured the pulse output using the oscilloscope that the resolution of the pulse from "writeMicroseconds" function has a resolution of 20us.

In the case of Arduino Nano 33Iot, it could provide 1us resolution using the servo library. (https://www.arduino.cc/reference/en/libraries/servo/)

Would it be possible for the ESP32Servo library to have 1us resolution (just like the servo library)? Is there any possible way to hack the library?

Thanks.

madhephaestus commented 4 months ago

https://github.com/madhephaestus/ESP32Servo/blob/ec5a4cefc29f9643c9175d4146a5f47e11ec9496/src/ESP32PWM.h#L65

the default resolution is 10 bit. This is an adjustable value because different cores have different resolutions of the timers. Try using 12 or 16 bits (im not sure which core you have and what the timer width is).

nuitvolgit commented 4 months ago

Thank you for the answer!

I tested with different resolutions and the resoultion_bits works up to 14. I got 1.2us resoultion time with resoultion_bits = 14.

Below is my code for testing servo and time resolution.

#include <ESP32Servo.h>
ESP32PWM pwm;
int servo_pin = 4;
int resolution = 14;
int period_us = 20000;  // 20ms
int freq = pow(10, 6) / period_us; // 50Hz
double max_duty = pow(2, resolution);
double us_2_duty_scale = max_duty / period_us;
int wait_ms = 1000;
int duty = 0;

void setup() {
     pwm.attachPin(servo_pin, freq, resolution);
}

void loop() {  
  for (int pulse_us = 1500; pulse_us < 1520; pulse_us += 1) {    
    duty = us_2_duty_scale * pulse_us;
    pwm.write(duty);
    delay(wait_ms); // waits 15ms to reach the pulse_usition
  }

  for (int pulse_us = 1520; pulse_us > 1500; pulse_us -= 1) {
    duty = us_2_duty_scale * pulse_us;
    pwm.write(duty);
    delay(wait_ms);
  }  
}