Arduino-based Syma 107G Controller with Dual-Channel Multiplexing

Hey everyone — I’ve been getting steady traffic and requests from visitors about the Syma S107G controller I’ve alluded to in earlier posts, so I guess it’s about time to write it up properly. Here we go…

Introduction & A little history

Way back in December, 2012, I posted a write-up of the reverse engineering work I did on the control protocol used by the cheap $20 Syma S107G infrared helicopters that are pretty popular at the time.  I guess it turns out they are still pretty popular as the Hackaday post still generates regular traffic to my blog — and a steady stream of emails from other curious makers interested in these awesome choppers.

Before I started reversing the protocol myself, I built a rudimentary controller to learn about how to implement other hacker’s descriptions of the IR protocol used by the S107G. It wasn’t very good, but it did teach me a lot about the importance of writing efficient code for the Arduino and some of the pitfalls of generating communication signals with microcontrollers. After playing around with the controller with my colleagues, I revisited the design of it to clean it up and start exploring how you might be able to pull off some fun stuff — thus the Dual-Channel Multiplexing Controller was born!

An Overview of the Controller

I think that the controller makes for a fun and relatively straightforward project for people interested in playing with robots/remote control vehicles — and more importantly it’s got potential to be the basis for some pretty cool projects in the future. Here’s the breakdown on how it works:

What does the Dual-Channel Multiplexing Controller actually do?

Basically, the controller simply allows you to control two helicopters at the same time from the same unit (using a computer for the controls). It does this by transmitting the control packets alternately for the two helicopters very quickly.

The control method — using the keyboard — is definitely NOT ideal (particularly for two-people at once!), in fact, it’s a real pain in the arse, but this is more of a proof-of-concept for a bigger project that I’ll explain later.

It’s important to note that all of the issues with this method of controlling the heli(s) has nothing to do with the controller itself, just the limitations of having to design a way to control the helicopters with a keyboard.

How to use the Controller

The controller consists of 3 major parts:

arduinorev31s

An Arduino UNOr3 (flashed with the sketch below).

IR_Shield_small

A super-simple “IR Shield” consisting of a couple super-bright IR LEDs and a couple of status LEDs.

GUI_Controller

A Windows app for controlling the heli(s) written in Processing.

Instructions — SYnchronizing

