Why is my Pixhawk 4 refusing to communicate over USB serial?

242 views Asked by At

I'm developing a camera interface for my drone running PX4 on a Pixhawk 4. I have connected my development machine to the Pixhawk via the USB port on the side. Currently my code is this:

import time
from pymavlink import mavutil


def ping(device):
    msg = None
    ping_id = 0

    while msg is None:
        print(f'Ping {ping_id}')
        device.mav.ping_send(int((time.time() - boot_time) * 1e6), ping_id, 0, 0)
        ping_id += 1

        msg = device.recv_match(type='PING',
                                blocking=True,
                                timeout=5.0,
                                condition=f'PING.target_system=={device.source_system} '
                                          f'and PING.target_component=={device.source_component}')

    print(f'Pong {msg.seq} {msg.get_srcSystem()}/{msg.get_srcComponent()} -> {msg.target_system}/{msg.target_component}')


def main():
    print('Looking for serial ports')
    serial_list = mavutil.auto_detect_serial(preferred_list=['*FTDI*',
                                                             "*Arduino_Mega_2560*", "*3D_Robotics*", "*USB_to_UART*",
                                                             '*PX4*', '*FMU*', "*Gumstix*"])

    if len(serial_list) == 0:
        return

    fc = mavutil.mavlink_connection(serial_list[0].device,
                                    baud=115200,
                                    source_system=mavutil.mavlink.MAV_TYPE_CAMERA,
                                    source_component=mavutil.mavlink.MAV_COMP_ID_CAMERA
                                    )
    print(f'Serial port "{serial_list[0].device}" open')
    fc.wait_heartbeat()
    print('Heartbeat found')
    ping(fc)


if __name__ == '__main__':
    boot_time = time.time()
    main()

If I run this after connecting the Pixhawk to the computer, it hangs waiting for the hearbeat.

However if I run QGroundControl first, let it connect via serial and then close QGroundControl, my code runs fine and I get the heartbeat and the PING message exactly as expected. And it stays happy until the next time I reboot the Pixhawk.

I'm using MAVLink 2.0 and the "common" dialect, although other dialects seem to behave the same.

After successful communication I can send a reboot command:

fc.mav.command_long_send(fc.target_system, fc.target_component,
                         mavutil.mavlink.MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN,
                         0,
                         1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
                         )

And the connection hangs again once it has rebooted.

I've looked at the verbose logs and source code of QGroundControl, but nothing leaps out at me about what it is doing that my pymavlink code isn't. It does assert the DTR line, but I've tried that in my code but it doesn't help.

0

There are 0 answers