# Sending custom MAVLink commands with QGC

**URL:** <https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070>\
**Category:** QGroundControl\
**Tags:** guide, surface-controller\
**Created:** [June 6, 2024, 2:02am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070 "2024-06-06T02:02:32Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [June 6, 2024, 2:02am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/1 "2024-06-06T02:02:32Z")

</div>

Hi everyone,

I’ve recently unearthed some little-known functionality in QGroundControl that allows configuring custom [MAVLink commands](http://mavlink.io/en/messages/common.html#mav_commands) to be sent to the vehicle, using either on-screen or joystick buttons! 😃

While ArduSub comes with a number of [joystick button functions](https://docs.bluerobotics.com/ardusub-zola/software/autopilot/ArduSub-4.1/developers/parameters/#btnn-function-function-for-button) built in, this can augment that, and also allows functionalities like controlling relays and setting PWM output values on other vehicle firmwares (like ArduRover on the BlueBoat!).

## Fly View Actions (On-Screen Buttons)

 ![QGC-fly-view-actions](https://us1.discourse-cdn.com/flex019/uploads/bluerobotics/original/2X/c/cd5f19ee530102eda6185a9d19744de76f4c6706.jpeg)

1. Create [an actions file](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/custom_actions/custom_actions.html#custom-actions-file), with the MAVLink commands you want to be able to send:  
`~/Documents/QGroundControl/CustomActions/FlyViewActions.json`:

2. Enable Custom Actions in QGC’s Application Settings (access via the top left corner)

3. Select the actions file from where you saved it  

4. Access the actions when in Fly View, by clicking the “Action” button in the left sidebar, and pressing the relevant action button(s) in the popup at the bottom of the screen

## Joystick Button Functions

The process and syntax for this is changing from the existing stable releases, so there are two sets of instructions depending on which QGroundControl version you’re running.

### QGC \< 4.5

> **Instructions for existing stable versions**
>
> 1. Create a `JoystickMavCommands.json` file:
> - The filename is hardcoded in QGC, so must match **exactly**
> 
> ```json
> {
> "comment": "Joystick MAV commands",
> "version": 1,
> "commands": [
> {
> "id": 181,
> "name": "Relay1 ON",
> "param1": 0.0,
> "param2": 1.0
> },
> {
> "id": 181,
> "name": "Relay1 OFF",
> "param1": 0.0,
> "param2": 0.0
> }
> ]
> }
> 
> ```
> 
> 2. Save it where your QGroundControl instance gets run from
> - In Windows this is inside the folder where you installed it
> - e.g. `C:\\Program Files\QGroundControl\JoystickMavCommands.json`
> 
> - In MacOS this seems to be the root directory (`/`), which is read-only
> - This can be worked around by saving it in a memorable location (e.g. `~/Documents/QGroundControl/CustomActions/JoystickMavCommands.json`), and then running QGC from in that folder via the Terminal:
> 
> ```sh
> % cd ~/Documents/QGroundControl/CustomActions/
> % /Applications/QGroundControl.app/Contents/MacOS/QGroundControl
> 
> ```
> 
> 3. Configure your joystick buttons via the Vehicle Setup options
> - You’ll need to scroll to the bottom of the actions dropdown to find your custom options  
> ![QGC-4.3-custom-joystick-mavlink-commands](https://us1.discourse-cdn.com/flex019/uploads/bluerobotics/original/2X/e/ed53cf9c3d24be218341ef2f2ee886841842c3f9.png)

### QGC \>= 4.5

> **Instructions for current development and future stable releases**
>
> 1. Create [an actions file](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/custom_actions/custom_actions.html#custom-actions-file), with the MAVLink commands you want to be able to send:  
> `~/Documents/QGroundControl/CustomActions/JoystickCustomActions.json`:
> 
> 2. Select the actions file from where you saved it, via the Application Settings in the top left corner  
> 
> 3. Access the actions when in Fly View, by clicking the “Action” button in the left sidebar, and pressing the relevant action button(s) in the popup at the bottom of the screen
> 
> 4. Configure your joystick buttons via the Vehicle Setup options

## Relay Configuration

While the servo PWM commands typically provide direct control over flight controller servo output pins, the relay output pins are selectable from the available servo output pins, which needs to be set up in the autopilot parameters before the relay can be used.

> 💡 When using a [Navigator Flight Controller](https://bluerobotics.com/store/comm-control-power/control/navigator/) it is possible to see the state of the relay pins as 0/1 in the `SERVO_OUTPUT_RAW` MAVlink messages (e.g. via the MAVLink Inspector).

### ArduSub (BlueROV2)

1. Allow the relevant servo pin to be used as a relay output, by setting its [`SERVOn_FUNCTION`](https://docs.bluerobotics.com/ardusub-zola/software/autopilot/ArduSub-4.1/developers/parameters/#servon-function) parameter to `Disabled (0)`
  - “n” is the pin number being configured (e.g. `9`)

2. Configure the relay number with the desired servo output pin, using the [`RELAY_PIN`](https://docs.bluerobotics.com/ardusub-zola/software/autopilot/ArduSub-4.1/developers/parameters/#relay-pin) / `RELAY_PIN2/3/4/5/6` parameter
3. Configure the joystick button function(s) as desired
  - ArduSub [provides built in](https://docs.bluerobotics.com/ardusub-zola/software/autopilot/ArduSub-4.1/developers/parameters/#btnn-parameters) `relay_n_*` functions for controlling relays 1-4
  - The [custom joystick button functions](#joystick-button-functions-2) can be configured to allow control over relays 5 and 6, using the [`DO_SET_RELAY (181)`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_RELAY) and/or [`DO_REPEAT_RELAY (182)`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_REPEAT_RELAY) MAVLink commands
    - Note the relay numbering in the MAVLink message is 0-indexed, so relay 5 is index 4

### ArduRover (BlueBoat)

1. Allow the relevant servo pin to be used as a relay output, by setting its `SERVOn_FUNCTION` parameter to `GPIO (-1)`
  - “n” is the pin number being configured (e.g. `9`)

2. Allow the relay number to be used as a servo output relay, by setting the `RELAYn_FUNCTION` to `Relay (1)`, and rebooting the autopilot
  - “n” is the relay number being configured (e.g. `1`)

3. Connect the relay number to its servo output pin via the [`RELAYn_PIN`](https://ardupilot.org/rover/docs/parameters.html#relayn-pin) parameter
4. Set up [custom joystick button functions](#joystick-button-functions-2) using the [`DO_SET_RELAY (181)`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_RELAY) and/or [`DO_REPEAT_RELAY (182)`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_REPEAT_RELAY) MAVLink commands, and configure the joystick button function(s) as desired

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [June 6, 2024, 2:03am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/2 "2024-06-06T02:03:03Z")

</div>



---

<div class="post-metadata">

**Author:** ![CA\_BlueBoat](https://avatars.discourse-cdn.com/v4/letter/c/9d8465/32.png) [@CA\_BlueBoat](https://discuss.bluerobotics.com/u/CA_BlueBoat)\
**Post date:** [June 7, 2024, 3:55pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/3 "2024-06-07T15:55:55Z")

</div>

This is great!

I would like to use a few joystick buttons to change the “WPNAV\_SPEED” parameter during an autonomous mission with the Blueboat (either incrementally increase/decrease speed or slow medium fast on 3 buttons).  
Looking through the Mavlink message lists, I cannot find anything that would change that parameter. do you have any advice?

Cheers

---

<div class="post-metadata">

**Author:** ![CA\_BlueBoat](https://avatars.discourse-cdn.com/v4/letter/c/9d8465/32.png) [@CA\_BlueBoat](https://discuss.bluerobotics.com/u/CA_BlueBoat)\
**Post date:** [June 7, 2024, 4:32pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/4 "2024-06-07T16:32:43Z")

</div>

I found the [`MAV_CMD_DO_CHANGE_SPEED`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) message. Would something like this work:

```json
  {
    "label": "Slow Speed",
    "description": "Travel at 1 m/s",
    "mavCmd": 178,
    "param1": 1,
    "param2": 1,
    "param3": -1
  },
  {
    "label": "Medium Speed",
    "description": "Travel at 2 m/s",
    "mavCmd": 178,
    "param1": 1,
    "param2": 2,
    "param3": -1
  },
  {
    "label": "Fast Speed",
    "description": "Travel at 3 m/s",
    "mavCmd": 178,
    "param1": 1,
    "param2": 3,
    "param3": -1
  }

```

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [June 8, 2024, 12:54pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/5 "2024-06-08T12:54:26Z")

</div>

> [@CA\_BlueBoat](#):
>
> This is great!

Agreed! Definitely useful functionality to have, and to know about 🙂

> [@CA\_BlueBoat](#):
>
> … either incrementally increase/decrease speed or slow medium fast on 3 buttons

Incremental controls require something to do the calculation with knowledge of the current state, and that generally needs to be built into the autopilot firmware (like we’ve done with the `servo_n_inc/dec` joystick button functions in ArduSub).

If there’s an appropriate MAVLink command then the three buttons approach should work with the steps I’ve outlined in this post 🙂

> [@CA\_BlueBoat](#):
>
> I found the [`MAV_CMD_DO_CHANGE_SPEED`](http://mavlink.io/en/messages/common.html#MAV_CMD_DO_CHANGE_SPEED) message. Would something like this work:

I believe that should work, at least until there’s a waypoint that sets a new speed target, or you go out of an autonomous control mode that supports speed regulation.

Note that for the joystick button functions, depending on your QGC version you may need to use the older format for specifying the MAVLink commands.

* * *

By the way, I’ve edited your comment to include a link to the MAVLink message in question, and also formatted your file snippet example as a pre-formatted text (/code) block, so the spacing is maintained. The [How to Use the Forums](https://discuss.bluerobotics.com/t/how-to-use-the-blue-robotics-forums-please-read/10521) post includes a section on what’s available for content formatting 🙂

---

<div class="post-metadata">

**Author:** ![clyde](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/clyde/32/8563_2.png) [@clyde](https://discuss.bluerobotics.com/u/clyde)\
**Post date:** [June 8, 2024, 8:55pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/6 "2024-06-08T20:55:06Z")

</div>

In ArduSub 4.5 BETA you can use joystick buttons to trigger actions in Lua scripts. You could write a Lua script that waits for a button press and then changes the WPNAV\_SPEED parameter.

Here is a script showing how to access the joystick from inside Lua:

> <https://github.com/ArduPilot/ardupilot/blob/Sub-4.5/libraries/AP_Scripting/examples/test_script_button.lua>

Here is a simple Lua script that changes a parameter:

> <https://github.com/ArduPilot/ardupilot/blob/Sub-4.5/libraries/AP_Scripting/examples/AHRS_switch.lua>

Lua is pretty powerful, and the API is improving rapidly.

/Clyde

---

<div class="post-metadata">

**Author:** ![jdragano](https://avatars.discourse-cdn.com/v4/letter/j/97f17d/32.png) [@jdragano](https://discuss.bluerobotics.com/u/jdragano)\
**Post date:** [July 12, 2024, 9:52pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/7 "2024-07-12T21:52:10Z")

</div>

So as of today, I’m unable to recreate your advised method of creating Joystick button functions. Can you confirm that you’re still able to do so please as well as what version of QGC you’re running? I’m happy to downgrade QGC if needed at this point…

I’m running on Linux for reference. I’m fully able to create a FlyViewActions.json file and have the actions show up, but can’t recreate any part of your Joystick button functions.

---

<div class="post-metadata">

**Author:** ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)\
**Post date:** [July 13, 2024, 7:05am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/8 "2024-07-13T07:05:29Z")

</div>

Hi @jdragano -  
I’d suggest you review @EliotBR 's post again, and focus on the above or below QGC version 4.5 instructions depending on what you’re using! You do need to click the little arrow to expand these details…

---

<div class="post-metadata">

**Author:** ![jdragano](https://avatars.discourse-cdn.com/v4/letter/j/97f17d/32.png) [@jdragano](https://discuss.bluerobotics.com/u/jdragano)\
**Post date:** [July 15, 2024, 1:20pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/9 "2024-07-15T13:20:06Z")

</div>

Hi @tony-white while I appreciate that, I did in fact already attempt that after ‘clicking the little arrows to expand these details’ - had I not I wouldn’t be posting here, asking for help.

If anyone has **constructive** advice it would deeply appreciated…

---

<div class="post-metadata">

**Author:** ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)\
**Post date:** [July 15, 2024, 9:11pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/10 "2024-07-15T21:11:57Z")

</div>

Apologies @jdragano -  
I only mentioned the sections under the arrows because it seemed you were unsure which instructions to follow in terms of your QGC version - both new and old are supported.  
Have you not found the actions you added at the end of the list when configuring Joystick buttons?

 ![image](https://us1.discourse-cdn.com/flex019/uploads/bluerobotics/original/2X/2/234dd434bbd5fa1a851fa08070eacc391730cc83.png)

---

<div class="post-metadata">

**Author:** ![jdragano](https://avatars.discourse-cdn.com/v4/letter/j/97f17d/32.png) [@jdragano](https://discuss.bluerobotics.com/u/jdragano)\
**Post date:** [July 16, 2024, 1:24pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/11 "2024-07-16T13:24:13Z")

</div>

No worries - apologies on my end as well.

But that’s correct, I don’t see the custom actions at the end of the list when configuring Joystick buttons (I do however get On-Screen Buttons with the FlyViewActions.json). I’m using QGC V4.4, running Ubuntu. I put it under ~/Documents/QGroundControl/CustomActions/  
Here’s a more in detail look at what I have working/have tried for the joystick commands:

1. I tried saving JoystickMavCommands.json (exactly as given by Eliot) under ~/Documents/QGroundControl/CustomActions/ and running (a) the QGC.appimage from its location in Downloads **while in the downloads directory** and (b) navigating first to ~/Documents/QGroundControl/CustomActions/ and running the home/Downloads/QGC.appimage from there [essentially the Mac instructions bullet point]
2. Ubuntu seems to point to a .config file directory where QGC is ran from, so I attempted to also stick the json in that ‘install folder’, but that didn’t seem to work either

---

<div class="post-metadata">

**Author:** ![erkamtb](https://avatars.discourse-cdn.com/v4/letter/e/3da27b/32.png) [@erkamtb](https://discuss.bluerobotics.com/u/erkamtb)\
**Post date:** [July 17, 2024, 2:22pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/13 "2024-07-17T14:22:14Z")

</div>

i couldn’t find QGC 4.5 or any above? on the github page there is just 4.4

Still I can’t find the 4.5 or above version of qgc. Where is it?

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [August 1, 2024, 6:46am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/14 "2024-08-01T06:46:43Z")

</div>

Hi @jdragano,

I didn’t test on Ubuntu (which is why I didn’t include explicit instructions for it), but it sounds like it might have a similar situation to MacOS in terms of how and where it looks for the file.

You could try adding the file to your root directory (which you didn’t mention trying), but if that doesn’t work then it’s likely easiest to install [a development release](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/releases/daily_builds.html), in which case you can follow the \>= 4.5 instructions, which allow you to just select where the file is in your filesystem from within QGC.

If you specifically need a stable build to work then you can try looking at QGC’s logs to see what kind of error(s) it’s giving about the custom actions, but determining the correct process for MacOS was a pain, and the Ubuntu one may be similarly annoying. You can of course wait until 4.5 is released as stable, but I’m not sure when that will be.

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [August 1, 2024, 6:53am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/15 "2024-08-01T06:53:50Z")

</div>

> [@erkamtb](#):
>
> I can’t find the 4.5 or above version of qgc. Where is it?

I mentioned in my original post that 4.5 is currently in development. There are daily build downloads [available here](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/releases/daily_builds.html), or if you want a specific time-point you can download the relevant Artifact from the GitHub Action for your operating system (e.g. [here](https://github.com/mavlink/qgroundcontrol/actions/workflows/windows.yml) are the recent Windows builds).

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [February 23, 2025, 10:52pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/17 "2025-02-23T22:52:28Z")

</div>

Noting that this (and generic HTTP requests and Javascript functions) are also available in Cockpit, through its [Custom Actions](https://blueos.cloud/cockpit/docs/latest/usage/advanced/#custom-actions) system 🙂

---

<div class="post-metadata">

**Author:** ![jobotics](https://avatars.discourse-cdn.com/v4/letter/j/8797f3/32.png) [@jobotics](https://discuss.bluerobotics.com/u/jobotics)\
**Post date:** [October 31, 2025, 10:18am UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/18 "2025-10-31T10:18:44Z")

</div>

Wow, that’s pretty cool and _almost_ what I’d need. What I’d actually want to do is to not press the buttons manually but to add such custom commands to be automatically executed during a waypoint mission. Is this at all possible in QGC? Or maybe in Mission Planner alternatively?

---

<div class="post-metadata">

**Author:** ![tony-white](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/tony-white/32/13297_2.png) [@tony-white](https://discuss.bluerobotics.com/u/tony-white)\
**Post date:** [October 31, 2025, 5:13pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/19 "2025-10-31T17:13:15Z")

</div>

Hi @jobotics -  
QGC does offer some [special waypoint types](https://docs.qgroundcontrol.com/Stable_V4.3/en/qgc-user-guide/plan_view/plan_view.html#mission_command_list) for actions, but your best bet for custom commands at waypoints is to do stuff with Lua scripts - not the ground control station software at all! See an example of how to do that [here](https://discuss.bluerobotics.com/t/controlling-external-devices-with-lua-scripts-on-ardurover-blueboat-winch/17134).

---

<div class="post-metadata">

**Author:** ![jobotics](https://avatars.discourse-cdn.com/v4/letter/j/8797f3/32.png) [@jobotics](https://discuss.bluerobotics.com/u/jobotics)\
**Post date:** [October 31, 2025, 9:54pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/20 "2025-10-31T21:54:31Z")

</div>

Thanks for that, I will try going the Lua script route, then.

---

<div class="post-metadata">

**Author:** ![EliotBR](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eliotbr/32/6937_2.png) [@EliotBR](https://discuss.bluerobotics.com/u/EliotBR)\
**Post date:** [November 1, 2025, 6:52pm UTC](https://discuss.bluerobotics.com/t/sending-custom-mavlink-commands-with-qgc/17070/21 "2025-11-01T18:52:03Z")

</div>

Hi @jobotics,

> [@jobotics](#):
>
> What I’d actually want to do is … to add such custom commands to be automatically executed during a waypoint mission. Is this at all possible in QGC?

QGC, Mission Planner, and soon Cockpit (as of 1.17) have support for including most (if not all) MAVLink commands in their mission planning functionality.\[1\]

In QGC you can expose the list of supported commands by clicking the dropdown next to the mission component’s name (e.g. “Waypoint ▾”), then changing its Category to “All Commands”, and choosing the command you want to send.

> [@tony-white](#):
>
> … your best bet for custom commands at waypoints is to do stuff with Lua scripts …

Tony’s point here is relevant if the things you want to do can not readily be accomplished with a sequence of existing MAVLink commands, or it’s awkward to do so (e.g. you have a series of commands you want to trigger at multiple different waypoints). When that’s the case, you can write your own fully custom functionality as a Lua script, and then either trigger that via a command, or have the script monitor the relevant vehicle states in a loop, and run the code you want when certain conditions are met.

* * *

1. Note that not every autopilot has support/handling for every command (here’s [the ArduSub list](https://ardupilot.org/sub/docs/ArduSub_MAVLink_Messages.html#incoming-commands), for example), but they should typically support at least the most common vehicle control ones.
