Skip to content

Regression in esp32-hal-ledc.c, merges 2 pins to 1 timer when it is not welcome #12157

@ninersheep

Description

@ninersheep

Board

ESP32 Dev Module

Device Description

WT32-eth01 like in https://github.com/egnor/wt32-eth01

Attached to 2x TB6600 drivers, controlled, via PWM signal, https://www.aliexpress.com/p/tesla-landing/index.html?scenario=c_ppc_item_bridge&productId=33012705038&

2x MT6701 magnetic encoder, via two I2C buses

2x nema17 Pancake motors, standard deal, 1A max

Assembled on prototyping board

Hardware Configuration

Programming via USB-TTL , CH340G-2 by Tenstar Robot

Version

v3.3.3

Type

Bug

IDE Name

Arduino IDE

Operating System

Windows 11

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

921600

Description

Introduced by PR #11452 (cbdaee6)

It attempts to be smart at sharing timers.

So say you want pwm of 100hz on pin1 and pwm 1000hz on pin2.

If you instead declare both to begin at 100hz and 100hz, THEN change (at runtime) 2nds frequency to 1000hz...
It won't work because they share the timer.

Result: changing one's frequency changes both. Not good.

If you instead set up both pins with different frequencies and / or resolution, it behaves as expected in 3.3.3.

When compiling with Arduino ESP32 3.1.3, it behaved like I expected - NOT sharing timers.

When compiling with Arduino ESP32 3.3.3, it shared timers, - Big regression for me!

This behaviour should be better documented - I was led to believe, if I use ledcAttachChannel() with 2 differrent channels for 2 pins (lets say channel 0 and 2), that I would avoid such behaviour!

There's also (seemingly) nothing to hint that I'd need to worry about either software or hardware timers in documentation.

https://docs.espressif.com/projects/arduino-esp32/en/latest/api/ledc.html

I have attached two videos, one showing behaviour with 3.1.3, another 3.3.3 - Both were driven such way:

right motor is driven 5000hz

first motor is driven 500hz

Physical speeds of drives should be differrent.

https://github.com/user-attachments/assets/0b3d48a6-2703-46a3-9812-26899971ac05 3-1-3

https://github.com/user-attachments/assets/709c3e2e-c5a9-4481-8844-f84478079820 3-3-3

I've tried to provide minimal example from my code, but the minimal example also surfaced another bug which I somehow fixed in my ,,full" code,
the fact that under 3.3.3, the motors start running as soon as the ESP outputs PWM,

But under 3.1.3, in putty, It doesn't make them spin until I push any button in PUTTY serial terminal.
At this point I've spend 2.5h wrangling this issue.

Sketch

// Pins
const int DIR_PIN1    = 15;
const int ENABLE_PIN1 = 17;
const int STEP_PIN1   = 32; //PUL+ , common cathode

const int DIR_PIN2    = 12; //IO12 must float to program. 
const int ENABLE_PIN2 = 17; //shared pin.
const int STEP_PIN2   = 14;

// Global PWM Properties
int freq1 = 500; //has to be the same as freq2 for bug to trigger! for 3.3.3
int freq2 = 510; //has to be the same as freq1 for bug to trigger!
int resolution1  = 8; //may have to be the same as resolution2 for bug to trigger!
int resolution2 = 9; 
int dutyCycle1 = 128; // TB6600 doesn't really care what duty cycle it receives as long as it's not zero
int dutyCycle2 = 128; 
int direction1 = 0;
int direction2 = 0;

void setup() {
  
  pinMode(DIR_PIN1, OUTPUT);
  pinMode(ENABLE_PIN1, OUTPUT);
  pinMode(STEP_PIN1, OUTPUT);

  pinMode(DIR_PIN2, OUTPUT);
  pinMode(ENABLE_PIN2, OUTPUT);
  pinMode(STEP_PIN2, OUTPUT);

  digitalWrite(ENABLE_PIN1, LOW); 
  digitalWrite(ENABLE_PIN2, LOW); 

  // configure LEDC PWM
  ledcAttachChannel(STEP_PIN1, freq1, resolution1, 0); //last is LEDCchannel number
  ledcAttachChannel(STEP_PIN2, freq2, resolution2, 2);
  
  Serial.begin(115200);
  delay(1000);
  Serial.println("--- Bug Reproduction Sketch ---");
  Serial.println("Commands: 'F1 [val]', 'F2 [val]'.");
}

