Here’s my first project post! It is a bit lacking in pictures because it chronicles a series of mishaps which did not result in any functional device. I’m writing it though because it’s important background information for subsequent projects. It turned out to be ridiculously long-winded, so skip to the rules at the end if you’re not interested in the details that led me there. As I will do in any post that mentions some software I wrote, I’ve attached source code to the post.
Ever since I got my first tiny, 2-channel, IR-controlled, indoor RC helicopter (probably ~7 years ago) I thought about making one autonomous. Back then that goal was way out of reach, but my embedded control capabilities and build skills have progressed far enough since then to make it achievable. I started real work on the project a few months ago. I am using the Syma S107 because they are amazing and only cost $20. My first step was to learn the commands that the remote sends so I could use a microcontroller to command the helicopter. With the help of a lot of online info from people who had already done this, I had the helicopter running pre-programmed flight paths in a few hours:
This success got me so excited about the project that I spent about 2 hours the next day putting together a mess of freeform-soldered components and taped them to bottom of the helicopter. There was a PIC 12F617, two IR LEDs, and an IR phototransistor. The PIC used a simple algorithm to get a distance measurement from one IR LED and the phototransistor, which were both pointed down at the ground. It would take an analog reading from the sensor, then turn on the LED and take another, and then find the difference between the two. A series of these measurements were collected and then averaged and the final value gave a crude indication of whether an object (the ground) was there and how far away it was. The PIC then used this measurement to turn the throttle variable up or down, and an interrupt routine periodically sent a command to the helicopter over the second IR LED, which was taped right up against the receiver on the helicopter.
Once I got that all up and running, I tried to test it in the lab at work and it kept crashing into things. So I took it outside to the parking lot. At first, it worked great. The IR reflectivity of the pavement was very low, so the setpoint I had established inside corresponded to a height of only about 4 inches outside. But it did actually manage to automatically regulate its altitude, and it floated around the parking lot for a couple of minutes. Then it suddenly took off straight up, and kept going up until I could barely see it in the sky. It was hit by a gust of wind, knocked over, and crashed irretrievably on the roof of the building. I went inside and ordered two more helicopters.
While I was waiting for those to arrive, I had time to think about the stupidity of rushing to make it fly and doing things half-assed, most notably by preserving the IR control and adding extra stuff to the outside of the stock helicopter. So when my replacements arrived, I ripped it completely apart and desoldered their unmarked (bastards!) microcontroller from the board. Then I traced all the connections so I could map the pinout, and replaced their micro with a PIC16F1824, one of my favorites.
<stock pcb image to be added later>
The board was fairly simple to understand—it needs to control two motors for the main rotors with variable speed but only one direction, and a third motor for the tail rotor that pitches the helicopter at variable speed and in both directions. Therefore it has an N-channel FET (or an NPN bipolar if they’re cheap) switching the low side of the two main rotor motors, and an H-bridge formed by four transistors for the tail motor. They also have the IR receiver, an LED, two current sense resistors for the main motors (awesome! But they obviously didn’t implement an overcurrent shutdown in software. Maybe they used them to help balance rotor speed, but I see no performance improvement between models that don’t have them to those that do), and a mystery sensor on a tiny daughter board:
<sensor image to be added later>
If anyone knows what this sensor does, please tell me. I can’t figure it out. Anyway, I wrote code that uses the two CCP modules to do PWM on the main rotors and an interrupt routine to (more slowly) PWM the tail rotor in either direction. I made a function that sets all the outputs based on four variables: throttle, yaw, yawcorrect, and pitch. This is called periodically, so all the main loop has to do is put the desired values in those variables and the motors react accordingly. With all that done, I wrote a simple main loop (which wasn’t really a loop at all) to gradually spin up the rotors and do a quick hop and then shut down, and the helicopter flew under my own software control!
I then used an available GPIO pin to run an IR LED, pointed down. The first iteration of my IR altitude detection had terrible range, so I had the neat idea to keep the integrated demodulated IR receiver that was already on the board and use that instead of my phototransistor. This gave me a huge amount of gain because of the internal amplification and band-width filtering, but with the disadvantage of being a binary output instead of an analog signal. If I pulsed my IR led at the carrier frequency used by the remote, the receiver would pick it up if the ground was there to reflect the light. I discovered another neat trick to get a bit of variation out of the sensitivity: if I intentionally skewed the frequency I was putting out on the LED, it would decrease the sensitivity of the receiver, and the ground would have to be closer for it to register. This seemed to work pretty well, but it was almost impossible to automatically hold an altitude when my only altitude data was “yes” or “no” instead of a number. I was making pretty good progress (despite having to fish the helicopter out of some bushes in my yard) until I flashed a new algorithm that sucked, and it took off straight up until I couldn’t see or hear it anymore.
That night I decided to make the rules, and I was not allowed to even open the box of my remaining helicopter until I had the ground work laid to follow them. I also decided that I was required to build a functional non-flying robot before I started on the next helicopter, and that’s where Tiny Tank Bot came from.
Everett’s rules for tiny autonomous helicopters
1. Infrared cannot be used for altitude sensing. It is way too dependent on the reflectivity of the surface and way too susceptible to sunlight interference. The exception to this rule is if I actually measure the travel time of a reflected infrared pulse, but at 3 nanoseconds per meter, I doubt I’ll find a microcontroller fast enough to do that.
2. All outdoor tests must have a failsafe wireless signal. While it’s in the air, I’ll have a transmitter on the ground continuously sending the “ok” signal, and the helicopter will initiate a landing sequence if the signal stops. Adding the hardware to comply with this rule also opens up a lot of new capabilities for the device, like radio control and telemetry.
3. All alpha tests of new hover algorithms need to have a shutdown timer implemented in software of no more than 60 seconds.
helicopter preliminary.asm For PIC12F617, transmits throttle value based on IR proximity sensor. This code emulates the controller IR protocol, so with modifications it may be useful for anyone who wants to build a custom remote control for a Syma S107.
UAV 1.0.asm This code doesn’t work! That is, the hover algorithm doesn’t. It still has good base code for running the three motors in the helicopter.