Introduction: KIVI (Leap Motion Controlled Arduino Vehicle)

Hey kiwis!

This is an Instructable on how to to construct a Leap Motion and Arduino controlled Kinetic Vehicle (or KIVI for short!). The Leap Motion Controller is a device specialized for tracking hand movements. We use the Leap to track our hand positions and convert those into instructions to move the car. The Arduino receives coordinates from the Leap Controller through an IDE called Processing, which transmits the data in form of bytes through the Serial Channel! The Arduino IDE is where we write code for what we want the Arduino to do and then the code is uploaded to the Microcontroller board!

We were surprised to find out that the Leap, being the powerful device it is, hasn't been in much use lately so we decided to have fun with it.

Step 1: WHAT WE NEED:

To build this Leap Motion Controlled Arduino Car, you will need:


  • 1x Leap Motion Controller

https://store-world.leapmotion.com

  • 1x Arduino Uno (or an Arduino Mega)

https://goo.gl/QyCNa1

  • 1x USB to UART TTL Serial Cable

https://goo.gl/AuPN6E

  • 1x HC - 05 Bluetooth Module

https://goo.gl/DX1WvL

  • 1x L293D Motor Driver IC (Dual H-Bridge Motor Controller)

https://goo.gl/GWu9T6

  • 2x DC Carbon Brush Motors

https://goo.gl/voJQDJ

  • 1x RC Car Chassis

https://goo.gl/jqEGmg

  • 2x 9V Batteries

https://goo.gl/y48Ukg

  • 2x Battery Caps

https://goo.gl/Q84mGj

  • Many Male to Male Jumper Wire

https://goo.gl/xLnKXy

That's about it!

Step 2: OTHER IMPORTANT TOOLS:

To build this project successfully, you will also need:

  • Double Sided Tape
  • A Multimeter
  • A Laptop

