Home        Store        Learn        Blog

Pymavlink- heartbeat

Hi,

from pymavlink import mavutil
master = mavutil.mavlink_connection('udpin:192.168.2.1:14550')
master.wait_heartbeat()
print("hi")

I am trying to set communication but the lines below “master.wait_heartbeat()” don’t work. probably there is a problem about “master.wait_heartbeat()”. I set up the ip addresses as in the guide. After running python script, communication lost on QGroundControl as it’s supposed to be.
I don’t have any idea about the issue.
Thanks in advance.

Hi,

Check our example Run pyMavlink on the surface computer.

Thanks for your reply. I’ve tried the example and it worked, I got the output. Also, I have tried the example below. But motors didn’t run.

    from pymavlink import mavutil

    # Create the connection
    master = mavutil.mavlink_connection('udpin:192.168.2.1:14550')
    # Wait a heartbeat before sending commands
    master.wait_heartbeat()

    def set_rc_channel_pwm(channel_id, pwm=1500):
        """ Set RC channel pwm value
        Args:
            channel_id (TYPE): Channel ID
            pwm (int, optional): Channel pwm value 1100-1900
        """
        if channel_id < 1 or channel_id > 18:
            print("Channel does not exist.")
            return

        rc_channel_values = [65535 for _ in range(18)]
        rc_channel_values[channel_id - 1] = pwm
        master.mav.rc_channels_override_send(
            master.target_system,                # target_system
            master.target_component,             # target_component
            *rc_channel_values)                  # RC channel list, in microseconds.

    set_rc_channel_pwm(5, 1600)

From the comment of the example:

"""
Example of how to use RC_CHANNEL_OVERRIDE messages to force input channels
in Ardupilot. These effectively replace the input channels (from joystick
or radio), NOT the output channels going to thrusters and servos.
"""

It’ll work with light and camera, as in the same example code, the motor will not work since you need to disable failsafes or ARM the vehicle.

Check the Arm/Disarm the vehicle example, that’s before the Send RC (Joystick) example for this reason.

from pymavlink import mavutil

# Create the connection
master = mavutil.mavlink_connection('udpin:192.168.2.1:14550')
# Wait a heartbeat before sending commands
master.wait_heartbeat()

master.arducopter_arm()

def set_rc_channel_pwm(channel_id, pwm=1500):
    
    if channel_id < 1 or channel_id > 18:
        print("Channel does not exist.")
        return

    rc_channel_values = [65535 for _ in range(18)]
    rc_channel_values[channel_id - 1] = pwm
    master.mav.rc_channels_override_send(
        master.target_system,                # target_system
        master.target_component,             # target_component
        *rc_channel_values)                  # RC channel list, in microseconds.
set_rc_channel_pwm(5, 1600)

I tried the code above. But after the “arm” command, the motor turned at max speed consistently.

Hi,

Are you running in manual or stabilize mode ? If the ROV is running with a mode that has any kind of stabilization control, it’ll try to compensate any error, and since it’s outside the water, the action will not result in any attitude change, the error will increase and also the thruster output.
What was your expected behavior ?

Hi,
Thanks Patrick. I understood that in stabilize mode motors try to protect the vehicle’s attitude and yesterday I tried it outside the water.

But today, I set up mode as manual. The motor is in the water bucket. I just want the motor will turn according to given values and I don’t expect any behavior when not to given PWM value. But despite I changed the mode as manual, the motor is turning consistently after arm command.

from pymavlink import mavutil

# Create the connection
master = mavutil.mavlink_connection('udpin:192.168.2.1:14550')
# Wait a heartbeat before sending commands
master.wait_heartbeat()
mode = 'MANUAL'
if mode not in master.mode_mapping():
    print('Unknown mode : {}'.format(mode))
    print('Try:', list(master.mode_mapping().keys()))
    sys.exit(1)

mode_id = master.mode_mapping()[mode]

master.set_mode(mode_id) 

master.arducopter_arm()
"""
def set_rc_channel_pwm(channel_id, pwm=1500):
    
    if channel_id < 1 or channel_id > 18:
        print("Channel does not exist.")
        return

    rc_channel_values = [65535 for _ in range(18)]
    rc_channel_values[channel_id - 1] = pwm
    master.mav.rc_channels_override_send(
        master.target_system,                # target_system
        master.target_component,             # target_component
        *rc_channel_values)                  # RC channel list, in microseconds.
count = 0
while count <= 1000:
    set_rc_channel_pwm(15, 1500)
    count += 1
    print(count)
    if count == 1001:
        master.arducopter_disarm()
 """

