The Arduino Nano RP2040 Connect comes with a built in IMU. It's fast speed and ability to program it with the Arduino IDE, it makes for a great microcontroller to serve as a quadcopter flight controller.
What's special about this project is that at the time of writing this article, there are no search results via Google, Bing, or Yahoo that can find a published opensource code for the Arduino Nano RP2040 Connect for flight control. This makes this project the first published open-source version!
These are the components we are using for our drone:
- Microcontroller: Arduino Nano RP2040 Connect
- Motors: QWinOut A2212 1000KV Brushless Outrunner Motor 13T
- ESCs: QWinOut 2-4S 30A/40A RC Brushless ESC Simonk Firmware Electric Speed Controller with 5V 3A BEC
- Battery: HRB 4S 3300mAh 14.8v Lipo RC Battery 60C
- Our Custom PCB
This hardware works with the code out of the box. The drone frame is up to the builder.
PCB DESIGN CONSIDERATIONS
The biggest design consideration for this board was the logic level. The RP2040 GPIO is designed for 3.3V and not 5V tolerant. However, the ESCs and the radio receiver communicate on 5V. So, any pin to the RP2040 that was receiving a signal required a voltage divider to protect the RP2040.
The second consideration was battery management. Many of the LiPo batteries available are long lasting with a ton of amps to deliver quickly but must not be allowed to go under their minimum cell voltage. We ballooned a LiPo once in the house. It's terrifying!
In turn, a means of letting the drone pilot know the battery is draining too low had to be designed. We achieved this by applying a voltage divider here as well. In our case, we had a 14.8V divided to just under 3Vs. The closer the battery approaches undervoltage (12.8V), the beeper will increase its beep rate until it is too annoying to want to continue use.
Otherwise, the rest of the design was just focused on providing reliable wire hookups between the drone receiver and motor electronic speed controllers (ESCs).
FLIGHT CONTROLLER CODE
Code Repo: RaisingAwesome/ArduinoNanoRP2040ConnectFlightController: Arduino Nano RP2040 Connect Flight Controller (github.com)
The flight controller code is based on the Arduino Madgwick Library. Getting the accelerometer data to translate into angular data is no easy task. We ate a lot of propellers in the first few trials, so we decided to invest time into a custom tool for tuning and studying the sensor data. We developed it in Unity and added additional Arduino code to pipe out JSON packets of data.
Using this, we can see how the motors are being driven in response to the IMU data. We can see its quickness of response and any issues with the IMU that occurs due to sudden changes in position.
FLIGHT CONTROLLER TUNING
The Maker revolution has been driven a lot by the availability of the IMU. The key to a stable and responsive drone is all about the coded PID calculations. However, those calculations have gain parameters that must be dialed in for your drone design. Store bought drones are already dialed in. There's no chance that a custom built drone won't need some degree of tuning.
So, we integrated a web server in our code. This allows us to connect with the drone on startup and feed it constants to help dial in the tuning. Below is a snapshot of one of the interface pages. It uses Bootstrap responsive styling to give a modern and ever evolving look-and-feel.
KEY LEARNINGS SO FAR
We've made a lot of mechatronic projects over the past decade, but the drone definitely requires the most finesse when it comes to sensors and actuation. Here is what we learned so far:
- You reduce a lot of complexity in troubleshooting by ensuring the center of mass is truly the center of the assembled drone.
- To check the center of gravity, simply find the center point in the 2D plane of the motor axis.
- Use something to pick the assembled drone straight up like a hook-ended picker tool.
- To balance it, we used washers on the frame clamped at the edge with one of those black paper binders. This allowed to adjust it as needed as we added and moved around components.
- Make sure everything is zip tied down.
- When the drone went a little sideways, we had a part flip up into a prop. Game over.
- So, we 3D printed various brackets to lock everything down in place.
- Stiffen the mounts at the motors to minimize vibration
- If you buy a frame, they probably have this problem worked out already.
- For our frame, we started by CNCing out an acrylic body. There was a resonance zone of the motor that led to high vibration that simply snapped the acrylic where the motor was mounted. It as awesome! It went totally sideways and the broken prop acted as an after burner with the other three props pointing right at us as it chased us around the yard. It was quite the comical sight.
- In turn, we reinforced those locations with 3D printed armor.
- Calibrate the IMU
- If you have a great looking drone, with the Arduino Nano RP2040 sitting a little pitched or rolled, then it will end in disaster. That's because as soon as it lifts off, it will try to correct those degrees. The effective correction has a 50% chance of flying it straight into the ground or flipping it over so quickly you won't have time to correct with a stick.
- To improve it, place the fully assembled drone on a level surface. In our code, uncomment the calculate_IMU_error function and deploy the code. Look at the serial monitor for the calculated IMU error values and instructions how to update it in the code. It takes about 30 seconds or more before it will dump out the new values you need. Comment it back out after you make the error value changes in the code.
- Start off level
- If you don't start level, this is just another set of variables you'll have to overcome when establishing the tuning of your code.
- Don't shortcut establishing a battery monitor.
- We went out of our way to design our PCB to provide an audible battery alarm. Drones will drain down a battery pretty quickly and it's easy to get focused on flight and forget how long you have been at it.
- Bigger Battery is Better
- We tried a very lightweight 7.4V LiPo. We loved it's light size, but compared to driving the ESCs with 14.8V, the smaller battery couldn't even think about getting the drone in the air. The 14.8V definitely spins faster and brings with it a roar that creates the needed lift to get off the ground for this big beast we are designing.
- Yaw needs special consideration for take off
- After a lot of head scratching, we realized that the Yaw correction was affecting take off. At take off, we just want to go straight up at our desired throttle speed. We realized that our code immediately was trying to achieve a fixed compass angle as soon as it was powered on. So, the fix was to store the startup yaw and handle stick input as a jog versus mapping the stick to a fixed yaw_IMU angle.
- Gyro Speed is a bit slow.
- We found that the gyro speed must be faster than the overall loop speed of the PID calculations. Well, that means the overall loop speed has to be less than 104HZ as that is the specification of the Arduino LSM6DSOX that is built into the Arduino Nano RP2040 Connect.
- When you compare loop speeds to popular controllers they are doing 4KHz-8KHz. That's waaaaayyyyy faster. They claim they are in turn able to better filter out noise and provide better responsiveness. However, we got in the air and our beast is a great aireal camera.
- Gyro gets dizzy.
- We noted that if you rapidly roll or pitch the RP2040, the gyro takes about 3-4 seconds to stabilize. This will be an issue if you want to be a trickster. Definitely wouldn't allow for successful FPV flips and barrel rolls. Our aim is to showcase the chip, so we are sticking to it for this build - but definitely will have to upgrade the IMU tech for our next one.
- Arduino Nano RP2040 Connect's pin A6 (and probably A7) didn't work for analogread. It could handle up to about 1V. We found we had to update the WifiNina Firmware with the Arduino IDE to take it to 1.5.0. For some reason, 1.4.8 is what the firmware checker in the File->Examples claims is the latest. When you use the WifiNina Firmware updater, it lets you go to 1.5.0 which fixes the problem.
- Flex in the frame can be a major problem. Our acrylic frame could not be controlled no matter how we adjusted the coefficients for the PID controller. We could see it flex as it attempted to take off. We switch to a stiff frame and it jump 12 feet in the air in a split second. Still crashed, but it at least could get off the ground.
We'll keep updating this blog as time goes on. Visit the History to quickly see any updates.
11/6/2022 Started keeping history log.