New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
driver/pca9685_pwm_output: bugfixs & QGC integration & support outputting in duty-cycle mode #21528
Conversation
565a66a
to
f6124ac
Compare
f6124ac
to
8faefca
Compare
Anyone interested in this stuff...? Maybe I need to find a pca9685 module and driving some LEDs mapped to RC inputs with this new driver on a pixhawk as a video demo to attract some attemtion...... |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: https://discuss.px4.io/t/px4-community-q-a-may-17-2023/32159/1 |
This guide might be moved somewhere later: PCA9685 PWM ExpanderBy using one of the PCA9685 module, you'll get another 16 PWM outputs on your Flight Controller. You can control servos, ESCs, as well as LEDs, even a single MOSFET which drives another brushed motor! Before going ahead, the following conditions is suggested to meet to make use of the module:
The driver does work on fmu_v2 but it is not included in the firmware by default. Even if you choose to manually build one by yourself, the missing Actuator Tab in QGC still makes it difficult to configure the outputs. Almost every FC has I2C buses exported. If there's already something connected to those ports, simply grabbing an I2C expander board and connect all your peripherals to that board. It should be fine to connect PCA9685 with external compass on the same I2C bus, as long as the update rate of PCA9685 is limited to lower value like 50Hz. But please avoid it if possible, due to the heavy bandwidth consumed by PCA9685. Note that currently there is no support for multiple PCA9685 instances. The following guide is based on CUAV Pixhack V3, with a piece of PCA9685 module that is easy to find on-line. FS-IA6B paired with FS-TH9X is used as RC system to finish the minimum setup of PX4. Initial SetupHardware ConnectionThe I2C port on Pixhack V3 is available through a 20pin connector. An I2C expander board is shipped alongside with FC so let's use it to connect PCA9685 module to FC. Also because PCA9685 module has 2.54mm pin header for DuPont wire connection, you still need to make your own wire by your self. Pixhack V3 ships its I2C expander board compatible to old APM style 1.25mm connector, so I just cut one side of the wire and soldered another side with 2.54mm DuPont pin socket. It is too risky to let those barely connected wires fly in to the sky. Strongly recommends to solder everything together before taking it to real flights! Only four wires are needed to be connected:
If you are going to connect servos to this module, An extra V+ pin can be used to power the rail. This pin can also be left unconnected if there is ESC connected to one of the channel, which provides BEC output to all other channels. Otherwise there will be no power output but only PWM signals on yellow pin headers. Firmware ConfigurationNow power the FC via USB and open QGC to test it. Click on the left top QGC icon and select Analyze Tools. Then click MAVLink Console and type the following command: i2cdetect -b 1 The parameter If Now try to start the driver: pca9685_pwm_out start -b 1 -a 0x40 If there is no error reported, verify the status by: pca9685_pwm_out status Congratulations! Now it's time to make PX4 start the driver on boot. Poweroff the FC, pull out the sdcard and put it onto your computer. Create a directory named Enter that directory and create a new file, named Open and write following script to that file: #!/bin/sh
pca9685_pwm_out start -b 1 -a 0x40 Save. Now eject the sdcard and insert it back to FC. Power on the FC. Open the MAVLink Shell as described before. Here we do a simple verification to ensure the driver is running now: pca9685_pwm_out status This indicates the driver is started on boot and is ready to use. Driver ConfigurationThings that may needed to be tuned:
PWM frequency will determine how many pulses will be sent out from PCA9685 in one second. Update rate (aka. schedule rate) determines how fast FC will notify PCA9685 to change its output. Setting of PWM freq has a side effect: lower PWM freq will result in lower PWM resolution. at the freq of 50Hz, PCA9685 will have about 205 steps between 1000us and 2000us signal range. That is between 7 and 8 bits resolution. At the freq of 400Hz, there are about 1638 steps between 1000us and 2000us, equal to 10~11 bits resolution. But some legacy servo or ESCs doesn't support higher PWM frequency. Setting of update rate also trades off. The higher update rate, the heavier load that CPU and I2C bus will facing. If the I2C bus is shared my multiple sensors then the update rate of PCA9685 should be kept minimal, to avoid sensor data congestion. It's OK to set PWM freq and update rate to different value, but it won't make sense if update rate is higher than PWM freq. The corresponding parameters:
Output ConfigurationThanks to the code refactor around mixer and actuator, now it is much easier to configure those custom outputs: It is very straight-forward in Actuator tab. Just select the required function and configure the standard parameters (min. max, disarmed, reverse). PCA9685 driver has one extra flag that will put the channel into Duty-Cycle output mode, if enabled. When Duty-Cycle mode is enabled for one channel:
Otherwise its output can be used to drive an ESC or servo, and PWM frequency is limited up to 400Hz. In the above image, I've configured the first channel into Duty-Cycle mode and made it outputs RC AUX1. RC AUX1 is mapped to one of the knob on my radio. The first channel is connected to an LED directly (as there is already a 220R resistor on PCA9685 module per channel). Then after the vehicle is armed, the LED brightness is directly mapped to the knob input. Final WordsIt is not recommended to mix the usage of this module and FC's built-in outputs onto the same function, like controlling each half of motors on a multirotor with different modules, as they has different output capacity and latency, which may cause troubles. The signal outputted from PCA9685 also has limited capacity, which can not be used to drive large RGB lights directly. |
8faefca
to
7ee7abc
Compare
@dagar Made a guide about how to use this driver on a PIXHAWK. Any revision comments on that? |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: https://discuss.px4.io/t/px4-community-q-a-may-24-2023/32263/1 |
src/drivers/pca9685_pwm_out/main.cpp
Outdated
if (param != PARAM_INVALID) { | ||
param_get(param, ¶m_pwm_freq); | ||
} else { | ||
PX4_ERR("param PCA9685_SCHD_HZ not found"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this say "param PCA9685_PWM_FREQ not found"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for reviewing :)
7ee7abc
to
6d522ea
Compare
Any chance to get this one merged? Seems there are still some users here @christianrauch Would you mind trying this branch? |
I sent a PR that only adds the parameter for setting |
I don't have this hardware, @christianrauch would you be interested in doing a quick review and regression test? |
Thanks for your feedback. PR title is adjusted according to the actual work done here. Hoping this may help someone later |
disarmed: { min: 800, max: 2200, default: 1000 } | ||
min: { min: 800, max: 1400, default: 1000 } | ||
max: { min: 1600, max: 2200, default: 2000 } | ||
failsafe: { min: 800, max: 2200 } | ||
disarmed: { min: 0, max: 4096, default: 1000 } | ||
min: { min: 0, max: 4096, default: 1100 } | ||
max: { min: 0, max: 4096, default: 1900 } | ||
failsafe: { min: 0, max: 4096 } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be the range 800...2200 to accommodate ESCs that are controlled by a PWM signal. Why change this to 0...4096?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it is capable to output in a totally different manner, according to:
PCA9685 driver has one extra flag that will put the channel into Duty-Cycle output mode, if enabled.
When Duty-Cycle mode is enabled for one channel:
- This channel of PCA9685 becomes an "analog output", which can be used to blink an LED, or drive a L298N based brushed motor, etc.
- min, max and disarmed value can be set between 0 and 4096, corresponding to no output (always low) and full output (always high)
- if all channels are put into Duty-Cycle mode, then the maximum PWM frequency of 1536 can be set
Otherwise its output can be used to drive an ESC or servo, and PWM frequency is limited up to 400Hz.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Still, could we keep the default values of 1000 / 2000?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Still, could we keep the default values of 1000 / 2000?
I have no strong opinion against that... @dagar any suggests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted back to normal mix/max values
Can you rebase this on the current main? I am getting the compiler error: You can also squash your "typo fix" commit as it changes one of your earlier commits in the same PR. |
It is already sync with latest main branch, and CI is passing as well. Those macros comes from https://github.com/PX4/PX4-Autopilot/pull/21528/files#diff-f2c1d45a2903a6c0b039644a1de99115b809e6ddf209b28f8c3afa67c34486f0 , I'd suggest doing |
This seems to work. But I am still confused about the parameter and their names. For |
Btw, I noticed that the PWM will still be continuously sent after the PX4 process finishes if it does not get disarmed before. Is there a way to have the PCA9685 timeout or similar so that it stops sending PWM signals if it does not get a new command via I2C in time? Can this be controlled via |
That makes sense. I really have bad taste on naming stuffs... The old parameter really affects both the update rate from PX4 and the PWM frequency inside PCA9685
No, it is only related to
No it is currently impossible due to the fact that the shutdown progress of px4 process is simply an But You may want to wrap the px4 process inside a script which will call another program once px4 exits, to disable the output of PCA9685, as a workaround |
- also supports Kconfig based clk source selection - adapt to recent changes of default PWM limits
…ty-cycle mode to advanced
6d522ea
to
05f72d5
Compare
I tested this on my lawnmower (using "main" branch), and it works great. I had a one-liner fix for the old code, just added a missing call to initialize output frequency to 50Hz. The new code works out of the box. Nice improvement showing actual frequency on "status". Old code accepted decimal port number ("-a 64"), new code works with hexes: "-a 0x40". |
This pull request has been mentioned on Discussion Forum for PX4, Pixhawk, QGroundControl, MAVSDK, MAVLink. There might be relevant details there: https://discuss.px4.io/t/parameters-that-dont-show-up-in-qgc/36019/3 |
This PR fixes
pca9685_pwm_out
. Now it should works again.Blocker #20594 got merged.
Fixed things:
Imporvements
pca9685
module, which is deprecated in 0e2df5aTest Coverage