Friday, July 27, 2012

Create your own LED cube

A LED cube is a very interesting and fascinating item that can gain lot of fun and knowledge. It's simply a 3D screen that can demonstrate your own models in a 3D space. If you are very good at programming, it will be very useful to craft more complex patterns on the cube

In my project I created my LED cube which is size of 8*8*8 (512 Leds). Here is the video
 I used red 3mm LEDs with 2.5 cm distance. Size, color and distance of LEDs are very important to make cube more visible and avoid ghost effects of reflection. It is better if you can use diffused LEDs (they can emit light to every direction with same intensity) but I couldn't find those in local market.

I used PIC16f877A microcontroller to  control entire cube. It has 40 pins and about 30 -25 usable pins to our task. But thing we don't forget here is that cube has 512 LEDs and they should have separate 512 wires to work with. Here I used the theory of using layers. So each layer has 64 LEDs and there are 8 such layers. One layer is lighten up at a time. Using the sensitivity of our eyes we can pretend that all layers are lightening at once when we switch them in a very high frequency.

In a layer all cathodes of leds are connected to one and anodes are kept free. Creating a layer is a bit challenging task. We should guarantee that all leds in the layer are keeping 2.5 cm gap and lie on the same plane. So it is easy if we can make a model like this to create the layer.

Then we can put leds into these holes and solder as we wish

After all cathodes are soldered we can see a layer like this

After all layers are finished we can move to connect layers to each other. When we are connecting layers we should make sure that anodes of the leds of one layer should be connected to the same anodes of other layer. Finally we have 64 wires for layer anodes and 8 wires for layers (common cathodes of each layer).

Next problem is how to connect all 64 wires of layers to microcntroller. Instead connecting them directly I used 8 74hc574 latch ics which have D flipflops. Using these ICs, you need only 20 pins from PIC. 8 pins to light up the layer leds, 8 pins to select the layer and 4 pins to select the latch ic.

Q0 - Q7 pins of 74hc574 (for more information refer to 74hc574 datasheet) ics are connected to rows of layer anodes. There are 8 rows the layer anodes so each row is represented by one latch ic. For putting data on a layer first select the latch ic and put data on PORTB of pic. Then move to next latch ic. When we move to next ic, values of previous ones are not changed because its D flipflops remind the previous states. Likewise we can light up a whole layer and then select the layer. Layer common cathodes are connected to J9. Using PORTD we can select a layer.



This is the brief description of the cube I have made. Those all are electronic stuffs and the most challenging task I have experienced is programming this cube. I used Timer0 clock interrupts of pic to switch between layers. Here is the code I have written. I used mikroc pro compiler



unsigned char layers[8][8]={0},i,j,k,l,m,n,q,x,y; //layers array has all values of the cube LEDs.
void loadRegister(int num){ //Here correct latch is selected
     PORTA.B0  = num%2;
     num=num>>1;
     PORTA.B1  = num%2;
     num=num>>1;
     PORTA.B2  = num%2;
     PORTA.B3=0;
     PORTA.B3=1;
}


void loadLayer(int layerNum){ //lightening a layer is done
     PORTD= 0b00000000;
     for(i=0;i<8;i++){
          PORTB=layers[layerNum][i];
          loadRegister(i);
     }
     if(layerNum==0){
          PORTD= 0b00000001; //selecting the layer
     }else if(layerNum==1){
          PORTD= 0b00000010;
     }else if(layerNum==2){
          PORTD= 0b00000100;
     }else if(layerNum==3){
          PORTD= 0b00001000;
     }else if(layerNum==4){
          PORTD= 0b00010000;
     }else if(layerNum==5){
          PORTD= 0b00100000;
     }else if(layerNum==6){
          PORTD= 0b01000000;
     }else if(layerNum==7){
          PORTD= 0b10000000;
     }
}


int num=0,conter=0;
char doCount=0;


void interrupt(){                              //Timer0 interrupts are handled at here. Here is the main driving section of the cube
     if(INTCON.TMR0IF){
        if(doCount){
           conter++;
        }
        loadLayer(num);
        num++;
        if(num==8)num=0;
        INTCON.TMR0IF = 0; // clear TMR1IF
     }


}


