Ledc library for esp32

Dear all,
I m trying to use the ledc.h library.
I have no signal on the oscilloscope. I should have got a length of 200 ms at 50% LOW, 50% HIGH. I have done a mistake but wich one? I have set frequency to 5000Hz. I put a resolution of 1 bit and 50% cyclacity. Why there s no signal? Thanks


[code]


#include "driver/ledc.h"


const int dcc_pin = 19;  // choix de la broche dcc out : n'importe laquelle peut être utilisée /// en se servant de la matrice du gpio

// setting PWM properties
#define dcc_sig_1_freq 8621 // fréquency of ~116µs 
#define dcc_sig_0_freq 5000 // fréquency of 200µs 
const int pin_channel = 0; // choice of te channel PWM = 0
const int sig_resolution = 1; // resolution = 1 bit => 2^1 = 0,1,2
const int sig_duty = 1; // cyclacity of 1/2 or 50% 1 is 50% or 1/2^1
uint32_t sig_freq = dcc_sig_0_freq; // set the frequency


void setup() {
   ledcAttachPin(dcc_pin, pin_channel); /// attach pin 19 to channel PWM
  ledcSetup(pin_channel,sig_freq, sig_resolution); //freauency of 5000 or 8621 
  ledcWrite(pin_channel, sig_duty); // set channel 0 with a cyclacity of 50%

}

void loop() {
  delay(10); 
}

[/code]
#include "esp32-hal-ledc.h"

#define iLIDAR_Posit90 1475 //using writeMicroseconds
#define iX_Posit90 1500 //using writeMicroseconds

#define TIMER_WIDTH 16
#define REFRESH_USEC  20000
#define TIMER_FREQUENCY 50

////// Recommended servo pins include 2,4,12-19,21-23,25-27,32-33
/*
** ledc: 0  => Group: 0, Channel: 0, Timer: 0
** ledc: 1  => Group: 0, Channel: 1, Timer: 0
** ledc: 2  => Group: 0, Channel: 2, Timer: 1
** ledc: 3  => Group: 0, Channel: 3, Timer: 1
** ledc: 4  => Group: 0, Channel: 4, Timer: 2
** ledc: 5  => Group: 0, Channel: 5, Timer: 2
** ledc: 6  => Group: 0, Channel: 6, Timer: 3
** ledc: 7  => Group: 0, Channel: 7, Timer: 3
** ledc: 8  => Group: 1, Channel: 8, Timer: 0
** ledc: 9  => Group: 1, Channel: 9, Timer: 0
** ledc: 10 => Group: 1, Channel: 10, Timer: 1
** ledc: 11 => Group: 1, Channel: 11, Timer: 1
** ledc: 12 => Group: 1, Channel: 12, Timer: 2
** ledc: 13 => Group: 1, Channel: 13, Timer: 2
** ledc: 14 => Group: 1, Channel: 14, Timer: 3
** ledc: 15 => Group: 1, Channel: 15, Timer: 3
*/
void setup()
{
 ledcSetup ( Channel_X, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( XaxisServoPin, Channel_X );   //
  ledcWrite (Channel_X, usToTicks ( iX_Posit90 ) );       //
  vTaskDelay( ServoDelay60mS );
  ////
  ledcSetup( Channel_LIDAR, TIMER_FREQUENCY, TIMER_WIDTH); //
  ledcAttachPin( Servo_LIDAR_Pin, Channel_LIDAR);   //
  ledcWrite( Channel_LIDAR, usToTicks ( iLIDAR_Posit90 ) );
  vTaskDelay( ServoDelay60mS );
  ////
  ledcSetup ( Channel_Y, TIMER_FREQUENCY, TIMER_WIDTH ); //
  ledcAttachPin ( YaxisServoPin, Channel_Y );   //
  ledcWrite (Channel_Y, usToTicks ( iY_Posit90 ) );  //
  vTaskDelay( ServoDelay60mS );
}

int usToTicks(int usec)
{
  return (int)((float)usec / ((float)REFRESH_USEC / (float)timer_width_ticks) * (((float)TIMER_FREQUENCY) / 50.0));
} // int usToTicks(int usec)

Is how I used the LEDC to drive a servo.

I now use the ESP32's MCPWM API to set motor PWM over the LEDC API.

The note "// set channel 0 with a cyclacity of 50%`" is oncorrect.

Microseconds, not milliseconds.

Ok thanks. Do you know why my programme does not work?

Yes.

Did you look over the code I posted VS the code you posted to see the differences?

I am not familiar at all with this library. Sorry for that and that is not obvious for me. The TIMER_FREQUENCY I want to use is 5000Hz in order to buid a time length of 200 microseconds with a 1-bit resolution and 50% cyclacity (so duty = 1). if you may elaborate a bit more because I do not see is my mistake... many thanks in advance

Need to call ledcSetup() first ...

void setup() {
  ledcSetup(pin_channel, sig_freq, sig_resolution); //freauency of 5000 or 8621
  ledcAttachPin(dcc_pin, pin_channel); /// attach pin 19 to channel PWM
  ledcWrite(pin_channel, sig_duty); // set channel 0 with a cyclacity of 50%
}

Thanks I have still the same issue: no signal.

LED Control

Maybe your settings are out of supported range for frequency / duty combination.
Does 5 kHz frequency with 13 bit resolution work (sig_duty = 4096)?

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/ledc.html

Good luck.

1 Like

Indeed. It wokrs with 13 bits. Question: why it does not work with 1-bit resolution. Does it change something?

Hi,
in ESP32 the resolution is not a fixed value.
It varies directly with frequency.
And the duty also varies with the resolution.
Inside the code I posted there are the formulas for calculating the resolution and the duty for ESP32.

Try this code.

#include "driver/ledc.h"
const int dcc_pin = 19;               // choix de la broche dcc out : n'importe laquelle peut être utilisée
//                                    // en se servant de la matrice du gpio
//                                    // setting PWM properties
#define dcc_sig_1_freq 8621           // fréquency of ~116µs 
#define dcc_sig_0_freq 5000           // fréquency of 200µs 
const int pin_channel = 0;            // choice of te channel PWM = 0
unsigned int sig_resolution = 1;         // resolution = 1 bit => 2^1 = 0,1,2
unsigned long sig_duty = 1;               // cyclacity of 1/2 or 50% 1 is 50% or 1/2^1
uint32_t sig_freq = dcc_sig_0_freq;   // set the frequency
int percent = 50;                       // Duty percentage
//---------------------------------------------------------------------------
void setup() {
//  Serial.begin(115200);
  delay(200);

  //  Calculation of settings for each frequency band
  //  Resolution = log2(Clock(80MHz)/f) + 1   ex: 50.000 HZ = 80.0000/50.000 = 1.600 log2(1600) = 10 + 1 = 11
  // wrong  //  Duty A%  = (2^Resolution)*(A/100)       ex: duty 50% --> 2**11 = 2048   2048/2 = 1024
 // correct//  Duty A%  = (2^Resolution)/(100/A)       ex: duty 50% --> 2**11 = 2048   2048/2 = 1024

  sig_resolution = int(log((80000000 / sig_freq) + 1) / log(2));
//  Serial.print("sig_resolution: "); Serial.println(sig_resolution);                 
  sig_duty = pow(2, sig_resolution)/(100/percent);
  
//  Serial.print("sig_duty: "); Serial.println(sig_duty); 

  ledcAttachPin(dcc_pin, pin_channel);                  // attach pin 19 to channel PWM
  ledcSetup(pin_channel, sig_freq, sig_resolution);     //freauency of 5000 or 8621
  ledcWrite(pin_channel, sig_duty );                     // set channel 0 with a cyclacity of 50%
}
//---------------------------------------------------------------------------
void loop() {
  delay(10);
}

Hello very useful. Many thanks.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.