Assuming you have all the parts above, here’s how to get the thing going:

  1. Make sure the IR Shield is properly connected to your Arduino.
  2. Connect the Arduino via USB to your PC. You have to do this first otherwise the controller app can’t enumerate the Serial port and won’t start.
  3. Open the “Heli_IR_GUI_DualControl.exe” app.
  4. Make sure both your heli’s are turned off.
    Note: obviously we don’t want to synchronize our helicopters to the same channel as we wouldn’t be able to control them independently. The following steps are the best way I’ve come up with to sync them separately.
  5. Press either “6” (heli #1) or “7” (heli #2) on your keyboard depending on which heli you want to sync. The appropriate LED (red or green) will turn on indicating you have 10 seconds to sync the heli.
  6. Turn on your Syma S107G helicopter and position it over the IR LEDs on the IR Shield.
    Note: you may notice there’s a flashing light on the heli’s PCB — I think some people believe this is related to the helicopter synchronizing with the controller, but I don’t think that is correct. I think it indicates the status of the on-board gyroscopic stabilization sensor — you need to hold the heli very still and the light will stop blinking. If you’re having trouble holding it still enough, you can try to power it on and place it on a table top while the Controller’s sync LED is lit — I found that the heli’s still synced quite reliably (probably due to the IR signal reflecting off the walls).
  7. Test that the helicopter synced successfully by pressing the helicopter’s Pitch Forward/Pitch Backwards key (W/S or I/K respectively). If the tail rotor spins, you’re good to go, if not, turn the helicopter off and repeat steps 5–7 again.
  8. Repeat for a second helicopter (if you want to).

Instructions — Flying the helicopters

I’ll say up front, flying these things with a keyboard is …sub-optimal at best. Here are some tips on how to get the choppers off the ground:

  • Rule #1: Make sure you hover one finger over the Engine Shut-off Key (Spacebar for #1, “\” for #2). You are going to need this, a LOT. This just cuts the Throttle to zero instantly, and can get you out of trouble when the heli is going out of control.
  • Throttle: This doesn’t work like on the original controller — this is increased/decreased in steps, and the throttle level is maintained until you change it. Press “1” or ”]” to increase the throttle, and “2” or “[“ to decrease it. Remember, you can always kill the throttle with the Engine Cutoff key.
  • Yaw: Unlike the original controller, this will make your heli turn at a constant rate. Generally this isn’t hard to adjust to, the original controller wasn’t exactly that great either — it’s just more coarse this way.
  • Pitch: Again, this will control the heli’s Pitch at a fixed rate (unlike the variable rate on the original controller).
  • Pro-tip: You probably want to hold it in one hand at first (or have someone else hold it) while you increase the throttle enough for it to hover — using the keyboard can be so slow/clumsy that you wont be able to increase the throttle enough not to send the heli careening off due to wake turbulence near the ground, or slam into the ceiling by overcompensating.

The Controller Hardware

The controller hardware is super simple — just an Arduino UNO and a few LEDs. As I’ve been playing with IR a fair bit, I wanted something a little more robust so I put the LEDs and a couple status LEDs on some Veroboard with some pin-header — we’ll (very generously) call it the “IR-Shield”

The “IR Shield”

IR_Shield

Please excuse the awful soldering.

Schematic:

IR_Shield_Schematic

Bill of Materials:

A few notes on the design:

  • The IR LEDs are wired in series, NOT independently. This is because the reason for two LEDs is for maximum coverage of transmission, not to control one helicopter per LED.
    As I discovered in the protocol reversing, the interval between control packets is surprisingly long, so I found that simply alternating between channel A & B on each loop was more than fast enough to maintain consistent control over both heli’s.
  • As you can see in the photos, I soldered to the Veroboard upside down — this was to accommodate the pin headers which aren’t easily soldered to the Veroboard the right way round (in a Shield-like configuration, at least).
  • The status LEDs are connected to pins 8 and 9 of the Arduino, whilst the IR LEDs are controlled by pin 12.
  • If you look closely at the top right image, I used to use some hot glue as an insulating buffer so the few leads that protrude (ever-so-slightly) didn’t short out to the metal casing of the Arduino’s USB port. Ugly, but functional.
  • The IR LEDs are bent at approximately 45 degrees-ish in opposite directions to maximize their coverage area.

The Controller Sketch

You can download the Arduino IDE sketch here:

The design goals of the Arduino controller sketch were as follows:

  1. To be atomic, and not rely on constant communication from the head-end (PC) to operate.
    This is to ensure simplicity and efficiency in the relationship between the head-end and the microcontroller. I don’t want to have to worry about synchronization of the control messages, filling up the Serial buffer, etc… I just want simple and efficient interactions.
  2. To provide a straight-forward interface to build future work upon.
    Being able to control the choppers with a computer begs for all sorts of great hacks like autopilots, flying Helicopters over IP (HoIP, or really-remote control…), etc…
  3. To be as efficient as possible, given the Arduino’s limited processing power.

    This was due to a lesson learned in an earlier controller project which was woefully inefficient — the helicopter is extremely clumsy when the Arduino can’t keep up with a poorly written sketch!

  4. To reflect the protocol definitions identified during reverse-engineering as closely as possible.
    No sense wasting all that work by using loose timings, eh!

The basic system flow is depicted here:

Controller_Flow_2

This design satisfies the requirements as follows:

  • The controller is atomic and independent (#1) as the head-end only has to be concerned with sending changes to the control registers and doesn’t require continuous synchronous communications to operate. The controller will continue to transmit the values for each control axis until they are changed.
  • The way the control sequences are designed makes implementing the interface on any head-end application very easy (#2). The first value (0, 1, or 2) indicates what type of message it is (helicopter A or B control, or a Sync signal), the second identifies the control axis to update, and the third value is the axis’ new parametric value. A truth table of the control messages can be found below.
  • Using short control sequences, only transmitting changes in control axis values from the head-end (instead of full Syma control packets or whatever), and mostly efficient techniques to construct and transmit the control packets, the Arduino has no issue keeping up with even periods of intense control changes (#3).
  • Other than having to tweak the timings due to the Arduino’s oddly slow pin transition times, the controller sketch implements the definitions I arrived at through reversing nicely (#4).

Controller Interface Truth Table

All you have to do to interface with the controller from any head-end application you want is to send a message sequence consistent with the following table via the Serial connection. Each message should be sent on a consecutive line:

Truth_Table(click to enlarge)

An example of a control sequence from the head-end might be:

Message 1: "0" - Helicopter A
Message 2: "2" - Change Pitch...
Message 3: "98" - ...to the value "98".

The Controller Application

GUI_Controller

The controller app is written in Processing and uses the ControlP5 GUI library for windowing, etc… The application is very simple and can be split up into 3 major parts: setting up and rendering the GUI, setting up the key-press event listeners, and the subroutines for sending the control updates to the Arduino.

The GUI is super simple — I experimented with having sliders for helicopter control, but it is SO clunky that it’s suicidal. One of the major things was that without some sort of feedback and a PID control routine for maintaining a steady altitude, controlling the other flight axes with GUI controls is far too slow to not crash and burn pretty quickly. So the GUI ended up as instructions and a basic set of feedback on what the current control values are.

The input mechanism ended up being a mixture of aggregating key presses (for things like the throttle where granular control is important), and toggling key presses (for things like Yaw and Pitch, where the keyboard is too clunky for granular control). Aggregate controls either add or subtract from the current control value. Toggle controls just jump to a preset value when pressed, and back to the center value. Ultimately, it turns out that the keyboard ROYALLY SUCKS for piloting helicopters — this is why I had to have an emergency engine cut-off key.

Using the Serial library, we can very simply communicate with the Uno and send the control messages in the format described above. As the coupling between the head-end and the controller is asynchronous and loose, this is basically all we have to do — nice and simple!

Code and Downloads

The Arduino Uno sketch (zip):

UNOr3_Syma107G_Dual_Heli_Controller_JimHung_com

The Processing sketch & 32/64-bit Windows Binary (zip):

JimHung_Processing_Dual_Helicopter_GUI

Conclusion

I hope this has been informative and useful for anyone interested in playing with Arduinos and these awesome helicopters. The control scheme design is very flexible and can be implemented with all sorts of head-end applications. I’ve toyed with the idea of autopilots, flight paths, choreographed flights with 2 heli’s — all of which are possible (with varying degrees of complexity). The controller communication scheme means that in these projects, sending commands to the helicopter is all but taken care of.

If anyone wants to give it a go and has any trouble, please don’t hesitate to pick my brain in the comments. Stay tuned for more reverse-engineering fun.


Syma 107G Controller Library

After my work on the Syma 107G was featured on Hackaday, [Maksim] emailed me to talk about writing up a programming library for the Syma 107 control protocol that would allow someone to control an RC boat, car, etc… with the S107T2 controller. I thought this was a cool idea, so I gave it a shot […]


Reverse-Engineering a Syma 107 RC Helicopter

The Syma 107 RC helicopter is a pretty great gadget, all things considered — it’s cheap, fun, and ridiculously good for the price. It’s also a spectacular gadget for fledgling hackers. ** 1-26-2013 UPDATE — I’ve written up a full protocol specification for the Syma 107G — If you are here looking for a purely […]


I Love Etsy, Part II!

After the last crazy awesome drawing, I had my eye on a set of Laurel & Hardy films from A Whiter Shade Of Pale… I thought I’d try my luck with the next installment in the Dragon saga. This is what was waiting for me when I got back from China (click to enlarge!): I’m […]


I love Etsy

I recently ordered a Super 8 projector (a Bell & Howell 357B) to spur me on to finish a super 8 short with my Canon 814 — I thought I’d have a little fun with the order details… (click to expand) How awesome is that! Thanks to Awhitershadeofpale for taking the time and effort to […]


Red Bull Soapbox Derby 2011

Because it was such a gorgeous day and to test drive my new Canon 7D, Andy and I drove into Downtown L.A. for this year’s Red Bull Soapbox Derby. It’s actually the first time I’ve been back to Downtown since last March, it hasn’t changed much.. ..Although having said that, the place was completely overtaken […]


Stuff and that, yeah?

Since moving to LA, I’ve been able to indulge myself in some (mostly quite eccentric) consumerism, and have treated myself to some fun stuff: A vintage typewriter. I feel like emails, facebook, IM’s, etc… are a bit boring and disposable; you never really need to put any amount of effort and thought into what you write. […]


I’ll get a Wimpy…

A few weeks ago, Mehreen flew out to L.A. to see me, which I was really looking forward to. I’ll probably make another post about that, but in the meantime, bask in the glory of us crossing off a pretty epic (and esoteric) entry in our to-do list. To give a little background, the first time […]


Telegram.


El-Eh?

I took advantage of the nice weather (blue skies, like every day since I arrived) and spent the day on the beach at Santa Monica.  I rather enjoyed the sea air and that. Almost makes up for the fact that americans don’t get a 4 day weekend for easter :’( I stopped by the Apple store on […]