The Memoirs of Jim 'ung

Syma 107G Controller Library

Syma 107G Controller Library

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 – here’s the lowdown on SymaLib.

Download & Requirements

Get the SymaLib library (v0.1) here. The library was written for the Arduino IDE v1.1 and is designed for use with a sketch similar to Adafruit’s IR Commander sketch (reference, github).


I started with the excellent Adafruit Industries IR Commander sketch as it is easy to understand and takes care of populating an array with the on/off pulse lengths for me. With this raw material, all the SymaLib library has to take care of is parse the received pulse lengths into their respective bit-wise values and provide a series of methods to get the parsed values of the handset’s controls.

Version 0.1 currently allows you to parse the 32-bit control packets from the S107T2 controller (described in my protocol spec: here) and return each control value as an integer.


SymaLib Library Example v0.1 by Jim Hung (

 This example code is designed to demonstrate the usage of the SymaLib
 to decode control signals from a S107T2 RC helicopter controller.

 Based on 'Raw IR commander' by Ladyada:

   "This sketch/program uses the Arduno and a PNA4602 to
   decode IR received.  It then attempts to match it to a previously
   recorded IR signal

   Code is public domain, check out and
   for more tutorials!"

#include  // include the SymaLib library

#define IRpin_PIN      PIND
#define IRpin          2

#define MAXPULSE 2000
#define NUMPULSES 50

#define RESOLUTION 20
#define FUZZINESS 30

uint16_t pulses[NUMPULSES][2];  // pair is high and low pulse
uint8_t currentpulse = 0; // index for pulses we're storing

SymaLib protocolparser; // declare our SymaLib object

void setup(void) {

  Serial.println("Ready to decode IR!");

void loop(void) {

  int numberpulses;
  String ctrldata = "";

  // Listen for IR signals and populate the array of pulse lengths

  numberpulses = listenForIR();

  // Give the SymaLib object the pulse array to parse. If it's a valid Syma107
  // control packet, SymaLib returns boolean True.

  boolean result = protocolparser.setPulseListParse(pulses,numberpulses,RESOLUTION,FUZZINESS);

  if (result) {

	// Read the controller values and do whatever you need to with them.

	  // This example prints out the integer values for each control:

    Serial.print(" Yaw: ");
    Serial.print("\tPitch: ");
    Serial.print("\tChannel: ");
    Serial.print("\tThrottle: ");
    Serial.print("\tTrim: ");

	  // This example prints out the binary values for the 32-bit control packet:



int listenForIR(void) {
  currentpulse = 0;

  while (1) {
    uint16_t highpulse, lowpulse;
    highpulse = lowpulse = 0;

    while (IRpin_PIN & _BV(IRpin)) {


       if (((highpulse >= MAXPULSE) && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse;

    pulses[currentpulse][0] = highpulse;

    while (! (IRpin_PIN & _BV(IRpin))) {


        if (((lowpulse >= MAXPULSE)  && (currentpulse != 0))|| currentpulse == NUMPULSES) {
         return currentpulse;
    pulses[currentpulse][1] = lowpulse;


Library Reference

Here are the methods provided by the SymaLib library:


Constructor. No arguments – initializes control byte array.


Returns: Boolean


uint16_t pulses[][2] – The pulse array populated by the ‘listenForIR’-like method.

int& numpulses – The number of pulses heard by the ‘listenForIR’-like method.

int resolution – The RESOLUTION constant used to calibrate the IR listener.

int fuzziness – The FUZZINESS constant used to calibrate the IR listener.


This method parses the pulse-array and stores it as an array of integers, either 1 or 0. This array is the basis of the object’s Get methods.


Returns: Int

Arguments: None.


Returns an integer of the decimal value of the Yaw control.


Returns: Int

Arguments: None.


Returns an integer of the decimal value of the Pitch control.


Returns: Int

Arguments: None.


Returns an integer of the decimal value of the channel switch.


Returns: Int

Arguments: None.


Returns an integer of the decimal value of the Throttle control.


Returns: Int

Arguments: None.


Returns an integer of the decimal value of the Trim control.


Returns: String

Arguments: None.


Returns a String of ‘1’ and ‘0’s representing the 32-bit control packet. Useful for debugging.


This is the first Arduino library I’ve ever written (hopefully not the last!) and I hope it is useful for other hackers. [Maksim]’s idea was cool and I’d love to see any projects that end up using it. Let me know in the comments!

Take care,


7 thoughts on “Syma 107G Controller Library

  1. roberto

    I wonder if the serout serin MBASIC commands used in programming Microcontrollers efficiently implement the Syma 107 control protocol .I work with Microchip uCs because of lack of other family types on the local market.
    Best regards

    1. Jim Post author

      Hey Roberto – I’m certain you could implement the protocol with a PIC/Microchip uC, all you need to do is have a control loop to sample (if you’re using analog electronic control inputs) or convert (if you’re using a computer/keyboard) your control values, then construct a 32-bit serial data packet. Then all you have to do is flash an IR LED according to the 0 or 1 symbols, and you’re in business. I’m about to post the code I use on an Arduino Uno which should make it pretty easy to see how I went about it. Best of luck!

  2. roberto

    Hi JIM,
    Thank you for the reply.I wonder if you already cooked the code for Microchip uCs.I have a problem of synchro and gliches.
    I am working on a project for students for autonomous hovering Quadrotor maintaining the altitude fixed for let say 10m while making use of an ultrasonic transducer for height measure.

    1. Jim Post author

      Hey Roberto – that project sounds great! What Quadrotor are you using? I’m just finishing up a series of in-depth posts on hacking and re-implementing the 2.4Ghz protocol for the Hubsan X4 micro-quadcopter – maybe that’ll be of interest to you.

      As for the Microchip code for the Syma S107G, I’m afraid I haven’t got any code for that as I don’t have any PIC microcontrollers to play with. Having said that I’ve done a quick search on the MBASIC language and specifically ‘serout’ – I don’t know if serout will work as it’s intended for RS-232 communications. What I would do is create a subroutine that generates the 38khz modulated carrier for X number of milliseconds. To do this you have to work out how quickly you need to strobe the IR LED pin on and off for your processor clock speed but it should be pretty straight forward – you will probably need to tweak the timings based on the transition times to get a tight carrier. Then you just need to create your control packets and transmit the data in series using the strobe subroutine. My sample Arduino code should be readable enough to get an idea of what I mean:

      Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *