External USB accessories in an AirSDK mission#

Starting with firmware 7.5.0, ANAFI Ai supports common USB devices plugged on the battery USB-C connector.

Supported devices include:

  • USB serial devices

  • Some Ethernet over USB adapters

  • Some USB sound cards

Drivers for these devices are automatically loaded.

You can test the support for your device using the developer shell on the drone, since the shell is run by user autopilot with the same rights as any AirSDK mission.


USB role switch is enabled on the drone. With a USB cable plugged in, the drone must be USB host to be allowed to take off. If the drone is USB device (e.g., connected to a computer) taking off is disabled.

When connected as a host, the LEDs on the battery will start flashing instead of staying solid green. The battery level is still indicated by the number of flashing LEDs.


The maximum current available on the USB-C port is limited to 500mA, if your device tries to draw more current the port will be disabled.

The following devices have been tested:

Network chipsets#

  • Realtek RTL8150/RTL8152/RTL8153

  • Microchip LAN78XX

  • ASIX AX88XX / AX88178A / AX88179

  • CDC Ethernet



  • Corechip SR9700/SR9800 & LAN75XX/LAN95XX

  • Prolific PL-2301/2302/25A1/27A1

USB audio#

  • Linux USB audio drivers with ALSA support

When an audio device is plugged on the drone you can:

  • Use libasound in your C or C++ mission code

  • Using the developer shell run aplay <file.wav> to play a PCM file to the audio output

  • Using the developer shell run arecord <file.wav> to record a PCM file from the audio input

Serial devices#

  • FTDI based devices (Arduino)

  • Generic Serial driver (some ESP32 boards)


Network chipsets#

Trendnet TUC-ETG USB-C (Type-C) to Gigabit Ethernet Adapter

When connected to the drone, a new network interface will appear.

Result of an ip addr command from the drone shell:

$ ip addr

9: eth0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
 link/ether 00:e0:4c:69:f3:13 brd ff:ff:ff:ff:ff:ff

By default, the system will check for a DHCP server in order to get an IP address.

If after 5 seconds the system has not received an IP address from an external DHCP server, the system starts its own DHCP server in order to provide Ethernet connectivity.

10: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 3c:8c:f8:f6:a6:0b brd ff:ff:ff:ff:ff:ff
altname enp0s31f6
inet scope global eth0
   valid_lft forever preferred_lft forever
inet6 fe80::3e8c:feff:fef6:a60b/64 scope link
   valid_lft forever preferred_lft forever

In this case, the first Ethernet interface will have an addressing range of

Serial devices#

All boards based on a FTDI USB/Serial converter, or any generic USB/Serial converter are compatible.

By default, the drone system will recognize the board and create an /dev/ttyACM0 device.

[ 894.120218] hub 2-0:1.0: USB hub found
[ 894.120247] hub 2-0:1.0: 1 port detected
[ 906.964866] usb 1-&: new full-speed USB device number 2 using xhci-hcd
[ 907.116443] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

The autopilot user has read/write access to the device. Any mission can then open this device and read/write data as it would do on any standard Linux computer.


Remember that multiple missions cannot access the same serial device concurrently.

Here is a simple C code snippet to push “Hello, World!n” on the ttyACM0 device:

 int fd = 0;
 bool file_opened = false;
 char obuf[256];

 /* Loop until the device can be opened */
 while (!file_opened) {
    fd = open("/dev/ttyACM0", O_RDWR | O_NONBLOCK);
    if (fd < 1) {
        ULOG_ERRNO("cannot open /dev/ttyACM0", errno);
    } else {
        file_opened = true;

/* Set tty in raw mode */
if (tcgetattr(fd, &tc) == 0) {
      tcsetattr(fd, TCANOW, &tc);

/* Generate the message to send */
snprintf(obuf, sizeof(obuf), "%s\n", "Hello, World!");

/* Write the message to the serial device */
res = write(fd, obuf, strlen(obuf));
if (res < 0) {
    ULOG_ERRNO("write", errno);