You will also need these important Softwares:

    • Processing IDE

    https://processing.org/download/

    1. Leap Motion for Processing Library
    2. Serial library
    • Arduino IDE

    https://www.arduino.cc/en/Main/Software

    1. Software Serial Header File

    And the most important thing of all:

    RECKLESS AND UNYIELDING OPTIMISM!

    Step 3: WHAT WE WILL BE MAKING:

    This is an introductory video to the what the project would look like!

    Step 4: THE CODE:

    The code is divided into two parts:

    Processing:

    import de.voidplus.leapmotion.*;
    LeapMotion leap;
    
    import processing.serial.*;
    Serial myPort;
    
    int voltagex;// From X-Axis
    int voltagez;// From Z-Axis
    
    void setup()
    {
      size(800, 500, P3D);
      background(255);
      noStroke();
      fill(50);
      
      myPort = new Serial(this, Serial.list()[0], 9600);
      System.out.println( Serial.list()[0]);// Check your Port!
    
      leap = new LeapMotion(this);//Declare the Leap device!
    }
    
    void draw() 
    {
    background(255);
    
    // int fps = leap.getFrameRate(); 
    
    /*
    The fps variable and this method was causing issues for us
    But maybe try uncommenting it and it might work out well for you.
    */
    
    for (Hand hand : leap.getHands()) 
    {
    float   handGrab           = hand.getGrabStrength();
    PVector handStabilized     = hand.getStabilizedPosition();// Get the hand coordinates! 
    
    voltagex = (int) map(handStabilized.x, 0, 700,-254,255);// Get the x coordinate and scale it
    
    if(voltagex>255)//Setting boundaries, so the values dont go beyond the range.
     voltagex=255;
    else if(voltagex<-255)
     voltagex=-255;
    
    voltagez = (int) map(handStabilized.z, -20, 80, -254,255);// Get the z coordinate and scale it
    
    if(voltagez>255)
     voltagez=255;
    else if(voltagez<-255)
     voltagez=-255;
    
    System.out.println("this is x "+voltagex);
    System.out.println("this is z "+voltagez);
    
    if(handGrab>0.85)  // To implement the Grab gesture
    {
    myPort.write("0 0");//Apply Brakes by grabbing!
    handGrab = hand.getGrabStrength();
    }
    
    
    String out= str(voltagex) + ' ' + str(voltagez);//Convert the coordinates to String.
    
    myPort.write(out);//Send out the String as Bytes through the COM Channel (for us it was COM9, may vary)
    System.out.println(out);
    
    hand.draw();
    
    }
    
    
    }
    
    void leapOnInit() {
    
    }
    void leapOnConnect() {
    
    }
    void leapOnFrame() {
    
    }
    void leapOnDisconnect() {
    
    }
    void leapOnExit() {
    
    }


    Arduino:

    #include <SoftwareSerial.h>
    
    SoftwareSerial Genotronex(10, 11);  //Define the RX and TX pins!
    int BluetoothData; 
    
    int x_coord= 0; // Controls Turning (Sign: Wheel | Magnitude: Acceleration)
    int z_coord= 0; // Controls Movement (Sigh : Forward/Reverse | Magnitude : Acceleration)
    
    void setup()
    {
    Genotronex.begin(115200);
    
    pinMode(6, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(3 ,OUTPUT);
    pinMode(5 ,OUTPUT);
    }
    
    void loop() 
    {
    
      Brake();
    
    while (Genotronex.available())
    {
    digitalWrite(13, HIGH);
    
    // X coordinate received from Leap
    x_coord = Genotronex.parseInt();
    
    // Z coordinate received from Leap
    z_coord = Genotronex.parseInt();
    
    if(z_coord >=0) // Move Forward 
    {
      if(x_coord>=0)//Right
      {
         Forward((255-x_coord), z_coord); // Slow Down Right Wheel
        }
       else//Left
      {
         Forward(z_coord, (255+x_coord)); // Slow Down Left Wheel
        }
     
      }
    else // Backward
    {
      z_coord = (-1)*z_coord;
      
      if(x_coord>=0)//Right
      {
         Backward(z_coord, (255-x_coord));// Slow Down Right Wheel
        }
       else//Left
      {
         Backward(255+x_coord, z_coord); // Slow Down Left Wheel
        }
      
      }
      //delay(100);
    }
    }
    
    void Forward(int Wheel_Left,int Wheel_Right)
    {
      analogWrite(3, 0);
      analogWrite(5, Wheel_Left);
      
      analogWrite(9, Wheel_Right);
      analogWrite(6, 0);
    }
    void Backward(int Wheel_Left, int Wheel_Right)
    {
      analogWrite(3, Wheel_Left);
      analogWrite(5, 0);
      
      analogWrite(9, 0);
      analogWrite(6, Wheel_Right);
    }
    void Brake()
    {
      analogWrite(3, 0);
      analogWrite(5, 0);
      
      analogWrite(9, 0);
      analogWrite(6, 0);
      }

    Step 5: THE CIRCUIT:

    Step 6: MAKING THE CIRCUIT:

    THINGS TO REMEMBER WHILE CONNECTING THE CIRCUIT:

    1. Make proper use of the Multimeter to check the connections frequently! (wouldn't want to have faulty connections while testing!)
    2. In case the two wheels don't rotate in the same direction, interchange the two wires of any one of the motors.
    3. Make sure the Tx and Rx pins of the Bluetooth module are rightly connected.
    4. It is preferable to make use of a light chassis. Otherwise, a higher power supply will be needed in order to power up the wheels which could potentially fry up the Arduino.
    5. Voltage regulators could be used if the power supply exceeds recommended values.

    Step 7: TESTING:

    Here's a motor test that we like to run to help with calibration.

    Arduino:

    //MOTOR TEST
    
    
    #include <SoftwareSerial.h>
    SoftwareSerial Genotronex(10, 11);  //Define the RX and TX pins!
    
    int x=0;
    void setup()
    
    {
    
    pinMode(6, OUTPUT);
    pinMode(9, OUTPUT);
    pinMode(3 ,OUTPUT);
    pinMode(5 ,OUTPUT);
    Genotronex.begin(9600);
    }
    void forward()
    {
      digitalWrite(3, LOW);
      digitalWrite(5, HIGH);
      digitalWrite(9, HIGH);
      digitalWrite(6, LOW);
    }
    void backward()
    {
      digitalWrite(3, HIGH);
      digitalWrite(5, LOW);
      digitalWrite(9, LOW);
      digitalWrite(6, HIGH);
    }
    void brake()
    {
      digitalWrite(3, HIGH);
      digitalWrite(5, LOW);
      digitalWrite(9, LOW);
      digitalWrite(6, HIGH);
    }
    
    void loop()
    
    {
      while(Genotronex.available()>0)
    {
      
     x= Genotronex.parseInt();
     if(x==8){
     Serial.println("FORWARD");
     forward();
    }
      else if(x==2){
      Serial.println("BACKWARD");
      backward();
    }
       else if(x==0){
       Serial.println("BRAKE");
       brake();
    }
    }
    
    }
    

    This code works with the Serial Monitor on the Arduino IDE to test the motor function.

    "DO MOTOR TESTS BEFORE THE LEAP TESTS!!"
    ~Prabhav Bhatnagar

    Step 8: HOW IT WORKS:

    Now that we're done with all the connections and testing, let's understand how your KIVI works :

    Processing receives the 'x' and 'z' coordinates from the Leap Motion Controller, maps them to values in the range of (-256, 255) and appends them to a string. This string is converted into bytes and sent to the Arduino via the Bluetooth Module.

    The String received by the Arduino is parsed into Integer. The circuit is mapped such that the positive and negative values in the Z-Axis control the direction of the KIVI, i.e., forward or reverse. For this to work, we pass the values we receive through the H-bridge, which directs the motor spin. For more details, refer to the following guide:

    http://www.modularcircuits.com/blog/articles/h-br...

    The positive and negative values in the X-Axis steer the vehicle. This is achieved by appropriately regulating the speed of the individual wheels. (Refer code)

    We have also implemented Gesture Control where we used the Leap Motion Sensor's functionality of detecting various features (here, the Grab Strength) to implement Braking.

    Step 9: WHAT NOT TO DO:

    This is a list of things that just don't work, we found it out the hard way:

    1. Avoid a heavy chassis if possible (especially if the batteries aren't that powerful).
    2. Use good quality batteries. Cheaper ones may run out fast and will definitely cause problems with the Bluetooth module. TRUST US!!
    3. Always make sure to check the wires and all the connections with the Multimeter.
    4. Don't get distracted easily. We know we did :/
    5. If the Leap stops working, or it's powered but you cant see the IR LEDs light up, then make sure to uninstall and reinstall the Leap Controller Software.
    6. We notices that Chrome takes to much RAM and may cause problems with the Processing sketch, we found it best to have it closed during the development period.
    7. Use Tinkercad for online simulations before you actually assemble the circuit
      https://www.tinkercad.com/

    GOOD LUCK!!

    Step 10: THE FINALE:

    MEMBERS OF THE PROJECT TEAM:

    • PRABHAV BHATNAGAR
    • AARYAN DEHLOO
    • NITYA BASKAR
    • YUGVIR PARHAR
    Arduino Contest 2017

    Participated in the
    Arduino Contest 2017

    Remote Control Contest 2017

    Participated in the
    Remote Control Contest 2017

    First Time Author Contest 2018

    Participated in the
    First Time Author Contest 2018