# Controlling PWM outputs with Python/Mavlink2Rest

**URL:** <https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154>\
**Category:** Blue Robotics Software\
**Created:** [January 26, 2025, 4:05am UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154 "2025-01-26T04:05:25Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![EivindV](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eivindv/32/14722_2.png) [@EivindV](https://discuss.bluerobotics.com/u/EivindV)\
**Post date:** [January 26, 2025, 4:05am UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/1 "2025-01-26T04:05:25Z")

</div>

Hi.

I’m new to BlueOS and software development for this.  
I would like to develop my own software for controlling the ROV.  
Currently I’m able to read status (heading, roll, depth etc) from the ROV by using a Python program and Mavlink2Rest interface.  
But I’m struggeling with controlling the PWM outputs from the Navigator Flight Controller.

Is there anyone that has a very basic Python program that can control these PWM outputs ?

Best regards  
Eivind Vigsnes  
Norway

---

<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:** [January 28, 2025, 1:39am UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/2 "2025-01-28T01:39:14Z")

</div>

Hi @EivindV, welcome to the forum 🙂

> [@EivindV](#):
>
> But I’m struggeling with controlling the PWM outputs from the Navigator Flight Controller.

Which outputs are you trying to control? There are different MAVLink messages that are relevant for different output types (e.g. [`MANUAL_CONTROL`](https://mavlink.io/en/messages/common.html#MANUAL_CONTROL) or [`RC_CHANNELS_OVERRIDE`](https://mavlink.io/en/messages/common.html#RC_CHANNELS_OVERRIDE) for controlling the vehicle motion, and [`MAV_CMD_DO_SET_SERVO`](https://mavlink.io/en/messages/common.html#MAV_CMD_DO_SET_SERVO) for auxiliary control of vehicle peripherals (like lights and grippers and the like)).

We have some old [Pymavlink examples](https://www.ardusub.com/developers/pymavlink.html), which you could potentially adjust to using with the MAVLink2REST API instead…

---

<div class="post-metadata">

**Author:** ![EivindV](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eivindv/32/14722_2.png) [@EivindV](https://discuss.bluerobotics.com/u/EivindV)\
**Post date:** [January 28, 2025, 8:45pm UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/3 "2025-01-28T20:45:38Z")

</div>

Thanks for guiding me in the right direction.  
I don’t need to use Mavlink2Rest , if it works with Pymavlink it would be great.

I had a look at the examples.  
**" Run pyMavlink on the surface computer"**  
With this example I’m receiving a stream with messages.

**“Send Message to QGroundControl”**  
This is working OK.

**" Set Servo PWM"**  
When I’m running this , there is no error messages.  
But there is no change on the PWM signal.  
I’m measuring the PWM signal with a oscilloscope, and the signal is constant on 1500 uS pulsewidth.  
The QGroundControl is not running.

Any advice how I should proceeed ?

Thanks

---

<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:** [January 30, 2025, 12:50pm UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/4 "2025-01-30T12:50:43Z")

</div>

> [@EivindV](#):
>
> **" Set Servo PWM"**  
> When I’m running this , there is no error messages.  
> But there is no change on the PWM signal.  
> I’m measuring the PWM signal with a oscilloscope, and the signal is constant on 1500 uS pulsewidth.

Are you running the example as-is? It was written for controlling the AUX servo outputs of a Pixhawk, skipping over the MAIN ones. The Navigator doesn’t have such a distinction, so you might just be controlling servo 9 instead of servo 1.

Note that if you are _trying_ to control output 1, that will not work using `set_servo` commands if it is assigned as a motor, because the motion components of the autopilot generally need to be controlled using vehicle motion commands.

You should be able to check what’s changing using the `SERVO_OUTPUT_RAW` message values, which you can receive in your code or view in the BlueOS MAVLink inspector 🙂

I wrote [this more complete example](https://gist.github.com/ES-Alexander/ee1dd479dd728b7cef1bf936f9114e71) a while ago, which may be useful for a sense of how to string different functionalities together 🙂

---

<div class="post-metadata">

**Author:** ![EivindV](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eivindv/32/14722_2.png) [@EivindV](https://discuss.bluerobotics.com/u/EivindV)\
**Post date:** [January 30, 2025, 6:52pm UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/5 "2025-01-30T18:52:04Z")

</div>

Thanks for clarifying this.  
Yes, you are correct, I was controlling servo 9.  
This helped me a lot 🙂

A second question:

I have this in the code:

```auto
# Create the connection
master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')

```

Here it’s using IP `0.0.0.0`, but my Navigator/BlueOS is running on `192.168.10.158`

I guess my program is receiving UDP messages from the Navigator/BlueOs, and the know which IP it should communicate with.  
But what if I have another Navigator/BlueOS connected to the network?  
How can I distinguish between them in the software?

---

<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:** [January 31, 2025, 8:36am UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/6 "2025-01-31T08:36:33Z")

</div>

> [@EivindV](#):
>
> I guess my program is receiving UDP messages from the Navigator/BlueOs, and the know which IP it should communicate with.

That’s using the “GCS Client Link” [MAVLink Endpoint](https://blueos.cloud/docs/stable/usage/advanced/#mavlink-endpoints), at the port that control station software like QGroundControl expects to broadcast to and receive communications through.

> [@EivindV](#):
>
> But what if I have another Navigator/BlueOS connected to the network?  
> How can I distinguish between them in the software?

If you’re using Pymavlink then I’d recommend setting up a custom endpoint for that\[1\] in each BlueOS device, in which case you can use different ports for those endpoints, and your Pymavlink code can be set to reflect that.

Alternatively, if you’re connecting with MAVLink2REST (or using a UDP server MAVLink Endpoint) you can specify the IP address of the BlueOS device you’re connecting to.

* * *

1. See [the example in the docs](https://blueos.cloud/docs/stable/usage/advanced/#mavlink-endpoints:~:text=e.g.%20some%20users%20may%20wish%20to%20set%20up%20a%20UDP%20endpoint%20for%20connecting%20to%20with%20Pymavlink%20from%20the%20surface%3A) - you’ll need [Pirate Mode](https://blueos.cloud/docs/stable/usage/advanced/#pirate-mode) enabled to see the MAVlink Endpoints page in the sidebar

---

<div class="post-metadata">

**Author:** ![EivindV](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.bluerobotics.com/eivindv/32/14722_2.png) [@EivindV](https://discuss.bluerobotics.com/u/EivindV)\
**Post date:** [February 19, 2025, 12:10am UTC](https://discuss.bluerobotics.com/t/controlling-pwm-outputs-with-python-mavlink2rest/19154/7 "2025-02-19T00:10:39Z")

</div>

I finaly got a chance to test this.  
It’s working fine.  
Thanks for good help.
