TL;DR: En Klipper la frecuencia PWM se establece indirectamente a través de un parámetro de cycle time (tiempo de ciclo). La frecuencia es 1 / cycle_time. La opción de configuración exacta depende de lo que estés controlando.
Qué parámetro de configuración usar
Klipper no tiene una única opción pwm_frequency. En su lugar configuras el periodo de un ciclo PWM, y Klipper deriva la frecuencia de ahí.
Ventiladores y pines de salida: cycle_time
Para ventiladores, pines de salida genéricos, canales LED y similares, usa cycle_time:
[fan]
pin: PA8
cycle_time: 0.010
hardware_pwm: False- Por defecto para
[fan]:0.010s → 100 Hz. - Por defecto para
[output_pin]:0.100s → 10 Hz. - Por defecto para canales LED
[neopixel]/[dotstar]:0.010s → 100 Hz.
El parámetro está documentado en docs/Config_Reference.md para [fan] (líneas 3239-3242) y [output_pin] (líneas 3678-3681).
Calentadores: pwm_cycle_time
Para calentadores (extrusor, cama caliente, etc.) el parámetro se llama pwm_cycle_time:
[extruder]
heater_pin: PA2
pwm_cycle_time: 0.100- Por defecto:
0.100s → 10 Hz. - La documentación indica que “no se recomienda cambiar esto a menos que haya un requisito eléctrico para conmutar el calentador más de 10 veces por segundo” (Config_Reference.md).
Cycle time configurable en tiempo de ejecución: [pwm_cycle_time]
Si necesitas cambiar el cycle time del PWM en tiempo de ejecución vía G-code, usa la sección [pwm_cycle_time]:
[pwm_cycle_time my_pin]
pin: PB0Luego en tiempo de ejecución:
SET_PIN PIN=my_pin VALUE=0.5 CYCLE_TIME=0.001Esto está documentado en docs/Config_Reference.md e implementado en klippy/extras/pwm_cycle_time.py.
Cómo se usa el valor internamente
En klippy/mcu.py, la clase MCU_pwm convierte el cycle time en ticks de reloj del MCU:
cycle_ticks = self._mcu.seconds_to_clock(self._cycle_time)Para PWM por software esto se convierte en el argumento cycle_ticks de set_digital_out_pwm_cycle (línea 488), y el tiempo activo dentro de cada ciclo se programa en las mismas unidades de tick. Para PWM por hardware el mismo valor cycle_ticks se pasa a la función gpio_pwm_setup() específica de la plataforma, que luego elige un prescaler y periodo del temporizador que mejor se ajusten.
Advertencia sobre PWM por hardware: la frecuencia real puede diferir
Cuando se establece hardware_pwm: True, la frecuencia que solicitas es solo un objetivo. El periférico del temporizador del MCU debe elegir un prescaler y un periodo del contador que se ajusten a sus límites de hardware, por lo que la frecuencia real puede ser ligeramente diferente.
Por ejemplo, la implementación STM32 en src/stm32/hard_pwm.c calcula los valores hwpwm_ticks y prescaler más cercanos alcanzables (líneas 328-348). La frecuencia final en STM32 es aproximadamente:
frequency = CLOCK_FREQ / (prescaler * hwpwm_ticks * pclock_div)Si dos pines PWM por hardware comparten el mismo temporizador, deben usar también la misma frecuencia; de lo contrario Klipper se detiene con “PWM already programmed at different speed” (línea 356).
Ejemplos prácticos
Ventilador de 25 kHz para control PWM de 4 hilos
[fan]
pin: PA8
cycle_time: 0.00004
hardware_pwm: True1 / 0.00004 = 25.000 Hz. Como esto está fuera del rango fiable del PWM por software, se requiere hardware_pwm: True.
Ventilador de refrigeración de piezas estándar de 100 Hz
[fan]
pin: PA8
cycle_time: 0.010Este es el valor por defecto y funciona bien con PWM por software.
Calentador de 10 Hz
[extruder]
heater_pin: PA2
pwm_cycle_time: 0.100De nuevo el valor por defecto; no es necesario cambiarlo a menos que tu MOSFET/driver necesite conmutación más rápida.
Resumen
- La frecuencia PWM en Klipper siempre es
1 / cycle_time. - Usa
cycle_timepara ventiladores, pines de salida y LEDs. - Usa
pwm_cycle_timepara calentadores. - El PWM por software respeta el cycle time exactamente.
- El PWM por hardware puede redondear el cycle time debido a las restricciones del temporizador del MCU.