void init_timer(){
    OPTION_REG = 0b10000101; //Timer0 interrupts are configured
    INTCON = 0b10100000; //Interrupts are enabled.
}


void delayms(int num){
     doCount=1;
     while(conter<num);
     conter=0;
     doCount=0;


}
int power(int p){
    int val=1;
    if(p==0)return 1;
    for(k=0;k<p;k++){
        val=val*2;
    }
    return val;
}


int clearAll(){
    int i,j;
    for(i=0;i<8;i++){
      for(j=0;j<8;j++){
         layers[i][j]=0;
      }
    }
}


void circle(int xcod,int ycod,int zcod,int rad){
     int x,y,m;
     for(x=0;x<8;x++){
         for(y=0;y<8;y++){
             for(m=0;m<8;m++){
                 if((x-xcod)*(x-xcod)+(y-ycod)*(y-ycod)+(m-zcod)*(m-zcod)-rad<=0){
                     layers[m][x]= layers[m][x]|power(y);
                 }
             }
         }
     }
}


void parabola(int xcod,int ycod,int c){


     int x,y,z;
     //clearAll();
     for(x=0;x<8;x++){
        for(y=0;y<8;y++){
            for(z=0;z<8;z++){
                if(-(x-xcod)*(x-xcod)-(y-ycod)*(y-ycod)+c-z>=0)
                layers[z][x] = layers[z][x]|power(y);
            }
        }


     }


}


void plane(int a,int b,int c,int d){
     int x,y,z;
     //clearAll();
     for(x=0;x<8;x++){
        for(y=0;y<8;y++){
            for(z=0;z<8;z++){
                if((a*x+b*y-d)/c==z)
                layers[z][x] = layers[z][x]|power(y);
            }
        }


     }
}


int random,temp;


void main() {
     TRISB =0;
     TRISD=0;
     TRISA=0;
     ADCON1 = 0b00000111;
     PORTA.B3=0; //en pin






     init_timer();
     while(1){
        for(m=0;m<8;m++){
           for(n=0;n<8;n++){
             for(l=0;l<8;l++){
                layers[l][m]=layers[l][m]+power(n);
                delayms(10);
             }
           }
        }
        for(m=0;m<8;m++){
           for(n=0;n<8;n++){
             for(l=0;l<8;l++){
                layers[l][m]=layers[l][m]-power(n);
                delayms(10);
             }
           }
        }
        clearAll();
        for(m=0;m<8;m++){
           for(n=0;n<8;n++){
             for(l=0;l<8;l++){
                layers[l][m]=power(n);
                delayms(10);
                clearAll();
             }
           }
        }
        clearAll();




     for(q=0;q<100;q++){
       for(x=0;x<5;x++){
       for(l=1;l<8;l++){
          for(m=0;m<8;m++){
             temp=layers[7-l][m];
             layers[8-l][m]=temp;
          }
       }
       random= rand()%64;
       layers[0][random/8]=power(random%8);
       delayms(15);
       }
     }
     clearAll();




      for(y=0;y<8;y++){
         for(m=0;m<8;m++){
             circle(m,m,m,4);
             delayms(20);
             clearAll();
         }
      }
      
      for(y=0;y<8;y++){
         for(m=0;m<8;m++){
             circle(m,7-m,m,4);
             delayms(20);
             clearAll();
         }
      }
      
      for(y=0;y<8;y++){
         for(m=0;m<8;m++){
             circle(7-m,7-m,m,4);
             delayms(20);
             clearAll();
         }
      }
      
      for(y=0;y<8;y++){
         for(m=0;m<8;m++){
             circle(7-m,m,m,4);
             delayms(20);
             clearAll();
         }
      }


      for(y=0;y<8;y++){
         for(m=0;m<8;m++){
            parabola(3,3,m);
            delayms(50);
            clearAll();
         }
      }


      for(y=0;y<10;y++){
         for(m=0;m<8;m++){
            plane(rand()%5,rand()%5,rand()%5,rand()%5);
            delayms(50);
            clearAll();
         }
      }
     
     }


}

I should say that this is a very very brief description and sometime you may find difficult to understand some concepts of this article. If so please don't hesitate to ask questions and I'm very happy to help you :)

Thank you

Wednesday, June 13, 2012

Configuring javacv

opencv (open computer vision) is an image processing library which is introduced by intel that is very powerful in processing images in very powerful and effective manner. However opencv is written in c language so most of my friends including me faced several difficulties with programming in c. So I decided to move to javacv ; a java wrapper that can naively call opencv functions. It is a general acceptance that java is relatively slower than C but believe me people who invented javacv have designed this in a way that you can never feel that kind of slowness in your java code.

In this blog post I hope to explain how to configure javacv with your IDE (In my case I use netbeans). Though javacv is easy, configuring is bit hard to catch from the first attempt. So I think this will be very useful to java people who are intending for new technology.

To install javacv there are few requirement
JDK
opencv 2.4 http://sourceforge.net/projects/opencvlibrary/files/
Netbeans ide
javacv-0.1-bin.zip  http://code.google.com/p/javacv/downloads/list


You need to install opencv2.4 into C:/opencv folder (It is the default location). I recommend to use same locations otherwise you will have to face many difficulties.
Extract javacv-0.1-bin.zip to a location in your hard disk 
Go to netbeans and create a new java project.
Add those jar files to your project







Then run this code




package javaapplication1;

import static com.googlecode.javacv.cpp.opencv_core.*;
import static com.googlecode.javacv.cpp.opencv_imgproc.*;
import static com.googlecode.javacv.cpp.opencv_highgui.*;

public class JavaApplication1 {

    public static void main(String[] args) {
        show("C:\\Users\\Public\\Pictures\\Sample Pictures\\Desert.jpg");
    }
    public static void show(String filename) {
        cvNamedWindow("dim");
        IplImage image = cvLoadImage(filename);
        if (image != null) {
            cvShowImage("dim", image);
            cvWaitKey(0);
            cvReleaseImage(image);
        }
     
    }
}



If you have installed opencv to default folder this code should run without any error. 

If it gives an error like this
This exception tells that it can't find opencv location in your machine. Actually this error comes from the one of the jar you have added to the project. In my case it is javacv-windows-x86.jar. It depends on your processor architecture. To resolve this error you have to download  http://www.dependencywalker.com/
to catch what are the dependencies are missing in you jar.
Then extract that jar using win rar and make sure that jniopencv_core.dll is in that folder.
Open that dll using  Dependency Walker 
As you can see there is one dll is missing. It is marked from yellow color. These dll are located in your opencv installation folder. Go to it and search for that dll. Then you can add it to system path. There are two ways to do that.
1 Easy way - you can simply copy that dll s to system32 folder in windows folder
2 Using environmental variable settings
 go to my computer -> properties -> Advanced System Settings -> Environment Variables
Select the path variable from the category of system variables

Click edit and append the path of the dll file to the end of the variable

Then click view -> refresh in Dependancy walker
If more dependency errors are shown, do the same procedure until no error is shown. I know this is hard :) But I couldn't figure out an easy way to do this

If all configurations are ok then you will be able to run that small code

References 
Any questions?

Wednesday, February 29, 2012

Selenium

Selenium IDE


Selenium IDE is an IDE that record and playback test cases to debug your web applications. Selenium is opensource so you can download it free and view its source code from here


Selenium can be installed in to your firefox web browser easily as a plugin and at the very first moment you have installed Selenium you can experience its powerful capabilities of recording test cases.


There is a tool called Selenium Remote Control that has ability to map Selenium with other browsers and platforms such as Chrome , Opera and Safari. This Selenium Remote Control creates javascript injections through those browsers so that Selenium has become more powerful enough to handle test cases which uses AJAX (The technology used to transfer or retrieve data without refreshing the browser)


So... Enough introduction :) Let's get back to work :)


Say hello world to selenium


Here I hope to show how to record a test case and replay it.


First you have to install selenium IDE to you browser.


My browser is Firefox so no need of installing Selenium RC :)
Go to the above link and select proper version
Then browser will ask for installing selenium to the browser. (You know what to do :) )




Here we go...
  • Go to browser Tools -> Selenium Ide.
  • Then select record.




That's it.
  • Do some googling. Go to some links...
  • Then go to Selenium IDE and stop recording.
  • Select Play entire test suite..
You will see that all the bowsing stuff you have done is replaying :)


So it is simple as that  but you can extend it further. You can save that test case and re use it later or you can export it into many compatible language test cases.


Here is another trick ....


While you are browsing you can make sure that you are going on the correct path by right clicking on a particular waypoint and select "Verify text present...."


While you are replaying the test cases, it makes sure that particular way point is in the proper place.....


So that's all about selenium IDE.... Then let's look at the language support supplied by selenium for test cases.
-------------------------------------------------------------------------------------------------------


       Another use of selenium is providing web drivers. Web driver is a tool which we can use to test web applications. In Selenium it supports several web drivers.


Ex:- Fire fox web driver
Internet Explorer web driver
Google chrome web driver


       The importance of this selenium web driver is it hasn’t tied with any other test framework. Due to this reason these web drivers can be easily used with any test framework and without any test frame work.
Another important aspect of these web drivers is the ability of handling web elements. And we can easily automate our processes by using the selenium IDE.




Testing using Selenium Server
In Selenium IDE testing can only use in Firefox browser. Now let’s try more general approach to automated testing using Selenium Server.
First you have to download selenium Server from http://selenium.googlecode.com/files/selenium-server-standalone-2.19.0.jar  and save in your computer.
I’m using IntelliJ Idea to do my testing. You can use whatever you are familiar with, Eclipse, Netbeans, etc.
First create a new project named “SeleniumPro” in Idea. After project is created right click on “SeleniumPro” select “Open module settings”. Then go to dependencies on it and add selenium-server-standalone-2.19.0.jar and junit libries.



Now we can start writing our code. Here we are going to write an code so we can open new browser instant. First we have to make an instant of web driver. We use org.openqa.selenium.WebDriver class for this.
WebDriver driver=new FirefoxDriver();
This is how we make an WebDriver instant to open Firefox browser. We can also use this to open other browers.
  WebDriver driver=new InternetExplorer();
WebDriver driver=new ChromeDriver();
Now run your code. It will open a Browser as we expected.
Now let’s see how to close an opened browser.
                 driver.quit();
Using this method we can close the browser we opened.
Our next task is to visit a website.
                driver.get(www.google.lk);
Put this line in tour code. Now our little program will open a browser, go to google and close. This is a very simple web automation that can be done using Selenium. 


Now let’s try to add some new features to our code. Let’s try to login to Facebook. So I have to type my email and password then click login.
To type first we have to find the textbox to type our email. We can make an instant of it as a web element. Now let’s see how we can make a web element corresponds to that textbox.
               WebElement login = driver.findElement(By.name("email"));
Here “email” is the identifier(name) used to name that textbox. You can find the name of any web element by right clicking on the web page and selecting “Inspect Element

Then click on “Inspect” In the left bottom corner, select the element which you need to find the name, then click “HTML”. Then a HTML code will come where we can find the name of the element.
Now we have to type our email address on it. We can do it by using this line.
                login.sendKeys(“email address”);
We can also type password in the same manner.
                WebElement passwd = driver.findElement(By.name("pass"));
                Passwd.sendKeys(“password”);
Now we have to click the log in button. We have to create a WebElement for that button and call clickmethod of it.
                WebElement loginbutton = driver.findElement(By.id("loginbutton"));
                loginbutton.click();
Now run and check whether it is working properly. We can do more web automations using Selenium.

Drawbacks of Selenium
Even though Selenium is an open source tool its documentation is very difficult for users to use. Also upgrades are happening very slowly to it.
Selenium IDE is only working with Firefox, to work with other browsers we have to use Selenium RC (Remote Controller) or Selenium Server.







Friday, February 3, 2012

Create a bluetooth joystick for your laptop using your java phone

So, hi all........:)
This is my first technical post. In this session, I hope to share some knowledge about java mobile bluetooth programming using J2ME. This is a project I did after 1 st semester exam in university (So this is bit old). However there are so many mobile technologies available today other than J2ME but there is a considerable amount of crowd using J2ME yet.

In this project main intention is to connect my mobile Nokia 3120 classic with my laptop using bluetooth and control my laptop using the phone. So I had to write two applications for both lap and phone using java.
I hope this works with all mobile phones support java. If not please let me know

First I would like to give the code for bluetooth server for the computer. To use this code there are few requirements
1 - A bluetooth dongle connected to to your pc and properly installed driver softwares
2- Set it to discoverable  mode.

3 - Your mobile phone should be paired with with this dongle



Server application consists with three classes. You can use Netbeans or Eclipse or other IDE to develop the application. In netbeans create a new java application project (With a Main class) and crate 3 classes named Frame , Key and Receive. Then following body to those classes.



***** You will need to add bluecove2.1.0.jar to libraries
http://code.google.com/p/bluecove/downloads/detail?name=bluecove-2.1.0.jar&can=2&q=

----------------------------------------------------------------------------------------

Main.java


public class Main {
    public static void main(String args[]){
        new Frame().setVisible(true);
     
    }
}

----------------------------------------------------------------------------------------
Frame.java


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.io.StreamConnectionNotifier;


public class Frame extends javax.swing.JFrame {

    final Object inquiryCompletedEvent = new Object();
    private LocalDevice local;
    private StreamConnectionNotifier server = null;
    private StreamConnection conn = null;
    private InputStream is;
    private OutputStream os;
    private Key key;

    public Frame() {
        initComponents();
        key = new Key(this);
        Thread t = new Thread(key);
        t.start();
        this.setResizable(false);

    }

    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        lblMessage = new javax.swing.JLabel();
        btStart = new javax.swing.JButton();
        lblTitle = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());

        lblMessage.setText("W.D.Upeksha, University of Moratuwa");
        getContentPane().add(lblMessage, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 40, 230, 20));

        btStart.setText("Start");
        btStart.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btStartActionPerformed(evt);
            }
        });
        getContentPane().add(btStart, new org.netbeans.lib.awtextra.AbsoluteConstraints(90, 60, -1, -1));

        lblTitle.setText("Bluetooth Server");
        getContentPane().add(lblTitle, new org.netbeans.lib.awtextra.AbsoluteConstraints(20, 20, 180, -1));

        pack();
    }// </editor-fold>

    private void btStartActionPerformed(java.awt.event.ActionEvent evt) {                                         
        try {
            try {

                //doDeviceDiscovery();
                lblMessage.setText("Waiting");
                createService();
                conn = server.acceptAndOpen();
                lblMessage.setText("Connected");
            } catch (IOException ex) {
                lblMessage.setText("Error");
                Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
            }


            String msg = "hello there, client";
            is = conn.openInputStream();
            os = conn.openOutputStream();
            // send data to the server
            os.write(msg.getBytes());
            os.flush();
            // read data from the server
            connection();
            conn.close();
            btStart.setVisible(false);
            lblMessage.setText("Connected");
        } catch (IOException ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }

    }                                        

    void connection() {
        Receive rec = new Receive(is, this);
        Thread thr = new Thread(rec);
        thr.start();

    }

    void reset(String str) {
        lblMessage.setText(str);
        key.setStr(str.trim());    
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new Frame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify
    private javax.swing.JButton btStart;
    private javax.swing.JLabel lblMessage;
    private javax.swing.JLabel lblTitle;
    // End of variables declaration

    private void createService() {
        try {
            ServiceRecord record = null;
            try {
                try {
                    local = LocalDevice.getLocalDevice();
                    local.setDiscoverable(DiscoveryAgent.GIAC);
                } catch (BluetoothStateException ex) {
                    Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
                }
                String connectionURL = "btspp://localhost:393a84ee7cd111d89527000bdb544cb1;" + "authenticate=false;encrypt=false;name=RFCOMM Server";
                server = (StreamConnectionNotifier) Connector.open(connectionURL);
            } catch (IOException ex) {
                Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
            }
            record = local.getRecord(server);
            DataElement elm = null;
            elm = new DataElement(DataElement.DATSEQ);
            elm.addElement(new DataElement(DataElement.UUID, new UUID(0x1002)));
            record.setAttributeValue(0x0005, elm);

            elm = new DataElement(DataElement.STRING, "BT Benchmark");
            record.setAttributeValue(0x101, elm);

            elm = new DataElement(DataElement.STRING, "Upeksha");
            record.setAttributeValue(0x102, elm);

        } catch (Exception ex) {
            Logger.getLogger(Frame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

---------------------------------------------------------------------------------------------------------
Key.java

import java.awt.AWTException;
import java.awt.Robot;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Key implements Runnable{
    private String str = "RELEASE";
    private Robot robo;
    private Frame frm;
    public Key(Frame frm){
        try {
            this.frm = frm;
            robo = new Robot();
        } catch (AWTException ex) {
            Logger.getLogger(Key.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void setStr(String str) {
        this.str = str;
    }

    
    @Override
    public void run() {
       while(true){
            try {
                if (str.equals("UP")) {
                    robo.keyPress(65);
                } else if (str.equals("DOWN")) {
                    robo.keyPress(66);
                } else if (str.equals("RIGHT")) {
                    robo.keyPress(67);
                } else if (str.equals("LEFT")) {
                    robo.keyPress(68);
                } else if (str.equals("UP_RELEASE")) {
                    robo.keyRelease(65);
                
                }else if (str.equals("DOWN_RELEASE")) {
                    robo.keyRelease(66);
                
                }else if (str.equals("RIGHT_RELEASE")) {
                    robo.keyRelease(67);
                
                }else if (str.equals("LEFT_RELEASE")) {
                    robo.keyRelease(68);
                
                } 
                Thread.sleep(100);
                
            } catch (InterruptedException ex) {
                Logger.getLogger(Key.class.getName()).log(Level.SEVERE, null, ex);
            }           
       }
    }    
}

--------------------------------------------------------------------------------------
Receive.java

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Receive implements Runnable {

    InputStream is;
    Frame frm;

    public Receive(InputStream is, Frame frm) {
        this.is = is;
        this.frm = frm;
    }

    public void run() {
        String msg;
        try {
            while (true) {
                byte[] buffer = new byte[100];
                is.read(buffer);
                msg = new String(buffer);
                frm.reset(msg.trim());
                Thread.sleep(100);
            }
        } catch (InterruptedException ex) {
            Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Receive.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}


----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------

Then we need an application to install into mobile phone to connect to server
Here is the code for it. For that it is recommended to use a netbeans mobile application or you can use eclipse (I'm not familiar with eclipse :) ).


Then create a new midlet named Midlet and two java classes named KeyCanvas and Communication

-------------------------------------------------------------------------------------------------------

Midlet.java

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Vector;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DataElement;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.bluetooth.UUID;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;

public class Midlet extends MIDlet implements DiscoveryListener{

    private Display display;
    final Object inquiryCompletedEvent = new Object();
    private Vector devicesDiscovered;
    private ServiceRecord[] servicesFound = null;
    private ServiceRecord service;
    private DiscoveryAgent agent = null;
    private LocalDevice local;
    private StreamConnection conn = null;
    private Form form;
    private List lst;
    private Command cmd;
    int face = 0;

    public void startApp() {
        try {
            StringItem stringItem = new StringItem("Remort", "Testing Connectio\n");
            doDeviceDiscovery();
            form = new Form(null, new Item[]{stringItem});
            lst = new List("Devices", List.IMPLICIT);
            display = Display.getDisplay(this);
            display.setCurrent(form);
            cmd = new Command("select", Command.EXIT, 0);
            lst.addCommand(cmd);
            lst.setCommandListener(new CommandListener() {
                public void commandAction(Command arg0, Displayable arg1) {
                    if (face == 0) {
                        int num = lst.getSelectedIndex();
                        doServiceSearch((RemoteDevice) (devicesDiscovered.elementAt(num)));
                    }
                    if (face == 1) {
                        try {
                            int num = lst.getSelectedIndex();
                            service = servicesFound[num];
                            DataElement el = (DataElement) service.getAttributeValue(0x100);
                            form.deleteAll();
                            form.append(el.getValue() + "");
                            display.setCurrent(form);

                            String connectionURL = service.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
                            conn = (StreamConnection) Connector.open(connectionURL);
                            form.append(" Connected");
                            OutputStream os = conn.openOutputStream();
                            String msg = "Connected to Client";
                            os.write(msg.getBytes());
                            os.flush();
                            form.append(" Data sent");
                            byte[] buffer = new byte[100];
                            connection();
                            Displayable can = new KeyCanvas(os);
                            display.setCurrent(can);
                        } catch (IOException ex) {
                            ex.printStackTrace();
                        }
                    }

                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    void connection() throws IOException {
        InputStream is = conn.openInputStream();
        Communication com = new Communication(this, is);
        new Thread(com).start();

    }

    void scan() {
        synchronized (inquiryCompletedEvent) {
            try {
                boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, this);
                if (started) {
                    form.append("wait for device inquiry to complete...");
                    inquiryCompletedEvent.wait();
                    form.append(devicesDiscovered.size() + " device(s) found");
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            } catch (BluetoothStateException ex) {
                ex.printStackTrace();
            }
        }
    }

    public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod) {
        try {
            form.append("Device " + btDevice.getBluetoothAddress() + " found");
            devicesDiscovered.addElement(btDevice);
            try {
                form.append(" name " + btDevice.getFriendlyName(false));
            } catch (IOException cantGetDeviceName) {
            }
            lst.append(btDevice.getFriendlyName(false), null);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    public void servicesDiscovered(int transID, ServiceRecord[] serviceRecord) {
        DataElement nameElement = null;
        lst.deleteAll();
        servicesFound = serviceRecord;
        for (int i = 0; i < serviceRecord.length; i++) {
            nameElement = (DataElement) serviceRecord[i].getAttributeValue(0x100);
            if (nameElement != null && nameElement.getDataType() == DataElement.STRING) {
                lst.append((String) nameElement.getValue(), null);
            }
        }

    }

    public void serviceSearchCompleted(int arg0, int arg1) {
        face = 1;
    }

    public void inquiryCompleted(int discType) {
        form.append("Device Inquiry completed!");
        display.setCurrent(lst);
        synchronized (inquiryCompletedEvent) {
            inquiryCompletedEvent.notifyAll();

        }
    }

    private void doDeviceDiscovery() {
        try {
            local = LocalDevice.getLocalDevice();
        } catch (BluetoothStateException bse) {
            // Error handling code here
        }
        agent = local.getDiscoveryAgent();
        devicesDiscovered = new Vector();
        try {
            if (!agent.startInquiry(DiscoveryAgent.GIAC, this)) {
             
            }
        } catch (BluetoothStateException bse) {
        }
    }

    private void doServiceSearch(RemoteDevice device) {

        int[] attributes = {0x100, 0x101, 0x102};
        UUID[] uuids = new UUID[1];
        uuids[0] = new UUID(0x1002);
        try {
            agent.searchServices(attributes, uuids, device, this);
        } catch (BluetoothStateException e) {
            // Error handling code here
        }
    }

    public Form getForm() {
        return form;
    }
}

------------------------------------------------------------------------------------------

Communication.java


import java.io.IOException;
import java.io.InputStream;

public class Communication implements Runnable {
    Midlet mid;
    InputStream is;
    Communication(Midlet aThis, InputStream is) {
        this.mid=aThis;
        this.is=is;
    }
    public void run() {
        while(true){
            try {
                Thread.sleep(100);
                byte buffer[] = new byte[100];
                is.read(buffer);
                String msg = new String(buffer);
                mid.getForm().deleteAll();
                mid.getForm().append(msg.trim());
            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
         
        }
    }
 
}

----------------------------------------------------------------------------------------
KeyCanvas.java


import java.io.IOException;
import java.io.OutputStream;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;

public class KeyCanvas extends Canvas {

    private Font mFont = Font.getFont(Font.FACE_PROPORTIONAL, Font.STYLE_PLAIN, Font.SIZE_MEDIUM);
    private String mMessage = "[Press keys]";
    private OutputStream os;

    public KeyCanvas(OutputStream os) {
        this.os = os;
    }

    public void paint(Graphics g) {
        int w = getWidth();
        int h = getHeight();

        g.setGrayScale(255);
        g.fillRect(0, 0, w - 1, h - 1);
        g.setGrayScale(0);
        g.drawRect(0, 0, w - 1, h - 1);

        g.setFont(mFont);

        int x = w / 2;
        int y = h / 2;

        g.drawString(mMessage, x, y, Graphics.BASELINE | Graphics.HCENTER);
    }

    protected void keyPressed(int keyCode) {
        try {
            int gameAction = getGameAction(keyCode);
            switch (gameAction) {
                case UP:
                    mMessage = "UP";
                    os.write(mMessage.getBytes());
                    break;
                case DOWN:
                    mMessage = "DOWN";
                    os.write(mMessage.getBytes());
                    break;
                case LEFT:
                    mMessage = "LEFT";
                    os.write(mMessage.getBytes());
                    break;
                case RIGHT:
                    mMessage = "RIGHT";
                    os.write(mMessage.getBytes());
                    break;
                case FIRE:
                    mMessage = "FIRE";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_A:
                    mMessage = "GAME_A";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_B:
                    mMessage = "GAME_B";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_C:
                    mMessage = "GAME_C";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_D:
                    mMessage = "GAME_D";
                    os.write(mMessage.getBytes());
                    break;
                default:
                    mMessage = "";
                    os.write(mMessage.getBytes());
                    break;
            }
            os.flush();
            repaint();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    protected void keyReleased(int keyCode) {
        try {
            int gameAction = getGameAction(keyCode);
            switch (gameAction) {
                case UP:
                    mMessage = "UP_RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case DOWN:
                    mMessage = "DOWN_RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case LEFT:
                    mMessage = "LEFT_RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case RIGHT:
                    mMessage = "RIGHT_RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case FIRE:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_A:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_B:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_C:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                case GAME_D:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
                default:
                    mMessage = "RELEASE";
                    os.write(mMessage.getBytes());
                    break;
            }
            os.flush();
            repaint();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
}

-----------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------
After compiling the project you will get a jar file and jad file in the dist folder of your project. You can simply copy those files in to your mobile phone and run it.


So... Now we have completed the programming part. Then lets's run the projects. First you have to run Server application. Make sure your bluetooth device is turned on. You will get a window like this





He he .... You can put your name instead of my name :D. Then click start. You will realize that start button is   pressed. It means that server waits for a client. Then you can run the application in your mobile phone. Fisrt turn on your mobile phone's bluetooth device.


As soon as you turn on the application, it will search for the mobile devices. If your computer's bluetooth device is discoverable, it will be shown.


Then you have to select it from the list.


After selecting the device, application will search for the services given by the server. Choose RFCOMM Server. It creates serial data transfer between client and server.



Then you will see that Server application shows that it has connected with the client. It means everything is ok. :)



Press down button of the phone. Can you see that server gets the message? if yes you are done. :)



Open notepad and press top, down, left and right buttons. You will see that something is written on the notepad. Server generates keyboard events according to the input you gave to the phone. If you want to change these key events go to Key.java and change those events. Ahh haaaa :)
Then open your favorite racing game and configure the controllers according to the key events generated by server. Then enjoy your wireless Joystick

I know that there is lot of stuff in this post is bit hard to the people who are new to bluetooth programming. Same happened to me at the start of the project. However I can provide you the referring  materials I have used.
Use this thesis to learn about bluetooth programming in J2ME.
All the stuff I have used is clearly described here.

Finally.. It's your part. If you feel this post was useful to you in anyway please put a comment. Doesn't matter whether it is good or bad. I only need is a feedback to improve myself

Thank you