void loop() {

  ledcChangeFrequency(STEP_PIN1, freq1, resolution1);
  ledcWrite(STEP_PIN1, dutyCycle1);
  digitalWrite(DIR_PIN1, direction1); 

  ledcChangeFrequency(STEP_PIN2, freq2, resolution2);
  ledcWrite(STEP_PIN2, dutyCycle2);
  digitalWrite(DIR_PIN2, direction2); 

  pwmCheckSerial();
}

void pwmCheckSerial() {
  if (Serial.available()) {
    String input = Serial.readStringUntil('\n');
    input.trim();
    input.toUpperCase();
    if (input.startsWith("F1 ")) { //motor1
      int val = input.substring(3).toInt();
      if (val >= 10 && val <= 10000) {
        freq1 = val;
        Serial.print("Freq1 set to: "); Serial.println(freq1);
      }
    } 
    else if (input.startsWith("F2 ")) { //motor2
      int val = input.substring(3).toInt();
      if (val >= 10 && val <= 10000) {
        freq2 = val;
        Serial.print("Freq2 set to: "); Serial.println(freq2);
      }
    }
  }
}

Debug Message

// 3.3.3 

[    17][D][esp32-hal-cpu.c:276] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, A                       PB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q5
  Revision          : 3.01
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   378188 B ( 369.3 KB)
  Free Bytes        :   336484 B ( 328.6 KB)
  Allocated Bytes   :    34380 B (  33.6 KB)
  Minimum Free Bytes:   330856 B ( 323.1 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Flash Frequency   : 80 MHz (source: 80 MHz, divider: 1)
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: N                       VS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: O                       TA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: O                       TA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: O                       TA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: S                       PIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: C                       OREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Dec 19 2025 16:20:31
  Compile Host OS   : windows
  ESP-IDF Version   : v5.5.1-418-gf1a1df9b2e
  Arduino Version   : 3.3.3
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : esp32
  Arduino FQBN      : esp32:esp32:esp32:UploadSpeed=921600,CPUFreq=240,FlashFreq                       =80,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=debug,PSRAM=di                       sabled,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=de                       fault
============ Before Setup End ============
[   543][D][esp32-hal-ledc.c:53] find_matching_timer(): Searching for timer with                        freq=500, resolution=8
[   552][D][esp32-hal-ledc.c:69] find_matching_timer(): No matching timer found                        for freq=500, resolution=8
[   564][D][esp32-hal-ledc.c:97] find_free_timer(): Found free timer 0
[   572][I][esp32-hal-ledc.c:288] ledcAttachChannel(): LEDC attached to pin 32 (                       channel 0, resolution 8)
[   584][D][esp32-hal-ledc.c:53] find_matching_timer(): Searching for timer with                        freq=510, resolution=9
[   595][D][esp32-hal-ledc.c:69] find_matching_timer(): No matching timer found                        for freq=510, resolution=9
[   606][D][esp32-hal-ledc.c:85] find_free_timer(): Timer 0 is in use by channel                        0
[   616][D][esp32-hal-ledc.c:97] find_free_timer(): Found free timer 1
[   624][I][esp32-hal-ledc.c:288] ledcAttachChannel(): LEDC attached to pin 14 (                       channel 2, resolution 9)
--- Bug Reproduction Sketch ---
Commands: 'F1 [val]', 'F2 [val]'.
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   378188 B ( 369.3 KB)
  Free Bytes        :   333756 B ( 325.9 KB)
  Allocated Bytes   :    36756 B (  35.9 KB)
  Minimum Free Bytes:   328128 B ( 320.4 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------
     1 : UART_TX[0]
     3 : UART_RX[0]
    12 : GPIO
    14 : LEDC[2][1]
    15 : GPIO
    17 : GPIO
    32 : LEDC[0][0]
============ After Setup End =============

-----------------------------------------------------

//3.1.3 

 [    17][D][esp32-hal-cpu.c:263] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q5
  Revision          : 3.01
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   379396 B ( 370.5 KB)
  Free Bytes        :   339144 B ( 331.2 KB)
  Allocated Bytes   :    32936 B (  32.2 KB)
  Minimum Free Bytes:   333776 B ( 326.0 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Dec 19 2025 16:38:43
  Compile Host OS   : windows
  ESP-IDF Version   : v5.3.2-584-g489d7a2b3a-dirty
  Arduino Version   : 3.1.3
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : esp32
  Arduino FQBN      : esp32:esp32:esp32:UploadSpeed=921600,CPUFreq=240,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=debug,PSRAM=disabled,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=default
============ Before Setup End ============
[   536][I][esp32-hal-ledc.c:166] ledcAttachChannel(): LEDC attached to pin 32 (channel 0, resolution 8)
[   545][I][esp32-hal-ledc.c:166] ledcAttachChannel(): LEDC attached to pin 14 (channel 2, resolution 9)
--- Bug Reproduction Sketch ---
Commands: 'F1 [val]', 'F2 [val]'.
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   379396 B ( 370.5 KB)
  Free Bytes        :   336536 B ( 328.6 KB)
  Allocated Bytes   :    35192 B (  34.4 KB)
  Minimum Free Bytes:   331168 B ( 323.4 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------
     1 : UART_TX[0]
     3 : UART_RX[0]
    12 : GPIO
    14 : LEDC[0][2]
    15 : GPIO
    17 : GPIO
    32 : LEDC[0][0]
============ After Setup End =============


///3.3.3 with both 500s

[    17][D][esp32-hal-cpu.c:276] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q5
  Revision          : 3.01
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   378188 B ( 369.3 KB)
  Free Bytes        :   336484 B ( 328.6 KB)
  Allocated Bytes   :    34380 B (  33.6 KB)
  Minimum Free Bytes:   330856 B ( 323.1 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Flash Frequency   : 80 MHz (source: 80 MHz, divider: 1)
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Dec 19 2025 16:57:55
  Compile Host OS   : windows
  ESP-IDF Version   : v5.5.1-418-gf1a1df9b2e
  Arduino Version   : 3.3.3
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : esp32
  Arduino FQBN      : esp32:esp32:esp32:UploadSpeed=921600,CPUFreq=240,FlashFreq=80,FlashMode=qio,FlashSize=4M,PartitionScheme=default,DebugLevel=debug,PSRAM=disabled,LoopCore=1,EventsCore=1,EraseFlash=none,JTAGAdapter=default,ZigbeeMode=default
============ Before Setup End ============
[   543][D][esp32-hal-ledc.c:53] find_matching_timer(): Searching for timer with freq=500, resolution=8
[   552][D][esp32-hal-ledc.c:69] find_matching_timer(): No matching timer found for freq=500, resolution=8
[   564][D][esp32-hal-ledc.c:97] find_free_timer(): Found free timer 0
[   572][I][esp32-hal-ledc.c:288] ledcAttachChannel(): LEDC attached to pin 32 (channel 0, resolution 8)
[   584][D][esp32-hal-ledc.c:53] find_matching_timer(): Searching for timer with freq=500, resolution=8
[   595][D][esp32-hal-ledc.c:63] find_matching_timer(): Found matching timer 0 for freq=500, resolution=8
[   606][I][esp32-hal-ledc.c:288] ledcAttachChannel(): LEDC attached to pin 14 (channel 2, resolution 8)
--- Bug Reproduction Sketch ---
Commands: 'F1 [val]', 'F2 [val]'.
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   378188 B ( 369.3 KB)
  Free Bytes        :   333756 B ( 325.9 KB)
  Allocated Bytes   :    36756 B (  35.9 KB)
  Minimum Free Bytes:   328128 B ( 320.4 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------
     1 : UART_TX[0]
     3 : UART_RX[0]
    12 : GPIO
    14 : LEDC[2][0]
    15 : GPIO
    17 : GPIO
    32 : LEDC[0][0]
============ After Setup End =============

Other Steps to Reproduce

Just make it not connect to same timer by default,,,

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions