ESP-IDF : ESP32 Change Servo Angle With Gradient

We can control a servo using ESP IDF LEDC API. We have already seen how to do that here. The servo sweep program changes the angle of servo in steps as per sweepDuration. Means the duty cycle will change from minValue to maxValue in duration specified by sweepDuration. This lets us control how fast servo reaches from its current position to a target position. In this post we will see how to improve on sweepServo program.

In sweepServo code, All the logic that controls the gradient is present in application layer. LEDC API provides many functions to handle situations like this. For example with ledc_set_fade_with_time, we can spread a given servo transition over a time period. On other hand if we use ledc_set_duty it will be a step change. Servo will try to jump from current position to target position in shortest possible time as the PWM signal will change instantaneously.

Lets see an example on how to use ledc_set_fade_with_time. Lets assume that we have a situation where servo is moving between two angles with a period T. We will make the transition between these two angles smoother (done over a time period) instead of instantaneous.

 void setServoAngle(int target_angle){
    ledc_set_fade_with_time(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_2, (uint16_t)(servo_duty+ (servo_delta(target_angle/180.0))),
                           SERVO_TRANSITION_TIME);
    ledc_fade_start(LEDC_HIGH_SPEED_MODE,LEDC_CHANNEL_2,LEDC_FADE_WAIT_DONE);
} 

 void gradientServoTask(void *ignore) {
     configureServo();
     while(1){
            setServoAngle(ACTIVE_ANGLE);
            ESP_LOGI(tag,"Servo in active angle");
            vTaskDelay(pdMS_TO_TICKS(SERVO_TIME_PERIOD));
            setServoAngle(REST_ANGLE);
            ESP_LOGI(tag,"Servo in rest angle");
            vTaskDelay(pdMS_TO_TICKS(SERVO_TIME_PERIOD));
    }
} 

full code is available here.

Add a Comment

Your email address will not be published. Required fields are marked *