Syma S107 No Fly Zone
Posted: January 8, 2012
When a friend at work got a Syma S107 IR helicopter to fly around the office, I decided to see if I could jam the signal and create a no fly zone around around my area. A quick search of the Internet and I found several people who already reverse-engineered the protocol with the best ones being here and here. I then went to NewEgg and bought my own helicopter so I could debug this thing. Actually, these helicopters are quite fun, although we both broke a tooth on one of the gears in each of our 'copters so they don't fly as well anymore. At least it flies better than my Linksys Quadcopter project :).
Related Projects @mikekohn.net
So I started with a smaller circuit and different firmware that simply sends a command to the 'copter over and over to prove I can at least control it. I knew I needed a strong IR LED, so I went to Mouser and found a Vishay TSFF5210 IR LED. The angle of half intensity of the LED is 10 degrees which seems a bit focused, but the radiant intensity was a big number :). Unfortunately, to get that high intensity I believe it takes 1A of current and the LED is only rated at 100mA continuous. Since I'm pulsing this LED I decided to drive it around 200mA (assuming my calculations are correct.. if the exact current calculation was needed I should have used an ammeter). To drive the LED I'm using a high-gain ZTX1049A transitor. To control the LED I used an MSP430F2012 since I had some laying around. The original circuit simply had an IR emitter that sent a single command over and over to the copter.
My next step was to modify the circuit and source code for jamming. I pointed 4 IR LED's in 4 different directions and put four Vishay TSOP38223 38kHz IR sensors next to them. When any of the four 38kHz IR sensors senses the remote control trying to send a command, the firmware is programmed to flash a yellow debug LED and send out its own command on all 4 IR LED's to turn the thrust off. Most likely the 'copter never really sees this command as the IR from the circuit probably just mixes with the remote's IR and creates garbage causing the helicopter to fall from the air. Achmadinejad would be proud :).
Note (January 26, 2012) Thanks to a poster on Hack A Day named Bogdan, the 100ohm resistor on the base of the ZTX1049A should be 1000ohm. The 100ohm resistor was pulling too much current on the pins of the micro causing it to reset and crash the MSP430 Launchpad and stuff. Because of the problems I was sending IR commands 1 byte per LED. With the change (and using a battery instead of the power supply I have that doesn't support the current draw) I can send the data on all four LED's at the same time. I posted a new schematic and new firmware after around 7pm central time in the US.
The firmware is pretty simple. I set up the internal DCO of the MSP430F2012 to run at 16MHz (if anyone from Texas Instruments reads this, PLEASE make an MSP430 chip in DIP packaging that can take an external 16MHz resonator or crystal. The DCO sucks.). Anyway, I set up Timer A to interrupt every 210 cycles which comes up to around 76190 times a second (double the 38kHz frequency). I used r13 to point to 1 of 2 interrupt routines: led_on, which toggles the output LED's and led_off which turns all LED's off. The led_on routine will also count the number of times the interrupt has been hit in the r5 register. This allows my main routine to keep time of how long each "burst" is. For example, when r5 counts to 152, it means 152 interrupts have been called which means approx 2ms has passed.
The protocol for this IR is, with a 38kHz carrier frequency, send 2ms on / 2ms off (a header portion to tell the 'copter a 32 bit command is coming) and next 32 bits of data where a 0 is sent by sending 0.300ms on / 0.300ms off, or a 1 by sending 0.300ms on and 0.600ms off. The 32 bit command is 4 seperate bytes where byte 0 is yaw, byte 1 is pitch, byte 2 is throttle, and byte 3 is trim. Yaw, pitch, and trim should be 0 to 127 where 63 is middle. The throttle is is 0 to 127 where the 7th bit (128) will tell it which channel (A or B). Each bit is send LSb first. In my code I do this by shifting left on the register holding the current byte and checking the carry flag. After each command, there should be a recovery time where the remote stays silent. I avoid this recovery time in the no_fly_zone.asm firmware so I have the possiblity of sending more commands than the remote sends.
The MSP430 assembly source code below can be assembled with my own naken_asm assembler.
Copyright 1997-2013 - Michael Kohn