Hi @Sena,

What are you trying to accomplish?
Note that you are overriding the INPUT 15, not output.
You can set SERVO15_FUNCTION to RCIN_15 to have direct control of it via mavlink. Just note that you need to keep refreshing the value before the 3 seconds timeout kicks in and it resets to zero.

Hi,
Sometimes I get the error below. But sometimes it works. Therefore it is not stable.

Traceback (most recent call last):
File “pwm.py”, line 6, in
master.wait_heartbeat()
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7l.egg/pymavlink/mavutil.py”, line 386, in wait_heartbeat
return self.recv_match(type=‘HEARTBEAT’, blocking=blocking)
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7l.egg/pymavlink/mavutil.py”, line 347, in recv_match
m = self.recv_msg()
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7l.egg/pymavlink/mavutil.py”, line 310, in recv_msg
s = self.recv(n)
File “/usr/local/lib/python2.7/dist-packages/pymavlink-2.2.4-py2.7-linux-armv7l.egg/pymavlink/mavutil.py”, line 832, in recv
ret = self.port.read(n)
File “/usr/local/lib/python2.7/dist-packages/serial/serialposix.py”, line 501, in read
'device reports readiness to read but returned no data ’
serial.serialutil.SerialException: device reports readiness to read but returned no data (device disconnected or multiple access on port?)

from pymavlink import mavutil
master = mavutil.mavlink_connection(
            '/dev/ttyACM0',
            baud=115200)

master.wait_heartbeat()
mode = 'MANUAL'
if mode not in master.mode_mapping():
    print('Unknown mode : {}'.format(mode))
    print('Try:', list(master.mode_mapping().keys()))
    sys.exit(1)

mode_id = master.mode_mapping()[mode]

master.set_mode(mode_id)

master.arducopter_arm()

def set_rc_channel_pwm(channel_id, pwm=1500):

    if channel_id < 1 or channel_id > 9:
        print("Channel does not exist.")
        return

    rc_channel_values = [65535 for _ in range(9)]
    rc_channel_values[channel_id - 1] = pwm
    master.mav.rc_channels_override_send(
        master.target_system,             
        master.target_component,            
        *rc_channel_values)                 
count = 0
while count <= 1000:
    set_rc_channel_pwm(5, 1600)
    count += 1
    print(count)
    if count == 1001:
        master.arducopter_disarm()

Hi @Sena,

Did you make sure that there is no other software trying to use the serial port? IIRC “modemmanager” could cause that.
You should also update pymavlink, your version seems to be pretty old.

You can use the command try except.

Like this:

from pymavlink import mavutil
master = mavutil.mavlink_connection(
            '/dev/ttyACM0',
            baud=115200)
try:
    master.wait_heartbeat()
except:
    print("No Data!")

and most of the time the wait_heartbeat command is unnecessary.

Thanks. It is better now. I have another question. I want to make forward movement. But when i set the parameter as 5 the ROV goes down. I know from input table that it must go forward when it set up as 5. But it do not work properly.

1 Eyl 2020 Sal 09:35 tarihinde Enis Getmez via Blue Robotics Community Forums <bluerobotics@discoursemail.com> şunu yazdı:

Is your rov working properly in Stabilize mode?

Turns around itself

11 Eyl 2020 Cum 15:58 tarihinde Willian Galvani via Blue Robotics Community Forums <bluerobotics@discoursemail.com> şunu yazdı:

Something is likely wrong on your motors setup. Check our instruction to setup the motor directions.
Note that this requires that the electrical connections are correct, too.

set_rc_channel_pwm(5,1700)

Hi, when I run the command above, motors don’t react. When I use while loop below motors start to work constantly but they stutter for about 0.2 seconds repeatedly. I’m not sure why this is happening, can you help me?

while 1:

set_rc_channel_pwm(5,1700)



@enis.getmez hi bro

You have a joystick attached.
That means QGC is also sending MANUAL_CONTROL messages with the joystick inputs, which is likely conflicting with your RC_CHANNELS_OVERRIDE.

Thank you for your reply. I tried what you suggested and now motors started to spin very fast, regardless of our low PWM signal. What can I do to fully gain control of the motors? The ESC’s we’re using are pre-programmed for pixhawk so that we can’t change PWM values. Last week, we ordered new ESC’s that Blue Robotics recommended for us, but they couldn’t make it out of the border to our country. :exploding_head:

Are you sending 1500 to stop?

When we send 1650 to go forward, it turns at full speed. In order to stop it we are forced to kill the power, because it doesn’t respond to our 1500.


image