How Raspberry Pi Zero got Ardupilot, hopefully flies

Well, this is a story about how Raspberry Pi Zero got Ardupilot, hopefully flies away and gets back safely ūüôā

I wanted to make this a professional looking PCB, with smd components, everything crammed on it, but for that, I might as well get a PXFMINI. I changed my thinking, and built a flight FC to be cheap, available, breadboard and DIY friendly, but still look professional. That’s why I use ready made breakout modules with sensors and had PCBs made by OshPark.

I bought an APM from 3drobotics a long time ago (well, at least technology-wise, it was a long time ago. 3 years maybe ūüôā ), and I really love it, still. I don’t really use all the features, but it’s nice to know they are there. I also really like¬†like the opensource community behing it.

So, yeah, after a couple of years, it was time to upgrade. I wanted to get the Pixhawk, but then dad got me the tiny Intel Edison, and some time after that, the PiZero was announced. Needless to say,¬†I did not get the Pixhawk. I didn’t want to use the Edison for testing, so I got me a PiZero from Pimoroni, and started googling on how to do it. I came across this website, from this guy. This made thing SOOOOOO much easier. Thanks Patrick!


Getting stuff (everything I used here)

Believe it or not, this is how I work… First I get an idea, then I buy the parts and finally figure out if it could work or not. Then buy proper stuff. I have lots of stuff haha ūüėÄ I work on impulse ūüėÄ

Bare minimum needed:

  • PiZero (or any other Pi)
  • MPU-9250, 9-Axis Gyro+Accel+Magn
  • MS5611 barometric sensor
  • two sided proto PCB, if you dont want to test on ye’olde proto board
  • some wire and pins, female and male

Optional stuff, very useful

  • APM Power module¬†to power the Zero
  • PCA9685 16 channel i2c pwm servo driver¬†(already built module or the IC alone)
  • UBLOX gps module (be careful with chinese clones, some have the wrong flash IC, won’t save settings)
  • ADS1115 to provide voltage and amp measuring (already built module or the IC alone)
  • OLED¬†ssd1306 I2C display (OR green, blue, amber leds with resistors. I chose the display, because it’s easy to connect, instead of those finicky little smd LEDs, plus it’s easier to read letters than blinky lights)
  • 1.5k resistor, 2.2k resistor
  • PWM to PPM converter if your RX doesnt have PPM
  • I also found MavPixel, a¬†WS2812 I2C¬†controller


Connecting it together part 1.

First, we connect the sensor modules, check if ArduCopter starts or not. If it does, we move to connecting the periferals.

GPIO broken out, connections to sensors

GPIO broken out, connections to sensors

APM piZero Proto

APM piZero Proto


Gyro and baro sensor are connected through same SPI bus, just have different CS (chip select) pin, which is controlled by software.

MPU9250 and MS5611 connections

MPU9250 and MS5611 connections

end part 1.


Getting ArduPilot software

You can use a different linux computer to get the software, edit the libraries to use the right orientation, cross compile and copy to PiZero…

Or you can compile on the Zero itself. Hassle-free, just takes longer… not much, tho. I’m going to go with that.

Install rasbian, download here, instructions also provided.
Connect to Pizero, either over ssh, or plug in your keyboard, type in:

sudo raspi-config

enter Expand Filesystem

enter Change User Password

enter Boot Options, Boot to CLI

enter Advanced Options, enable SSH, SPI, I2C, disable Serial.

add¬†“enable_uart=1” in /boot/config.txt (this is to enable serial input for GPS)

save and restart


Now, we install RT-PREEMPT, which is RTOS patch, makes rasbian Real-time OS. Copy the commands from here, or even better, go to the original website, and check for new versions. This basically copies the precompiled kernel over our original one.

~$ sudo rm r /boot/overlays/

~$ sudo rm r /lib/firmware/

~$ cd /tmp

~$ wget

~$ tar xzf kernel4.4.9rt17.tgz

~$ cd boot

~$ sudo cp rd * /boot/

~$ cd ../lib

~$ sudo cp dr * /lib/

~$ sudo /sbin/reboot

Reboot and reconnect.

Install required software and ArduCopter 


  1. Clone code from github

    ~$ git clone

  2. Install GNU awk

    ~$ sudo apt-get install gawk

  3. Change MPU9250 orientation

    Open file: ardupilot/libraries/AP_InertialSensor/AP_InertialSensor_MPU9250.cpp

    Find and replace
    , _default_rotation(ROTATION_YAW_270)

  4. Enable PWM
    Open file: ardupilot/libraries/AP_HAL_Linux/HAL_Linux_Class.cpp

    Find and replace
    static RCOutput_PCA9685 rcoutDriver(PCA9685_PRIMARY_ADDRESS, true, 3, RPI_GPIO_27);
    static RCOutput_PCA9685 rcoutDriver(PCA9685_PRIMARY_ADDRESS, false, 0, RPI_GPIO_27);

  5. Disable RGB leds and enable OLED
    Open file: ardupilot/libraries/AP_Notify/AP_Notify.cppFind and replace

    AP_BoardLED boardled;
    NotifyDevice *AP_Notify::_devices[] = {&boardled};

    Replace with
    Display_SSD1306_I2C display;
    NotifyDevice *AP_Notify::_devices[] = {&display};

    Go to ArduCopter dir for copter, or ArduPlane if you want to compile for a plane.
    ~$ make pxfmini
  7. Test!


Connecting it together part 2.

Now, that we have a working ArduPiCopterZeroDroneFlyingMiniLinuxComputer (I’m so clever with names, I know), we can start connecting the peripherals.

First, we will add ADS1115 to monitor the battery. ADS1115 uses I2C to communicate so connect

  • GND – GND
  • VCC – 5v
  • SDA – SDA
  • SCL – SCL
  • Voltage wire from Power module – A0
  • Ampere wire from Power module¬†– A1
  • ADDR – GND (set¬†address to ‘0x48’)
ADS1115 connections

ADS1115 connections

ADS1115 connections

ADS1115 connections


2. Next connect the Power Module
There is a 6 pin connector on the PM, pinout as follows
(PLEASE, test with a multimeter, chinese clones CAN have cables the other way around, so black is vcc and red is gnd)

pin PM        action               pin on APM
1,2               5V                     any 5v, to provide power to PiZero.
3                  Current [I]         A1 on ADS1115
4                  Voltage [V]        A0 on ADS1115
5,6               Gnd                   any ground


3. To drive the servos or ESCs, we need¬†PCA9685.¬†It’s an I2C enabled pwm driver, so just connect it to any I2c pins, maybe the easiest is to hook it up to ADS1115. As said SDA to SDA, SCL to SCL, 5v to 5v, gnd to gnd, no rocket science there.There is, however, a catch with 5v power rail… Wiring it like this does NOT provide to 5v pin on the ESC/servo connectors. For multicopters, leave it as is, but if you intend to use servos, connect 5v to vcc pin on the module, maybe put a fuse between PCA and RPI, just to be sure. Me, I just remove 5v wire from ESC, and connect vcc power to PCA. Your choice.


4. UBLOX gps module…¬†I have one chinese and one original from 3DR. Shell out for the high quality one… That’s all i’m gonna say.
Bunch of useless shit needs to be done to clones, for them to work properly. Majority of them have THE WRONG eeprom chip installed. Well wrong isn’t¬†exactly a right word, since it’s “just” a wrong orientation. Either way, with clones, you’re left with a couple¬†choices:

  • Get the correct chip from the internets
  • rewire the wrongly oriented chip
  • send configuration string to gps with rc.local everytime the pi boots, and completely forget about eeprom ūüôā

The last one is probably the easiest, since you don’t even have to configure the GPS in Windows over FTDI converter. And that’s the one I intend to use. I could go into detail on how to set it with U-center, but I won’t, since it’s been done already.

If you have the one that was put together like it was supposed to be, just connect power and RX to TX and TX to RX. Nothing more to it. If you want to test it, just enter

cat /etc/ttyAMA0

and you should see gps sentences being sent over to you. If not, probably switch RX and TX, or repeat step: Getting ArduPilot software.


GPS connections

GPS connections

GPS connections

GPS connections

5. We need to be able to control the FC, so we connect PWM to PPM converter
On the converter, there are three “out” wires , the usual servo connector, gnd, vcc, signal (ppm). Connect vcc to 5v, gnd to gnd. For the signal input, we will need a voltage divider, since Rpi GPIO has 3v3 input max.¬†connect it like a-so.. where R1 is 1.5Kohm and R2 is 2.2Kohm.¬†This lowers the high 5v to acceptable¬†2.973v. So, Vin is PPM, OUT is gpio4

Voltage Divider Circuit Schematic

Voltage Divider Circuit Schematic

Voltage Divider on the left

Voltage Divider on the left

6. OLED is a simple I2C device, so connect the I2C lines any where on the board, pins, rpi or servo controller. SDA to SDA, SCL to SCL and 5v power.

7. Besides that shiny, tiny OLED screen, I also wanted a different form of visual notification, the kind that you can see from outer space ūüôā Something like IRIS has, or the Phantom. I stumbled upon MavPixel. It’s a diy Arduino pro mini project, that scans the telemetry, and controls up to 12¬†WS2812 I2C¬†rgb¬†leds accordingly. It also comes with GUI configurator, which is basically a copy of Cleanflight’s Led configuration program, so it should be easy to figure out.

When I get the LEDs, I will make another post, just for MavPixel.


I had some PCBs made from OSHpark. As always, the result is BEE-E-A-utiful

[Parts List]

[OSHpark pcb link]

ArduPilot PiZero

ArduPilot PiZero

ArduPilot PiZero

ArduPilot PiZero



  1. So I’m confused as to how to wire both a receiver and the PCA9685 to a set of ESCs. Do I need to splice the signal wire from the ESCs into both to allow manual and autonomous control?

    • Hi

      no, you don‚Äôt splice the wire. I use the PCA9685 module, and just connect the three wires to the module. there is no direct ‚Äúmanual‚ÄĚ control, passthrough is passed through he APM. Connections are the same.

Leave a Reply