Related Posts Plugin for WordPress, Blogger...
This form does not yet contain any fields.

    Follow Me on Pinterest

    Our products are on iTunes!

     Nanaimo Studio

    Find us on Google+ 

     

    We are listed on: Dmegs Link Directory

    Blog Index
    404 page

    Entries in arduino (4)

    Wednesday
    Jan092013

    Unity 3D iOS apps with JOY(STICK)

    In the last tutorial , we used a joystick to control an iOS space shooter game, I hope you had fun with it. This time around, we are going to use joystick to control a 3D iOS App made in Unity3D. Here is a demo video of the final product.

    Assumptions

    1. You are somewhat familiar with Unity's GUI. No previously coding experiences in Unity is assumed.
    2. You have heard about Arduino. No coding experience in Arduino required.
    3. Basic Understanding of Objective-c & iOS application development

    The Big Picture

    The idea of this tutorial is to use an Arduino Joystick to wirelessly control a character in Unity 3D and run the app on iPhone. In order to accomplish this, there are several things we need:

    1. Arduino: get joystick data and button data and broadcast it with UDP protocol.
    2. Xcode data receiving interface: Our Open Source RedButton API provides a delegate method to easily retrieve Joystick data broadcasted from the Arduino joystick.
    3. Unity Plugins for iOS: Once our iPhone receives the Joystick data, it need to send data from our Objective-c code to Unity code, so the joystick position can control the character in Unity.
    4. Unity 3D application: A character in Unity that can move forward, backward, left and right in response to our Joystick data.

    Arduino

    This part is exactly the same as the Hardware, Arduino program section in the previous blog You can upload the same code (Under Arduino folder) to your arduino board.

    2012-07-15 16.50.09

    Xcode data receiving interface

    The RedButton API is used to receiving Joystick data from Joystick. This is an API we developed and used in our [iOS Games with Joy(stick)] tutorial. Follow the RedButton API Introduction section in the blog if you haven't used it before.

    Unity Plugins for iOS

    One of the main issues you may ask is how do you send Joystick data to Unity. Luckily for you, Unity describes a way to do just that in their official documentation. You can take a close look at Unity's build native code plugins for the iOS platform [here]. or you can follow the instruction below.

    Three steps from the official documentations:

    1. Define your extern method in the C# file like follows:

      [DllImport ("__Internal")]
      private static extern float FooPluginFunction ();
      
    2. Set the editor to the iOS build target

    3. Add your native code source files to the "Classes" folder

    In the RedButton API, we have defined several delegate methods to receive data from Arduino. Now we just need to add a layer on top of RedButtonAPI layer so it can send messages to Unity. Let's call this transition layer SendToUnity. The SendToUnity.h and SendToUnity.mm was defined for this purpose. SendToUnity Class is the transition layer: it sends data received from RedButtonAPI class to Unity.

    Let us apply those steps in this project:

    Here we use Joystick X axis data as an example to go through each line of code in both the Objective-C and Unity code. The Joystick Y axis data and the A,B,C buttons is similar to Joystick X axis data. The whole file of SendToUnity.h & SendToUnity.mm file can be downloaded from [here](Under Xcode file folder)

    1. In Xcode, SendToUnity.h file add a float property x to save joystick x axis data.

      #import <UIKit/UIKit.h>
      #import "RedButtonAPI.h"
      @interface SendToUnity : NSObject<RedButtonAPIDelegate>
      @property(nonatomic) float x;
      @end
      
    2. In SendToUnity.mm file

      #import "SendToUnity.h"
      #define kJoystickCenterX 50
      @implementation SendToUnity
      @synthesize x;
      -(id)init{
          if (self = [super init]) {
              RedButtonAPI *redButton = [[RedButtonAPI alloc] init];
              redButton.delegate = self;
          }
          return self;
      }
      - (void)joystickDataofX:(NSString *)xData Y:(NSString *)yData{
          self.x = [xData intValue];
      }
      @end
      
      
      static SendToUnity *tmp = nil;
      
      
      extern "C" {
          float RedButtonJoystickX(){
              if (tmp == nil) {
                  tmp = [[SendToUnity alloc] init];
              }
                  return (tmp.x-kJoystickCenterX)/kJoystickCenterX;
          }
      }
      

    The SendToUnity.mm file defined a constant to store Joystick's center value. In its init method, we instantiate a RedButtonAPI object and set its delegate to SendToUnity.

    Then, joystickDataofX:Y: delegate is used to receive the axis data. The last extern "c" part is necessary in order for Unity to call and get the return value.

    Note that we use (tmp.x-kJoystickCenterX)/kJoystickCenterX equation to normalize the return value to a range between -1 to 1.

    3.In Unity, if you want to call RedButtonJoystickX methods, you need to defined it in the c# file like so:

        [DllImport ("__Internal")]
        private static extern float RedButtonJoystickX();
    

    The method can then be called as if it is an internal Unity method:

        float fA = RedButtonJoystickX();
    

    Unity 3D application

    OK. Now the issue about send data from Joystick to Unity is solved, the next step is to build the Unity app.

    In this app, we reused some source files from Unity's official tutorial called Penelope. Speaking of which, If you are going to create a third person game in Unity, Penelope tutorial is really a MUST read.

    1. Download and import Resources file from [Penelope tutorial].

    2. Create a new project named NewPenelope

    3. Create a Plane via Unity->GameObject->Create Other->Plane. Drag & Drop the grass1TGA file onto Plane to set the grass ground. Set Position to 0,0,0 & Scale to 10,10,10 as the image below.

    Screen Shot 2012-08-12 at 11.50.52 PM
    1. Create a Directional light via Unity->GameObject->Create Other->Directional light. Make its position 0,0,0 and set its Rotation to 45,0,0

    2. Create Player Object via Unity->GameObject->Create Empty. Rename it to Player. In the Project Objects folder, choose penelopeFBX. Drag & Drop it onto Player to make it as Player's child object.

    3. Now comes the fun part. Let's add some scripts to our Player object.

    (1) Character Controller script

    Select Player in the Hierarchy, then using Component->Physics->Character Controller set the parameters as indicated in the screenshot below.

    Screen Shot 2012-08-12 at 11.57.04 AM

    (2) Animation Controller script

    For this one, use the same script in Penelope tutorial named AnimationController.js. This script will be attached to the Player object. This script plays the appropriate animations for Penelope and blends the animations. It also uses the character’s movement direction to determine which animation should be played.

    (3) Move script

    This is the main script we are using to control the Character.

        using UnityEngine;
        using System.Collections;
        using System.Runtime.InteropServices;
        public class Move : MonoBehaviour {
        //character variable stores the player
            public CharacterController character;
            //defined all objective-c side method as extern data
            [DllImport ("__Internal")]
            private static extern float RedButtonJoystickX();
            [DllImport ("__Internal")]
            private static extern float RedButtonJoystickY();
            [DllImport ("__Internal")]
            private static extern bool RedButtonIsButtonAPressed();
            [DllImport ("__Internal")]
            private static extern bool RedButtonIsButtonBPressed();
            void Start () {
                Screen.orientation = ScreenOrientation.LandscapeLeft;
            }
            void Update () {
            float fA = RedButtonJoystickX();
            float fB = RedButtonJoystickY();
            bool bC = RedButtonIsButtonAPressed();
            //use the Joystick X value to control Unity's X axis
            //use the Joystick Y value to control Unity's Z axis
            character.Move(new Vector3(fA,0,fB));
    
            //send a log output if button A is pressed.
            if(bC)
            {
                Debug.Log(bC.ToString());   
            }   
            }
        }
    

    7.Add script to Camera

    Add FollowTransform.js to Camera. This script makes camera follow the player when the player is moving to a different position. Here is the FollowTransform.js code:

        var targetTransform : Transform;        // Transform to follow
        var faceForward : boolean = false;      // Match forward vector?
        private var thisTransform : Transform;
        function Start()
        {
            thisTransform = transform;
        }
        function Update () 
        {
            thisTransform.position.x = targetTransform.position.x;
            thisTransform.position.y = targetTransform.position.y+2;
            thisTransform.position.z = targetTransform.position.z-3.5;  
            if ( faceForward )
                thisTransform.forward = targetTransform.forward;
        }
    

    This script sets the camera x as player x, camera y as player y + 2, camera z as player z - 3.5 so that the relative position of camera and player are always the same.

    8.Make all connections IMPORTANT

    In Camera's Follow Transform (Script), set Player as target like this:

    Screen Shot 2012-08-15 at 9.51.22 PM

    In Player's Animation Controller, Character Controller, Move (Script)

    Set all the connection and values as shown below:

    Screen Shot 2012-08-15 at 9.54.37 PM

    Summary: Steps to run the whole project

    1. Upload theArduino program to the Arduino board, make sure your connect Joystick Shield (top), WiFi Shield (middle), Arduino (bottom) in the right order and make sure the Red LED light is on (WiFi network is created)
    2. In your iPhone WiFi Settings select RedButtonAPI
    3. In Unity, click Build Settings, switch platform to iOS
    4. Click Build & run. It will open Xcode for you.
    5. In Xcode, select Run on device.
    6. That's it. It's time to use joystick to control your penelope.
    CameraRelativeSetup.unity - NewPenelope - iPhone, iPod Touch and iPad

    All files for this project can be found from [GitHub]

    I hope you found this tutorial useful.

    Thursday
    Jul262012

    iOS Games with Joy(stick)



    Playing games using controllers is nothing new for gamers with iOS devices. The controllers I am referring to are virtual joystick, accelerometer or gyroscope. But let's face it, playing games with fingers sometimes just doesn't feel the same without the physical touches of a joystick (there is a reason why we call it JOY stick!). This is something I sometimes miss when I play games on the touch devices.

    Fortunately, my college education hasn't gone to waste and it is being put to good use here. Instead of putting up with the constraint, I say we make a real joystick for our iPhone today!

    Let's start with our first goodie - the joystick. The joystick controller we are using in this project looks like this:

    2012-07-15 16.14.08

    Yes, we are using our lovely Arduino plus a WiFi Shield and a Joystick Shield. Don't miss our previous post on using Arduino to build an ultrasonic tape measuring device if you haven't read it.

    Hardware

    Connect three shields together.

    Three Shields: Arduino UNO (top left), WiFi Shield (top right), Joystick Shield (bottom)

    2012-07-15 16.50.09

    Attach the three shields together with JoyStick Shield at the top, WiFi Shield in the middle middle, Arduino at the bottom.

    2012-06-23 10.39.46

    That's it!!!

    Arduino program

    You can download the Arduino code that performs the UDP broadcast from here. In the git repo, there are two folders: RedButton API, WiShield. Make sure you have the newest version of Arduino IDE

    • Copy RedButton API to /Your local Arduino/ folder
    • Copy WiShield to /Your local Arduino/libraries/ folder

    Compile and upload RedButtonAPI file to your Arduion board

    The Arduino code create a local network named "RedButtonAPI" and broadcast its status to the network via UDP port 1234. The output format looks like: "id=1111,1,1,1,50,49," (The reason I add id field here is to help us detect reduntant data.) "1,1,1,50,49" coresponds to the values from ButtonA, ButtonB, ButtonC, JoystickX and JoystickY.

    You can download the joystick shield datasheet from here.

    Here is the schematic of the joystick:

    Screen Shot 2012-07-17 at 11.23.51 AM

    (Keep in mind which button is buttonA, buttonB or buttonC and the direction of Joystick X and Joystick Y)

    To complete all pieces of the puzzle, let's look at how we use RedButton API to enable the communication between the hardware and our iOS devices wirelessly.

    RedButton API Introduction

    RedButtonAPI is a static library that we created to enable communication between Arduino and any iOS device using the connectionless UDP protocol.

    NOTE: RedButton API was inspired by Amit Pitaru's work in the area of assistive technology.

    You just need two steps to use this API. Create a instance of RedButton API class and set it up to receive controller values via its delegate method.

    How to integrate RedButton API:

    1. Create a RedButtonAPI instance, set delegate to your self (self in this case is the HelloWorldLayer class)

      RedButtonAPI *redButton = [[RedButtonAPI alloc] init];
      redButton.delegate = self;
      
    2. Set up the delegate methods. There are six methods you should be aware of:

      - (void)receivedRawDataFromArduino:(NSString *)data;
      - (void)receivedRawDataFromArduinoWithRedundantCheck:(NSString *)data;
      - (void)buttonAPressed;
      - (void)buttonBPressed;
      - (void)buttonCPressed;
      - (void)joystickDataofX:(NSString *)xData Y:(NSString *)yData;
      

    In most use cases, you will just need last four methods. These methods tell you if A, B, C buttons are pressed and the current value of your joystick.

    Test driving RedButton API

    1. Download the API from github
    2. Download the SpaceShooter Game code from here.

      NOTE: Space Shooter is a cocos2d game developed by Ray Wenderlinch for one of his cocos2d game tutorials. Below is a video demo from Ray's tutorial showcasing space shooter. In this video you can see how the space shooter is being controlled via the use of tap and accelerometer.

      Let's take it a step further and use our own joystick to control Ray's ship!

    3. Drag two files (libRedButtonAPI.a, RedButtonAPI.h) into SpaceShooter Project, in Build Settings, set Compiler to Apple LLVM compiler 3.1

    4. In HelloWorldLayer.h, import RedButtonAPI.h, add delegate declaration
    5. In init method of HelloWorldLayer.m , create an instance of RedButtonAPI, set delegate to self
    6. In HelloWorldLayer.m, replace the ccTouchesBegan:withEvent: method with buttonAPressed method and keep the rest of the code intact. Essentially we are replacing the touch control with our joystick A button control.
    7. In init method of HelloWorldLayer.m, comment out self.isTouchEnabled = YES;
    8. In HelloWorldLayer.m, we are going to use joystick to control the position of our space ship:

      • Comment out accelerometer:didAccelerate: method
      • Add joystickDataofX:Y: method:

        - (void)joystickDataofX:(NSString *)xData Y:(NSString *)yData{
        #define kJoystickCenterX 50
        #define kJoystickCenterY 49
        #define kMaxDiffX 0.2
        int x = [xData intValue];
        int y = [yData intValue];
        _shipPointsPerSecY = (y-kJoystickCenterY)/kMaxDiffX;
        _shipPointsPerSecX = (x-kJoystickCenterX)/kMaxDiffX;
        }
        

      kJoystickCenter and kJoystickCenterY is the value of the physical joystick when the joystick is in its neutral position. If the joystick is in the middle right position, we will calculate the X, Y offset and give a speed to the ship based on the offset value.

      • Comment out this line of code: //self.isAccelerometerEnabled = YES;

      • In init method after the definition of float maxY, float minY, replace them with the code block below:

        CGSize winSize = [CCDirector sharedDirector].winSize;
        float maxY = winSize.height - _ship.contentSize.height/2;
        float minY = _ship.contentSize.height/2;
        float maxX = winSize.width - _ship.contentSize.width/4;
        float minX = _ship.contentSize.width/4;
        float newY = _ship.position.y + (_shipPointsPerSecY * dt);
        newY = MIN(MAX(newY, minY), maxY);
        float newX = _ship.position.x + (_shipPointsPerSecX *dt);
        newX = MIN(MAX(newX, minX), maxX);
        
      • Add a variable in HelloWorldLayer.h file

        float _shipPointsPerSecX;
        

        The purpose of this code is to set the boundary so our ship will always be within the visible area of our iPhone screen.

    9. In the update method, comment out this part:
      Screen Shot 2012-07-23 at 11.19.59 PM
      Comment out restartTapped method and endScene method and their corresponding code blocks.
    10. Compile and run the code. We can now move the space ship with our joystick!

    Time to check out our beautiful creation:


    Here is the screencast showing the steps mentioned above:

    You can find all related files to this project from github

    Hope you enjoy the post. If you like what you are reading, subscribe to our RSS feed for more cool articles coming your way.

    Sunday
    Jun172012

    Mobile Nerf Tank



    We have been experimenting a little more with Arduino and decided that Mobile Tape Measures are cool, but Nerf guns are even cooler! We like Nerf guns a lot but after a while it gets a little tiring to run around. Plus, the more you run, the more of a target you become. So we figure, why not put together a mobile nerf tank that will solve the problem at hand? Below is a prototype we are building, there are still a few things to do, such as adding accelerometer and gyroscope support for controlling the car and the arm, and potentially replacing the arm with actual servos - it's just more cool if it made from scratch. While this may seem a frivolous project, we actually think it may change the world (our mission). For example, nerf fights are now available to the physically disabled. Now it's fun to scold your kids - you can chase them down with one of these things in the comfort of your couch. You are an artist with no kids? We didn't forget you. Simply dip the foam darts into different color paints and you can create Nerf art by controlling multiple Nerf tanks and pre-programming shooting patterns all from a single phone. As you can see, the possibilities are limitless (ok, there are at least ten uses). 

     

    Saturday
    Jun022012

    Mobile Tape Measure (using IOS + Arduino)




    Today we take a little departure from our usual pure code project and get our hands dirty with a very popular hardware called Arduino.  Arduino is a highly popular open source hardware prototyping platform.  In geek's term, it's a microcontroller that you can use to interface with other hardware, which you can then program to get you the desirable behavior.  You already know how to program your phone, knowing how to create custom hardware that interfaces with your phone can take the value of your software skills to the next level, allowing you to do things that's otherwise impossible with computer alone.  As such, knowing how to use something like Arduino gives you the ability to extend your computer or mobile hardware and make it do things that's outside of its current capabilities. In this post, we are going to do exactly that by creating a tape measure gadget and recording the distance data on our iPhone.

    You can download the code for this project here.

    Goal

    The goal of this project is to detect the distance between you and the object in a place you can’t see, and display the distance on your iPhone's display.

    Usages

    1. Measure distance between the sensor and the object in front of it.
    2. You can put the device on the back of your car to keep yourself from running into another car when you parallel park.
    3. You can put it on your pocket, if someone is too close to your pocket, the alarm will sound.

    Ultrasonic Ranger

    I use HC-SR04 as my ultrasonic range finder. It is a very popular on the market with stable performance and high accuracy. You can buy it from Amazon for $9.49.

    HC-SR04 ultrasonic range finder

    Specifications:

    • Ranging: 3 cm to 400 cm
    • Resolution: 0.3 cm

    HC-SR04 Datasheet

    There are 4 pins out of this module from left to right, they are: VCC, Trig, Echo, GND.

    The basic idea is that VCC connects to 5V, GND to ground to provide power.  This creates an electrical potential difference, which causes electrons to flow, thereby giving you current. Trig is a trigger pin to tell the board to start working. When the Trig pin is set to high for more than 10-microsecond impulse, the module starts ranging. The Echo pin returns different duration of high level based on distance .

    Distance = ((Duration of high level) * (Sonic:340m/s))/2

    Connect HC-SR04 to Arduino

    From left to right wire Red, Yellow, Green, Blue

    Arduino

    Display on Arduino IDE serial monitor

    /* HC-SR04 Ultrasonic module results to Arduino serial monitor 
    #define ECHOPIN // Pin to receive echo pulse
    #define TRIGPIN // Pin to send trigger pulse
    void setup()
    {
      Serial.begin(9600); 
      pinMode(ECHOPIN, INPUT);
      pinMode(TRIGPIN, OUTPUT);
    }
    
    void loop() {
      // Trigger Trig pin to Start Ranging
      digitalWrite(TRIGPIN, LOW);
      delayMicroseconds(2);
      digitalWrite(TRIGPIN, HIGH);
      delayMicroseconds(10);
      digitalWrite(TRIGPIN, LOW);
    
      // Compute distance
      float distance = pulseIn(ECHOPIN, HIGH);
    
      //pulseIn(pin,value) reads a pulse length of the value.(μs - microseconds)
      distance = distance / 58;
    
      // From datasheet: pluse width(μs)/58 = distance (cm)
      // pluse width(uS)/148 = distance (inch)
      Serial.println(distance); 
      delay(1000); // return distance per second.
    }
    
    

    Connect Arduino to iPhone through Redpark Serial 

    Redpark SerialRedpark SerialBased on Apple’s MFI licensing program, you must be an MFi licensee to develop hardware accessories that connect to your iDevice. But becoming a member of the MFi program is a long process. So I just buy “The Redpark Serial Cable” to connect to iPhone and a “P4B RS232 to TTL Serial Adapter”  to do away with the hassles since we are just building a prototype.

    Connections

    1. iPhone to Redpark (20pin)
    2. Redpark to P4b (Serial connection)
    3. P4b to Arduino (Wire)
      1. Download Redpark SDK from here
      2. Drag and drop redparkSerial.h, rscMgr.h header files from inc/folder and libRscMgrUniv.a from lib/folder into your project.
      3. Add External Accessory Framework from Build Phases tab.
      4. In your project's plist file. Add a new row named "Supported external accessory protocols", type "com.redpark.hobdb9" into Item0.
      5. Compile and Run to check if any errors.
    4. Interface on iPhone

      Declare three components in .h file

        @property (weak, nonatomic) IBOutlet UITextField *inputText;
        @property (weak, nonatomic) IBOutlet UITextView *outputResult;
        - (IBAction)sendClick:(id)sender;
      

      Add Redpark Serial Library

      Add codes in your project

      In your viewController’s header file, add these lines:

      #import 
      #import "RscMgr.h"
      #define BUFFER_LEN 1024
      @interface ViewController : UIViewController  {
        RscMgr *rscMgr;
        UInt8 rxBuffer[BUFFER_LEN]; 
        UInt8 txBuffer[BUFFER_LEN];
      }
        @property (weak, nonatomic) IBOutlet UITextField *inputText;
        @property (weak, nonatomic) IBOutlet UITextView *outputResult;
        - (IBAction)sendClick:(id)sender;
      @end
      

      Then in ViewController.m file, inside viewDidLoad method add these two lines:

        rscMgr = [[RscMgr alloc] init];
        [rscMgr setDelegate:self];
      

      After you init a instance of RscMgr and setup the delegate method to itself, it’s time to implement the delegate callbacks.

      #pragma mark - RscMgrDelegate methods
      - (void) cableConnected:(NSString *)protocol {
        [rscMgr setBaud:9600];
        [rscMgr open];
      }
      
      - (void) cableDisconnected { }
      - (void) portStatusChanged { }
      
      - (void) readBytesAvailable:(UInt32)numBytes {
        int bytesRead = [rscMgr read:rxBuffer Length:numBytes];
        NSLog( @"Read %d bytes from serial cable.", bytesRead );
        
        for (int i = 0; i < numBytes;++i) {
          self.outputResult.text = [NSString stringWithFormat:@"%@%c",self.outputResult.text,((char *)rxBuffer)[i]];
        }
      
        [self.outputResult scrollRangeToVisible:NSMakeRange([self.outputResult.text length], 0)];
      }
      

      cableConnected:protocol method setup the bit rate to 9600

      readBytesAvaliable:numBytes method reads bytes from buffer and added them to Result display.

      The last line: [self.outputResult scrollRangeToVisible:NSMakeRange([self.outputResult.text length], 0)];

      The purpose of this line is to autoscroll Result display, so that the newest results always show on the bottom of the screen. At this point, if you run your application on iPhone and connect it to Arduino board, your iPhone will get the same output as Arduino IDE’s serial monitor.

      One last thing

      We did not implement the send button method yet. We don't really need it if we just want to display Ultrasonic Result on iPhone screen but it is still good to know how to do it for future use (say if you want persist the data).

      - (IBAction)sendClick:(id)sender {
        [self.inputText resignFirstResponder];
        NSString *text = self.inputText.text;
        int bytesToWrite = text.length;
        for ( int i = 0; i < bytesToWrite; i++ ) {
          txBuffer[i] = (int)[text characterAtIndex:i];
        }
        [rscMgr write:txBuffer Length:bytesToWrite];
      }
      

      Now when you click send button, it will send all bytes of what’s in inputText field to txBuffer one by one.

      Mobile Tape Measure (side view)

       Mobile Tape Measure (top view)

      You can download the code for this project here.