Odd LEDC behavior

GR8R8M8
Posts: 3
Joined: Sat Jul 03, 2021 11:47 pm

Odd LEDC behavior

Postby GR8R8M8 » Sun Jul 04, 2021 12:01 am

Hi y'all! I have a bit of an odd issue (to me at least) related to the built in clock generator. I'm trying to produce a square wave with a pulse length of ~50ns across a range of frequencies (100Hz-4kHz). I found some code relating to LEDC usage and have this:

Code: Select all

#include "driver/ledc.h"
#include "driver/periph_ctrl.h"
#include "esp_system.h"
#include "sdkconfig.h"
#include <stdio.h>
#include <math.h>

#define var_gpio_num 15
#define var_freq_hz 305
#define var_pulse_length 0.00000005
#define var_duty_resolution LEDC_TIMER_18_BIT


void app_main()
{
    periph_module_enable(PERIPH_LEDC_MODULE);

    int var_duty = var_freq_hz*var_pulse_length*262144;

    ledc_timer_config_t ledc_timer = {
       .duty_resolution = var_duty_resolution,     
       .freq_hz = var_freq_hz,
       .speed_mode = LEDC_HIGH_SPEED_MODE,
       .timer_num = LEDC_TIMER_0,
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t channel_config = {
        .channel    = LEDC_CHANNEL_0,
        .duty       = var_duty,                        
        .gpio_num   = var_gpio_num,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .timer_sel  = LEDC_TIMER_0
    };

    ledc_channel_config(&channel_config);
}
I've connected my ESP32-WROOM-32D to an oscilloscope and this code generates the 50ns, 305Hz signal pretty much perfectly (little bit of under/overshoot but that's to be expected), however if I try to change the frequency to anything greater than 305Hz (whether it be 306Hz, 1000Hz, ect) the ESP32 produces no output. I've tried changing the number of bits for the timer and the corresponding number in the "int var_duty" line, and a different range of frequencies can be produced but no matter what duty resolution I try, the full range doesn't display. If anyone has any clue as to why this is happening, some help would be greatly appreciated!

User avatar
ESP_krzychb
Posts: 399
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: Odd LEDC behavior

Postby ESP_krzychb » Sun Jul 04, 2021 4:35 am

Hi GR8R8M8 ,

If I run your code with var_freq_hz = 306, I am getting the following error on the serial terminal:

Code: Select all

E (294) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=255   
The issues is that your specific settings are outside of what can be delivered by LEDC hardware, see https://docs.espressif.com/projects/esp ... esolutions

Try the the code with some slight updates:

Code: Select all

#include "driver/ledc.h"
#include "driver/periph_ctrl.h"
#include "esp_system.h"
#include "sdkconfig.h"
#include <stdio.h>
#include <math.h>

#define var_gpio_num 15
#define var_freq_hz 306
#define var_pulse_length 0.00000005
#define var_duty_resolution LEDC_TIMER_17_BIT


void app_main()
{
    periph_module_enable(PERIPH_LEDC_MODULE);

    int var_duty = var_freq_hz * var_pulse_length * (1 << var_duty_resolution);

    ledc_timer_config_t ledc_timer = {
       .duty_resolution = var_duty_resolution,     
       .freq_hz = var_freq_hz,
       .speed_mode = LEDC_HIGH_SPEED_MODE,
       .timer_num = LEDC_TIMER_0,
    };
    ledc_timer_config(&ledc_timer);

    ledc_channel_config_t channel_config = {
        .channel    = LEDC_CHANNEL_0,
        .duty       = var_duty,                        
        .gpio_num   = var_gpio_num,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .timer_sel  = LEDC_TIMER_0
    };

    ledc_channel_config(&channel_config);

    printf("Duty %d\n", var_duty);

}

GR8R8M8
Posts: 3
Joined: Sat Jul 03, 2021 11:47 pm

Re: Odd LEDC behavior

Postby GR8R8M8 » Sun Jul 04, 2021 5:26 am

Hi! Thank you so much for getting back to me! I tested the code that you provided but I'm still not getting the expected output at frequencies greater than 610Hz. I tried a couple of combinations earlier and I was able to get the 4kHz signal at I believe a 15 bit duty resolution but lower frequencies ended up being out of range. Is there any elegant solution for this? My plan was just to manually test the boundaries of what duty resolutions would work and then change the duty resolution dependent on the frequency. Thanks again!

User avatar
ESP_krzychb
Posts: 399
Joined: Sat Oct 01, 2016 9:05 am
Contact:

Re: Odd LEDC behavior

Postby ESP_krzychb » Sun Jul 04, 2021 4:11 pm

Indeed, I would adjust the duty resolution depending on the required frequency var_freq_hz.
Within the frequency range (100 Hz ~ 4 kHz) and for the pulse width (~50 ns) you need, the following formula should work:

Code: Select all

#define APB_CLK_FREQ 80000000  // 80 MHz

int var_duty_resolution =  (int) log2 (APB_CLK_FREQ / var_freq_hz);


GR8R8M8
Posts: 3
Joined: Sat Jul 03, 2021 11:47 pm

Re: Odd LEDC behavior

Postby GR8R8M8 » Sun Jul 04, 2021 9:08 pm

You are amazing, thank you so much!

Who is online

Users browsing this forum: No registered users and 157 guests