This project involves building and programming a quadcopter. You may ask: it seems everyone these days is making drones, isn't it just about buying a couple of motors and a kit? No, I'd like to push myself and make every component of a flight controller from scratch1.
What does that include? Motor speed controllers (x4), RF communications, inertial unit and a program to bring them all together.
1Something something apple pie, invent universe or whatnot
This will be my second time attempting this exact project. Last I tried, I was a freshman and fully prepared to fail my embedded systems class for a cool, over-ambitious final project.
Above is the gist of my development. It was with that project that I first learned to CAD, so most of my time went there and the electronics were more of an after thought (hence the nightmare through-hole stuff going on). And, well, it "flew" once. Then the crash shorted the spaghetti mess going on at the base and that was it.
So this time around (well actually everything is different now because I lost all the files), I'm taking a much better approach: PCBs! And it so happens that this week's assignment is designing a circuit in an EDA software that we'll bring to life next week.
Sketch of a single motor controller circuit
The first part of this PCB is the motor controller, which revolves around the idea that we'd like a microcontroller to modulate the speed of a motor but its pins cannot directly power it. That's because motors are really power hungry and one with load (let alone four) will definitely not work and perhaps fry the on-board regulator.
So we offload that task to a voltage controlled current source, such as a MOSFET. The MCU's pins can regulate voltage (via PWM), and the MOSFET will comfortably allow a lot of current to fly through it. I used the NDS355AN because it's what we have in lab, but let's double check its ratings to give the illusion of choice.
I asked ChatGPT how to interpret a FET datasheet
Here are the important design requirements for this particular application:
And now some details/decisions about my circuit for anyone wondering:
I tried using Fusion360's circuit and PCB design suite. It sucked, never again.
I tried KiCAD next and had a much better experience. The first task was replicating my circuit digitally:
Complete circuit
Then I need to arrange everything in circuit board land:
PCB design I came up with
The drone frame is very simple and fitting the motors and board takes advantage of the PLA's compliance. I got this idea from here. On a Prusa this took 24mn to print, and this design is about 30mn of work in Shapr3D. So the frame only took an hour; neat!
The frame is flat, so there's only one sketch
Visualization of the final drone. I used these two models.
This is technically next week's assignment, but I wanted to get a head start. In the EECS lab section, we're using the Bantam Tools CNC mill.
One of the earlier boards I milled
I used SMD components, solder paste and a hot plate/air station to assemble everything.
Hot air station I used
All the SMD parts put together!
What. A. Pain. Writing about this in full details would probably be very boring but the takeaways of my (and Anthony, who helped a ton) suffering is described here:
I learned these tips the hard way when all but one of the motors worked (the last would always be on). It turned out that the pin controlling that motor was shorted to the battery (via trace under the ESP32 that I can't see) so the gate was always driven high. This is fixed by routing that motor to a different pin (slow, painful) or following the advice above (easy, straightforward).
Now, I still have all but one working motor. For some reason, one of the controllers stopped working.
PCBs v1, v2, and v3 all had shorting issues where a motor was either driven high constantly, never turning on, or stealing power from the microcontroller.
So what did I change in v4? PCB v4 in KiCad
Well apart from embracing double sided PCBs and making the traces more spaced apart thanks to the freed space, I changed my milling method. Notably, I used 1/32" in addition to 1/64" end mills. I repeat, do not use 1/64" end mill exclusively. I used the Bantam Tools mill, which is especially nice because it will calculate which traces require the thinner tool. Then, I meticulously checked and cleaned every single trace on the PCB under the microscope, using tweezers and compressed air to remove debris. Finally, I probed the pads with a multimeter to check for any shorts. All of this before putting on any parts.
So you would think it worked first try?
Everything that can go wrong, will go wrong.
The first issue I ran into was the ESP32's GPIO pins seemingly not turning on. Despite being able to flash code and respond to serial, the microcontroller did not want to execute code. The issue turned out to be strapping Pins. For whatever reason, one of the pins I'm using must be driven high at startup or the ESP32C3 will not execute from flash.
Since I have four 10kΩ pull-down resistors in my design, I investigated those first and... somehow a bit of solder flowed around three of the four resistors and effectively shorted them. This would've probably been a big headache later on, and it fixed this first issue!
So watch out for strapping pins!
Great! Now the microcontroller works, and so do the four motors! What could possibly go wrong?
How about everything (MCU, motor controllers) breaking during the fourth test. Not only did the battery no longer power the microcontroller, but using USB and the battery would not turn on the motors. And this happened without any changes or damage.
So what happened? Well motors consume a lot of power, on the order of 1A each. And each copper trace on my PCB can probably handle that without much trouble, but two traces in particular have to handle much more: Ground and BAT+. The motors are routed in parallel but the junction happens after a long, thin strip of copper down the middle of the board so that one burnt completely.
The fix would be to redesign and mill the PCB, or add jumper wires with adequate current ratings.
Don't run lots of power through thin traces!
Somehow the trace to power the microcontroller also burnt. I'm not sure how, it really shouldn't be drawing that much current. It'd be nice to apply the same fix as before, but the burn happened underneath the MCU (BAT+ pin isn't exposed) and would be impossible to fix without desoldering a lot of things.
So I connected BAT+ to Vin, which works but has the disadvantage of removing the option to power the drone using both USB and battery.
Pretty self explanatory. There's a ton of vibration in the frame design, so that's probably a bunch of energy wasted and more current drawn.
Finally! The electronics work. So we can move on to flight software, starting with the IMU.
I'm using the MPU6050 which is relatively cheap (and old) but has an onboard processor (DMP) that performs sensor fusion for me. That's nice because the ESP32C3 is single-core and will eventually have WiFi bottleneck issues.
The reason I'm using the ESP32C3 and not the RP2040 or something along those lines is for its wireless capabilities. I want the tuning software and remote control to be a website. I implemented this in two ways: either the ESP32 acts as an access point (i.e. it becomes its own WiFi network) or joins the same network as my laptop (e.g. "EECS_Labs"). Both work and it's a tradeoff of boot-up speed or connection speed.
Either way, the ESP32 hosts a website which I can access via its IP address. Then, that website opens a WebSocket that I use for bidirectional communication (i.e. user commands <-> telemetry).
Here's a demo of this working. The drone is just spamming the console with its orientation... wirelessly!
Probably the biggest advantage to using a website rather than a standard RF controller is I can add anything to it. For example, the PID constants can be tuned wirelessly and without flashing.
Also, what is PID? It stands for Proportional, Integral, Derivative. It approximates the problem of balancing our drone (motors are not made equal. Powering them all will not result in stable flight) using a linear model of the error on each of three orientation axes: yaw, pitch, roll. This is called closed-loop control, as opposed to open-loop which is like driving with your eyes closed (a bad idea).
It's a little hard to convince this on video, but here the left-most motors increase in speed to counteract the orientation shift.
Things went well but it's all downhill from here.
While tuning the PID, the drone flew off into my arm (it hurts ;_;) and broke one of the motor controllers. One of the MOSFETs blew clean off!
Above is the voltage across the ESP32's power pins. That sudden drop is when the motors turn on, which is enough to reset it. This is due to the motors causing a sudden current spike (stall current is significantly higher than constant) which drops the voltage sufficiently to reset the ESP32. I could fix this with a buck converter or better battery, but I didn't have time for either.
So behold this monstrosity:
It kind of defeats the point of being wireless (which it still is, technically!) but I powered the drone using a desktop power supply at 3.7V, 3A MAX.
Anddd the topping on the cake is this:
I dropped the drone during testing and another motor broke. At this time, lab was closing and I had no way of fixing this. So the drone may not fly today, but hopefully in the future!
I thought making a drone would be a battle split between hardware and software. Apparently not, because electronics is really difficult. What I have so far (~2 weeks of work) doesn't fly but I'll keep iterating!