feat(drivers/pca9685_pwm_out): merge PCA9685_SCHD_HZ into PCA9685_PWM_FREQ (#28705)

PCA9685_PWM_FREQ and PCA9685_SCHD_HZ controlled the same physical PWM
rate through two independent parameters that had to be kept in sync
manually by the user, and neither was exposed in the ground station's
Actuators tab.

Merge both into PCA9685_PWM_FREQ, which now drives both the chip's
PWM frequency and the I2C update rate, and expose it as a single
config field on the actuator output group.

PCA9685_SCHD_HZ is removed outright, with no automatic migration: a
saved PCA9685_PWM_FREQ carries over for free since the name is
unchanged, and PCA9685_SCHD_HZ was intentionally left orphaned rather
than migrated, so that inspecting main.cpp or PCA9685.cpp is enough
to understand the current behavior of the driver.

Verified on real Skynode S hardware: the parameter reaches the
Actuators tab in the ground station, and the PWM frequency measured
with a logic analyzer on the PCA9685 output pin matches the
configured value.

Assisted-by: Claude:claude-sonnet-5

Signed-off-by: danielbuleandra <daniel.buleandra@auterion.com>
This commit is contained in:
Daniel Buleandră
2026-09-25 11:47:54 +02:00
committed by GitHub
parent 253479bbeb
commit ba140de1e4
3 changed files with 19 additions and 44 deletions
+1
View File
@@ -31,6 +31,7 @@ Please continue reading for [upgrade instructions](#upgrade-guide).
## Upgrade Guide
- `COM_ARM_TRAFF` has been replaced by `COM_TRAFF_AVOID`. The old value 3 ("enforce for mission modes only") is migrated to `COM_TRAFF_AVOID=2`, which blocks arming in all modes, not just mission modes. If you relied on being able to arm manually with traffic detected, set `COM_TRAFF_AVOID=1` (warning only) instead.
- `PCA9685_SCHD_HZ` has been removed. `PCA9685_PWM_FREQ` now sets both the PWM frequency of the PCA9685 and the rate at which values are pushed to it; if you had `PCA9685_SCHD_HZ` set to a non-default value, set `PCA9685_PWM_FREQ` to it after upgrading. Frequencies above 400 Hz (previously only usable in duty-cycle mode) are no longer supported.
- **Re-check motor failure handling on hexarotors.** [CA_FAILURE_MODE](../advanced_config/parameter_reference.md#CA_FAILURE_MODE) = `1` now also stops the motor opposite the failed one on a hexarotor (previously only the failed motor was removed from the allocation). Other airframes are unaffected, and `CA_FAILURE_MODE=0` (the default) is unchanged. See [Motor Failure Recovery](../config/motor_failure_recovery.md). ([PX4-Autopilot#28078](https://github.com/PX4/PX4-Autopilot/pull/28078))
## Other changes
+5 -21
View File
@@ -102,8 +102,7 @@ private:
true
};
float param_pwm_freq, previous_pwm_freq;
float param_schd_rate, previous_schd_rate;
float param_pwm_freq{50.f}, previous_pwm_freq{0.f};
bool param_update_failed = false;
uint32_t param_duty_mode;
@@ -218,9 +217,8 @@ void PCA9685Wrapper::Run()
if (ret == PX4_OK) {
previous_pwm_freq = param_pwm_freq;
previous_schd_rate = param_schd_rate;
_state = STATE::RUNNING;
ScheduleOnInterval(1000000 / param_schd_rate, 0);
ScheduleOnInterval(1000000 / param_pwm_freq, 0);
} else {
perf_count(_comms_errors);
@@ -253,11 +251,9 @@ void PCA9685Wrapper::Run()
ret |= pca9685->wake();
if (ret == PX4_OK) {
// update of PWM freq will always trigger scheduling change
param_update_failed = false;
previous_schd_rate = param_schd_rate;
previous_pwm_freq = param_pwm_freq;
ScheduleOnInterval(1000000 / param_schd_rate, 0);
ScheduleOnInterval(1000000 / param_pwm_freq, 0);
} else {
param_update_failed = true;
@@ -265,12 +261,6 @@ void PCA9685Wrapper::Run()
ScheduleDelayed(20_ms);
break;
}
} else if ((float)fabs(previous_schd_rate - param_schd_rate) > 0.01f) {
// case when PWM freq not changed but scheduling rate does
previous_schd_rate = param_schd_rate;
ScheduleClear();
ScheduleOnInterval(1000000 / param_schd_rate, 1000000 / param_schd_rate);
}
}
@@ -407,14 +397,8 @@ int PCA9685Wrapper::task_spawn(int argc, char **argv) {
void PCA9685Wrapper::updateParams() {
ModuleParams::updateParams();
param_t param = param_find("PCA9685_SCHD_HZ");
if (param != PARAM_INVALID) {
param_get(param, &param_schd_rate);
} else {
PX4_ERR("param PCA9685_SCHD_HZ not found");
}
param = param_find("PCA9685_PWM_FREQ");
// sets both the PWM frequency of the chip and the rate we push new values at
param_t param = param_find("PCA9685_PWM_FREQ");
if (param != PARAM_INVALID) {
param_get(param, &param_pwm_freq);
} else {
+13 -23
View File
@@ -1,5 +1,8 @@
module_name: PCA9685 Output
actuator_output:
config_parameters:
- param: 'PCA9685_PWM_FREQ'
label: 'PWM Frequency'
output_groups:
- param_prefix: PCA9685
channel_label: 'Channel'
@@ -40,34 +43,21 @@ parameters:
min: 1
max: 127
default: 64
PCA9685_SCHD_HZ:
description:
short: PWM update rate
long: |
Controls the update rate of PWM output.
Flight Controller will inform those numbers of update events in a second, to PCA9685.
Higher update rate will consume more I2C bandwidth, which may even lead to worse
output latency, or completely block I2C bus.
type: float
decimal: 2
min: 50.0
max: 400.0
default: 50.0
PCA9685_PWM_FREQ:
description:
short: PWM cycle frequency
short: PWM frequency and update rate
long: |
Controls the PWM frequency at timing perspective.
This is independent from PWM update frequency, as PCA9685 is capable to output
without being continuously commanded by FC.
Higher frequency leads to more accurate pulse width, but some ESCs and servos may not support it.
This parameter should be set to the same value as PWM update rate in most case.
This parameter MUST NOT exceed upper limit of 400.0, if any outputs as generic 1000~2000us
pulse width is desired. Frequency higher than 400 only makes sense in duty-cycle mode.
Sets the PWM frequency generated by the PCA9685, and the rate at which the Flight
Controller pushes new output values to it.
A higher rate gives a more accurate pulse width, but consumes more I2C bandwidth,
which may lead to worse output latency or completely block the I2C bus.
Values above 400 are not supported: a generic 1000~2000us pulse width cannot be
produced above that, and the I2C bus cannot sustain the resulting update rate.
type: float
decimal: 2
min: 23.8
max: 1525.87
unit: Hz
min: 50.0
max: 400.0
default: 50.0
PCA9685_DUTY_EN:
description: