Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

RC Helicopter, Arduino and of course, the Kinect

Today's project in a cool inspirational Kinect to Arduino to Helicopter hardware project...

Flying a S107 RC Helicopter using the Microsoft Kinect and the Arduino Uno

Flying a S107 RC Helicopter using the Microsoft Kinect and the Arduino Uno.

The Kinect detects my hands, head, and hips. This information is translated into x, y, z coordinates, processed with some 7th grade Algebra, and then sent to the Arduino over the serial port. The Arduino receives the signal, and converts it to a 38 kHz Infrared signal that the S107 can understand.

I've provided more information on this page: codingfun.collinboy.net

Hope to have this demo and other cool gadgets at the Kitsap Maker Festival in June!

Final note: The "I did it" line at the end of the video is in memory of my son Collin. I'd give all this up to have you back kiddo!

...

How to fly a S107 helicopter with the Kinect?

  • You will need a Kinect with power adapter to connect to a Windows 7 (or 8) computer. Xbox Kinect or Windows Kinect will work.
  • You will need an Arduino Board.
  • You will need various resistors, transistors, IR LEDs.
  • You will need some creativity.

This is not a step by step tutorial. I will provide the Arduino code that gets the Helicopter flying, but the rest is up to you to be creative.
So let’s get to the hard part first. Getting the Arduino to talk to the S107. The S107 speaks a specific language transmitted over a 38 kHz signal.
The signal structure that I used for the S107 is as follows:
(Note: Channel "A" uses Throttle Values 0 to 127. Channel "B" uses Throttle Values 128 to 255.)

  1. Start Signal: 2000 us
  2. Pause: 2000 us
  3. Rudder Signal: 8 bits of transmission (for example 127 is "01111111", 63 is "00111111")
  4. Elevator Signal: 8 bits of transmission
  5. Throttle Signal: 8 bits of transmission
  6. Trim Signal: 8 bits of transmission
  7. End Signal: 300 us

With that, let’s look at the code: Here is a nice formatted link to the Arduino File.

...

As you can see, all you need to do is feed the void Transmit() with integer values between 0 and 127 (or 128 to 255 for Channel "B" ). Do this from the void loop().

You can actually alternate between the "A" and "B" channel without any problems (that I've encountered).

You may also see that there is no code in there for communicating with the Kinect. I wanted to give a clean version of the S107 code. The Kinect serial input requires more code in the void loop().

Reading from the serial is a lot of hassle. I will make an update soon to explain how to read from the serial port.

For the Kinect project, I used the Microsoft Kinect SDK software to determine the location of my hands relative to head and hips. This gave me a y-coordinate distance that could be scaled from 0 to 127.

The Kinect can also be used to measure distances relative to the sensor. Again, this data can easily be converted to scaled z-coordinate values between 0 and 127.

The fun part was determining the best use of x, y and z coordinates. You only have 2 hands, so controlling a 3 channel Heli takes some thinking.

Also fun is determining how to initialize the Heli (interlocks to avoid premature takeoff) and how to incorporate a kill switch.

I hope that this will help inspire some creativity to use the Kinect with the Arduino boards.

Project Information URL: http://codingfun.collinboy.net/, http://www.youtube.com/watch?feature=player_embedded&v=hfqh46s-BPM [Project found via Kinect Gesture-Controlled RC Helicopter]

Project Download URL: http://codingfun.collinboy.net/

Project Source URL: http://codingfun.collinboy.net/

// Connect (+) of IR LED to 5Vcc
// connect (-) to pin 4 with a 100 Ohm resistor in line.  For best results make a transistor circuit with external power source

#define RED 4    // the output pin of the IR LED

void setup() {
    pinMode(RED, OUTPUT);    // set IR LED (Pin 4) to Output
}

void loop() {
//Do you magic here.  The code directly below just throttles up to 60 and back down to 0.  
//You can get data from the serial port, a joystick, or whatever.  You just need to translate your input into values between 0 and 127.
//Pass those values to Transmit( ) as an integer between 0 and 127 and that's it!

    int t;
    for (t = 0; t < 40; t++) {
        Transmit(63, 63, t, 63);  //Rudder = 63, elevator = 63, throttle = t, trim = 63
             // Transmit(63, 63, ((40 - t) + 128), 63); //This would cause Channel "B" to throttle down

    }

    for (t = 40; t > 0; t--) {
        Transmit(63, 63, t, 63);
             // Transmit(63, 63, ((40 - t) + 128), 63); //This would cause Channel "B" to throttle up 
    }
} //End loop()

void Transmit(byte rudder, byte elevator, byte throttle, byte trim) {
    static byte Code[4];
    byte mask = 128;     //bitmask
    int i;

    Code[0] = rudder; // 0 -> 127; 63 is the midpoint.
    Code[1] = elevator; // 0 -> 127; 63 is the midpoint.
    Code[2] = throttle; // 0 -> 127; 0 is throttle off
    Code[3] = trim;    // Haven't messed with this
    
    OutPulse(2002);  // Start 38Khz pulse for 2000us (2002us is evenly divided by 26)
    delayMicroseconds(2000);  // 2000us off.

    for (i = 0; i<4; i++) {        // Loops through the Code[]
        for (mask = 128; mask > 0; mask >>=1) {    // See Arduino reference for bit masking (really cool stuff!)
        OutPulse(312);         // Sends 312 pulse each loop

            if(Code[i] & mask) {          //If both bit positions are 1 you get 1              
                delayMicroseconds(688);     // send 1 (700 off)
            } 
            else {
                delayMicroseconds(288);     // send 0 (300 off)
            }
        } //End mask loop
    }  //End i loop

    OutPulse(312);  //Send 300 microsecond Closing Pulse
    delay(60);       

} // End Transmit


void OutPulse(int Pulse) {  //sends 38Khz pulses over the Pulse Length
    int p;

    for(p = 0; p < (Pulse / 26) - 1; p++) {  //Takes about 26 microseconds per loop
        digitalWrite(RED, HIGH);
          delayMicroseconds(10);
        digitalWrite(RED, LOW);
          delayMicroseconds(10);
    }
}  //End OutPulse

Tags:

Follow the Discussion

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.