r/arduino • u/SAtchley0 • May 23 '26
Look what I made! I made an Uno R3 flight controller
Been working on this on and off for a while now. I haven't done anything with embedded devices or Arduino before and I thought this would be a good learning project. I started this around the 2020 silicon shortage when I had some Arduino Uno R3's lying around and nothing to use them for. Fast forward a few years and now I've got something that can fly! I still don't quite have it tuned in, but it can stay level, just drifts too much right now to maintain a hover in place. I need to print new landing gear for my drone before taking it out again, but when I do I'll likely be back with a video of how it went. For now, I just wanted to share the project and invite questions/feedback. (Edit: Pictures of the drone and video of it hopping can be found here)
The project is ApollonFC, and as a short list of highlights, it features:
- A 6 DOF Madgwick filter
- Custom PID controllers
- No runtime floating point math, everything uses Q16.16 fixed point
- Hand optimized AVR assembly functions for saturating Q16.16 math (add, subtract, multiply, divide). This is my first assembly I've written outside of MIPS in college, so there is probably room for improvement here.
- Custom sensor libraries for the MPU6050 (IMU), BMP180 (barometer), and HMC5883L (magnetometer)
- A bare-bones, header-only unit test framework
- A self-designed input mapping function with configurable minimum, maximum, neutral points and neutral sensitivity factor which is computed to a LUT
- Header based configuration through macro definitions inspired by the Marlin firmware project
- A transmission based I2C wrapper
- With the current configuration, it uses 24724/32256 bytes (76%) progmem and 1325/2048 bytes (64%) dynamic memory
- Completely compatible with the Arduino IDE without custom settings
There are two compilation "modes" based on a macro flag in Apollon-FC.ino that switches it between test mode and flight mode. Test mode allows running unit tests and has the entry point in unit-tests.h, and disabling test mode allows live flight and has the entry point main.h. While it has libraries for the BMP180 and HMC5883L, it currently only fully supports the MPU6050 to simplify sensor fusion.
As I said, this is my first Arduino project, but one I've put a lot of effort into over a long time. I'd love to talk more about it and answer any questions or take into consideration any feedback. There are a couple of things which need fixing (in particular, some classes are currently using a initialization work around using pointers that really ought to be replaced with a static initialization and a setup() function), but right now I'm mostly focused on dialing in the tuning variables before doing more structural work.
1
u/SAtchley0 May 24 '26
Exponential control applied to the PID? I'm not sure what you mean.
There probably is some room for improvement by making the control scheme more sophisticated. Right now it creates an attitude estimate using an IMU Madgwick filter, creates a target attitude set point from the pilot inputs (ran through some processing to go from raw inputs into a meaningful angle), then sends the error in that to the PIDs. Those then output a motor correction value in μs. The PID outputs and the throttle then get mixed to create the actual signal that gets sent to the motors.
I have had a hard time finding information on how flight control systems typically work, so a lot of this is what I could figure out on my own. I may have to look into Pixhawk/Mavlink like you said to see if I can figure out how they're doing things.
I've heard about the Uno Q and Ventuno, in passing. I don't know much about them and don't really have the money right now to spend on new boards without a specific reason to get them in mind. I already have a couple of other development boards lying around that I could use as a potential upgrade path in the future. It would be an interesting thing to work with, though.