Download logs from uart

Hello guys, I’m new to ardupilot, I need to upload logs via uart. I have already searched half the Internet, I did not find anything, maybe they will prompt me here. Logs need to be downloaded not through qgroundcontrol and others, but through a regular serial port as a sequence of bytes. Is this possible at all?

No, MAVlink / MAVftp is the only option, there’s no way to “dump DF log xx to serial port x”. (Without programming)
Those methods not require the GCS you mentioned, but the protocol.
What do you need it for?

Yes, I understand the need to use Mavlink/MavFTP. I don’t understand what command I can unload the logs from the serial port. And I also don’t understand if there is an implementation of MAVFTP in python.

You can look at the implementation in MAVProxy.

please don’t use MAVFTP for log download.
We are using MAVLINK for log log donwload. You can look at Mavproxy implementation to do so, and implement your own donwloader MAVProxy/mavproxy_log.py at master · ArduPilot/MAVProxy · GitHub
The sequence is quite simple : ask the LOG_ENTRY you want to get log number and size. Ask the autopilot each block of the log.
Be aware that log donwloading through uart will be slow as limited by the uart bandwidth. To max up the donwload speed, disable the streamrate before donwloading, set a hight baudraute : over 921600 baud and set the CTS/RTS line.

Best option is the usb port where you should be able to reach at least 200kb/s easily

Thank you very much for your reply. I tried to implement what you said in python, but my speed is catastrophically low. Even with a baudrate of 921600. 1 megabyte in 5 minutes. In addition, unloading occurs incorrectly, sometimes the “Assert” error crashes. Maybe you can advise me on the code?

master.mav.log_request_list_send(master.target_system, master.target_component, 0, 0xffff)
logs = []
while True:
m = master.recv_match(blocking=True, type=‘LOG_ENTRY’, timeout=1)
print(m)
if m is None:
master.mav.log_request_list_send(master.target_system, master.target_component, 0, 0xffff)
continue
info(f’ received {len(logs)} log entries [{len(logs)*100//(m.num_logs+1):d}%]’, end=’\r’, flush=True)
logs.append(m)
if m.id == m.last_log_num:
break
info(f’\033[2K+ found {len(logs)} log entries’)

print(logs)

for log in logs:
    logfn = path.join('/root/TestTCPServer/LOGS', f'log_test_{log.id}.log')
    logdesc = f'{log.id} ({log.size/1024./1024:.2f} MiB)'
    if path.exists(logfn):
        info(f'- log {log.id} already downloaded, 1skipping')
        continue
    elif log.size == 0:
        info(f'- log {log.id} is empty, skipping')
        continue
    ofs = 0
    master.mav.log_request_data_send(master.target_system, master.target_component,
                                     log.id, ofs, log.size - ofs)
    try:
        with open(logfn, 'wb') as f:
            while ofs < log.size:
                info(f'\033[2K  downloading log {logdesc} [{ofs*100//log.size:d}%]', end='\r', flush=True)
                m = master.recv_match(blocking=True, type='LOG_DATA', timeout = 1)
                if m is None:
                    master.mav.log_request_data_send(master.target_system, master.target_component,
                                                     log.id, ofs, log.size - ofs)
                    continue
                if m.id != log.id:
                    continue
                assert m.ofs == ofs
                ofs = m.ofs + m.count
                f.write(bytes(m.data[:m.count]))
            info(f'\033[2K+ downloaded log {logdesc}')
    except KeyboardInterrupt:
        info(f'\r\033[2K- cancelled download of log {logdesc}')
        unlink(logfn)
        master.mav.log_request_end_send(master.target_system, master.target_component)
        if input('Quit? [yN] ') == 'y':
            break
        else:
            info('\033[A\033[M', end='', flush=True)
1 Like

am I facing the same issue? Arducopter 4.2.2

Are you able to solve that assertion error issue?