Where (in the source files) can I change the PWM outputs?


I tried to change pwm output to shut down one motor in source code(ver 1.11.2).
I checked mixer, pwm.cpp and px4io.cpp. But, I can’t find final pwm output code.

I found that pwm value was fetched frome IO(px4io.cpp). but I don’t know where code that send pwm value to IO.

Someone know which code(line) do send pwm to IO?

1 Like

PWM Output in PX4 is not as simple as a single line of code.
It works by stringing together a number of control modules using uORB messages. You can find a diagram of all the connections here, but it’s quite complex.

For most multi-rotors, the px4io module will read in control thrust-roll-pitch-yaw data from the mc_att_rate_control module via the actuator_controls_0 message. The px4io module then uses the mixer file for your airframe, loaded at boot time, to convert the actuator_controls_0 message to PWM values which are sent to your ESCs via the MAIN or AUX ports. The PWM parameters can be used to set maximum and minimum output values, the default value when disarmed, or a failsafe value as necessary.

If you want to turn off a motor during testing, the easiest way is just to unplug it.
Failing that, you can create or edit a custom mixer file to include a zero mixer Z: on the appropriate pin.
This documentation should help.

Good luck.

1 Like

Hi Robwaat,

I am also trying to find the pwm output code but not to modify only read. Your comment has helped alot but i was wondering if you could help with the best method i should go about my problem. I am wanting to obtain the pwm_output and then perform some calculations on the pwm signal to estimate noise production at the rotors (and then export this noise calculation to outside the flight controller, but thats another problem in itself haha). I do not have an airframe so will be simulating (not sure to use SITL or HITL) and am wondering if its best to perform this calculation in px4io.cpp (as its the file with the pwm paramter) or if i should export the paramater to a seperate C/C++ file.

Any pointers will be really appreciated.


To reply @Sam2 and @eogks465,

The last place of where you will see actuator_controls_0 values is usually the attitude controller, hence for Multicopter or Fixed-Wing, you can overwrite (at your own risk) before it publishes to the uORB control outputs topic, usually like the line below
This will be quite an indirect way to change the PWM values since it has to pass through the mixer.

For @Sam2, you can export the ulog file, and the topic would be actuator_outputs, however this would only be what PX4 send to your rotors, if you are using SITL (you have more control), you can view simulator_mavlink.cpp, from the Simulator::actuator_controls_from_outputs(), you can change directly what the motors in gazebo will read, since the values will be sent via mavlink under hil_act_control

Thanks a lot for the help @matthewoots, i was able to apply the calculation i needed!!

I do have one more question, I am now trying to do the same thing but with HITL. What would the equivalent file for simulator_mavlink.cpp be for HITL, is it mavlink_main.cpp? And if so where abouts in such file would i find the equivalent Simulator::actuator_controls_from_outputs()?

I really appreciate your help!

Thank you for your advice. I want to simulate a situation in which one motor fails while a multicopter is in flight. Is it possible to simulate a motor failure situation through the aforementioned custom mixer?

Can i switch mixer during flight?


I found _actuators_0_pub.public(actuators); code in MulticopterRateControl.cpp. It is known that actuators.control has a value in the range of -1 to 1. As mentioned above, I would like to simulate the motor failure by arbitrarily changing the PWM value, not the actuators_control value. Even if I search PWM parameter, I’m not sure what code is actually sent to IO. Could you give me some advice?

To be honest switching mixers in flight isn’t something I’ve tried before, so this might not work.

That said, the mixer files are essentially a number of prameters set by an airframe script at startup. For example the default quad airframe 4001_quad_x calls rc.mc_defaults, which runs a number of commands to load the motor output mixing behaviour for a quadcopter. This is defined at compile time using quad_x.main.mix. The command set MIXER quad_x then loads it as the active mixer file.

If you were to define a custom mixer (called e.g. quad_x_broke) where one of the motor outputs is a zero mixer, it might be possible to load this during flight via an nsh shell using the command set MIXER quad_x_broke.

However, this is not something I’ve tried to do, so it might be that the controller will reject any changes to the mixer while the drone is armed / in flight as a safety precaution. You would have to try it yourself and see.

How effective is it?