Problems with Threads and bluetooth

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Problems with Threads and bluetooth

Postby esmetaman » Thu Dec 06, 2007 6:44 pm

Hi,

I am trying to develop a set of classes to send a number by bluetooth in a master nxt brick and a slave brick receive that number.

I would like to send data n times, but i need that the slave can receive data.

My problem is due to how to reinit a listener thread in slave brick.

I will try to write a example to explain better:

Slave BRICK runs SlaveComms.nxj and this program launch a Listener Thread . This thread need to receive a number.

Master BRICK runs MasterComms.nxj and this program has a LCDUI menu and final user push a button and launch a event to send a number 4 for example.

Slave BRICK receive that number, but my listener thread die. and program finish.

My question is about how to reinit that thread.

Another question:

I notice that when in master brick finish the communication and turn on slave brick because listener thread die then main program finished, i noticed that master cant send twice. Why is the reason.

thanks
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 296
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

SLAVE CODE

Postby esmetaman » Thu Dec 06, 2007 6:47 pm

Code: Select all
import lejos.nxt.*;
import lejos.navigation.*;

public class RemoteReceiver{
   
   /**
    * @param args
    */
   public static void main(String[] args) {

      try{
         Pilot robot = new Pilot(2.1f,6f,Motor.A, Motor.C,false);
         BotSoul bObj = new BotSoul(robot);
         
         
            RemoteReceiverListener NCL = new RemoteReceiverListener(bObj);
            NCL.start();
         
      }catch(Exception e){
         
      }
   }

}



Code: Select all
import lejos.nxt.*;
import lejos.nxt.comm.*;
import java.io.*;

public class RemoteReceiverListener extends Thread{

   private String MESSAGE_AWAITING = "Awaiting";
   private String MESSAGE_CONNECTED = "Connected";
   
   //private Boolean NXT_CONNECTED = false;
   
   private Thread _MENU;
   
   private BTConnection btc;
   
   private InputStream is;
   private OutputStream os;
   private DataInputStream dis;
   private DataOutputStream dos;
   
   private BotSoul _bObj;
   
   public RemoteReceiverListener()throws Exception{
      
   }   

   public RemoteReceiverListener(BotSoul bObj)throws Exception{
      _bObj = bObj;
   }   
   
   private void showMessage(String message){
      //.clear();
      LCD.drawString(message,0,1);
      LCD.refresh();
   }
   
    public void run()
    {
       try{
          LCD.clear();
          String connected = "Connected";
          String waiting = "Waiting";
          LCD.drawString(waiting,0,0);
        LCD.refresh();
      
        BTConnection btc = Bluetooth.waitForConnection();
         
        LCD.clear();
        LCD.drawString(connected,0,0);
        LCD.refresh();   

         DataInputStream dis = new DataInputStream(btc.openInputStream());
         DataOutputStream dos = new DataOutputStream(btc.openOutputStream());
       
         Sound.playTone(300,300);
         int x = dis.readByte();
         //Sound.playTone(300,300);

         dos.writeByte((byte) 0xFF); // Ack
         dos.flush();
         
         LCD.drawInt(x,4, 0,1);
         LCD.refresh();

   
       }catch(Exception ex){
          
       }
    }
}

Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 296
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

MASTER CODE

Postby esmetaman » Thu Dec 06, 2007 6:50 pm

Code: Select all
import lejos.nxt.*;

public class NXTCommMaster{

   /**
    * @param args
    */
   public static void main(String[] args) {

      try{
         TiltSensor ts = new TiltSensor(SensorPort.S1);
         
         MasterSoul bObj = new MasterSoul(ts);
         NXTCommMasterUI UIObj = new NXTCommMasterUI(bObj,"NXT","NXT");
         UIObj.start();
      }catch(Exception e){
         
      }
   }

}



Code: Select all
import javax.microedition.lcdui.*;
import lejos.nxt.*;

public class NXTCommMasterUI extends Thread implements CommandListener{

   String NXTWiiVersion = "NXT Master";
   
   private static final int CMDID_BACK_TO_MAIN    = 1;
   private static final int CMDID_EXIT_APP       = 2;

   private static final Command BACK_COMMAND = new Command(CMDID_BACK_TO_MAIN, Command.BACK, 0);
    private static final Command EXIT_COMMAND = new Command(CMDID_EXIT_APP, Command.STOP, 2);

   private List    menu       = new List("Test Components", Choice.IMPLICIT);
   
   // Main menu items
   private TextBox input       = new TextBox("Your NXT:", "", 16, TextField.ANY);
   private TextBox input2       = new TextBox("Oponent NXT :", "", 16, TextField.ANY);
      
   private Alert    soundAlert    = new Alert("Sound Alert");
   private Alert    exitAlert    = new Alert("Exit");
   
   private Gauge   alertGauge  = new Gauge(null, false, 20, 0);

   private Gauge    volGauge    = new Gauge("Volume: ", true, 8, 6);
   
    private Display display;
     
    String NXTName;
    String NXTOponentName;

   private MasterSoul _bObj;
   
   public NXTCommMasterUI(MasterSoul bObj){
      NXTName = "NXT";
      NXTOponentName = "NXT";
      input.setText(NXTName);
      input2.setText(NXTOponentName);
      
      _bObj = bObj;
   }

   public NXTCommMasterUI(MasterSoul bObj, String _NXTName,String _NXTOponentName){
      NXTName = _NXTName;
      NXTOponentName = _NXTOponentName;
      input.setText(NXTName);
      input2.setText(NXTOponentName);
      
      _bObj = bObj;
   }   
   
   public void menu(){
      // Create main menu
      menu = new List(NXTWiiVersion, Choice.IMPLICIT);
      menu.append("Set Name", null);
       menu.append("Set Oponent", null);
       menu.append("Connect", null);
       menu.append("NXT Status", null);         
       menu.append("About", null);

       menu.setSelectedIndex(0, true);
       menu.addCommand(EXIT_COMMAND);
       menu.setCommandListener(this);

       input.addCommand(BACK_COMMAND);
       input.setCommandListener(this);

       input2.addCommand(BACK_COMMAND);
       input2.setCommandListener(this);
     
       // Start displaying main menu and handling buttons
       display = Display.getDisplay();
       display.setCurrent(menu);
       display.show(true);      
   }
   
   private void setNXTBrickName(String name){
      if(name.length() >0){
         _bObj.setName(name);
      }
   }
   
   private void showNXTBrickStatus() throws Exception{
      LCD.clear();
      LCD.drawString("Battery / Memory",0,0);
      LCD.drawInt(_bObj.getBattery(),0,1);
      LCD.drawInt(_bObj.getMemory(),0,2);
      LCD.refresh();
   }

   private void showCredits() throws Exception{
      LCD.clear();
      LCD.drawString("Authors:",0,0);
      LCD.drawString("Lawrie Griffiths",0,2);
      LCD.drawString("Juan Antonio",0,3);
      LCD.drawString("Brenha Moral",0,4);
      LCD.drawString("www.lejos.org",0,5);
      LCD.refresh();
   }      
   
   //Event controller
   public void commandAction(Command c, Displayable d){
      NXTName = input.getText();
      NXTOponentName = input2.getText();

      if (c.getCommandId() == CMDID_BACK_TO_MAIN) {

         this.setNXTBrickName(input.getText());

         // Display main menu again
         display.setCurrent(menu);
      } else if (c.getCommandId() == CMDID_EXIT_APP) {
         // Request to exit application
         exitAlert.setType(Alert.ALERT_TYPE_CONFIRMATION);
         exitAlert.setString("Exit " + NXTWiiVersion + "?");
         exitAlert.setCommandListener(this);
         display.setCurrent(exitAlert);
      } else {
         // Handle system commands
         if (d == exitAlert) {
            if (exitAlert.getConfirmation()) {
               display.quit();
            } else {
               display.setCurrent(menu);
            }
         } else if (d == menu) {
            List list = (List) display.getCurrent();
            if (list.getSelectedIndex() == 0) {
               input.setText(NXTName);
               display.setCurrent(input);
            }
            else if (list.getSelectedIndex() == 1) {
               input2.setText(NXTOponentName);
               display.setCurrent(input2);
            }
            else if (list.getSelectedIndex() == 2) {
               try{
                  //volGauge;
                  //Bug detected
                  //this._bObj.controlNXTByTilt(input2.getText());
                  this._bObj.connect(input2.getText());
               }catch(Exception e){
                  LCD.drawString(e.toString(),0,7);
               }
            }
            else if (list.getSelectedIndex() == 3) {
               try{
                  showNXTBrickStatus();
                  Thread.sleep(1000);
               }catch(Exception e){
                  LCD.drawString(e.toString(),0,7);
               }               
            }
            else if (list.getSelectedIndex() == 4) {
               try{
                  showCredits();
                  Thread.sleep(1000);
               }catch(Exception e){
                  LCD.drawString(e.toString(),0,7);
               }               
            }
         }
      }
   }   
   
   //Thread method
    public void run()
    {
        while(true)
        {
            try{               
              this.menu();
           }catch(Exception  e){

           }
        }
    }

}



Code: Select all
import lejos.nxt.*;
import lejos.nxt.comm.*;
import java.io.*;

public class MasterSoul {

   private String _botName;
   private int battery;
   private int memory;
   
   private BTUtilities BTUObj;
   
   public MasterSoul(){
      BTUtilities BTUObj = new BTUtilities();
   }
   
   private TiltSensor _ts;
   
   public MasterSoul(TiltSensor ts){
      BTUtilities BTUObj = new BTUtilities();
      
      _ts = ts;
   }   

   public void setName(String botName){
      _botName = botName;
      BTUObj.setNXTName(botName);
   }

   public String getName(){
      return _botName;
   }

   public int getBattery(){
      battery = Battery.getVoltageMilliVolt();
      return battery;      
   }
   
   public int getMemory(){
      memory = (int)(Runtime.getRuntime().freeMemory());
      return memory;
   }
   
   //EXAMPLE
   public void sendCommand(String NXTReceiver){
      try{
         BTUObj.sendCommandExample(NXTReceiver);
      }catch(Exception e){
         LCD.drawString(e.getMessage(),0,7);
      }
   }
   
   public void connect(String NXTname) throws Exception {
         //TiltSensor controller = new TiltSensor(SensorPort.S1);
         int x, y, z;
         int a;
         String name = NXTname; //"NXT";
        
         LCD.drawString("Connecting ...", 0, 7);
         LCD.refresh();
        
         BTRemoteDevice btrd = Bluetooth.getKnownDevice(name);
         BTConnection btc = Bluetooth.connect(btrd);
        
         LCD.clear();
         LCD.drawString("Connected", 0, 0);
         LCD.refresh();
        
         DataInputStream dis = btc.openDataInputStream();
         DataOutputStream dos = btc.openDataOutputStream();
              
            x = _ts.getXTilt();
            //y = _ts.getYTilt();
            //z = _ts.getZTilt();
            
            //a = (int) _cmps.getDegreesCartesian();
            
            LCD.drawInt(x, 3, 0, 2);
            //LCD.drawInt(y, 3, 0, 3);
            //LCD.drawInt(z, 3, 0, 4);
            //LCD.drawInt(a, 3, 0, 6);
            LCD.refresh();
            
            dos.writeByte(x);
            //dos.writeByte(y);
            //dos.writeByte(z);
            //dos.writeByte(a);
            dos.flush();
            byte ack = dis.readByte();
        
      }   
}



Code: Select all
import java.io.*;
import java.util.*;
import lejos.nxt.*;
import lejos.nxt.comm.*;

public class BTUtilities {

   public BTUtilities(){
      
   }
   
   public void setNXTName(String NXTName){
      Bluetooth.setFriendlyName(getBytes(NXTName));       
   }
   
   public byte[] getBytes(String BTDeviceName){
      byte[] nameBytes = new byte[16];
      
      for(int i=0;i<BTDeviceName.length();i++){
         nameBytes[i] = (byte) BTDeviceName.charAt(i);
      }
      nameBytes[BTDeviceName.length()] = 0;

      return nameBytes;
   }
   
   public void getDeviceList(){
      byte[] cod = {0,0,8,4}; // Toy, Robot
      LCD.clear();
      LCD.drawString("Searching ...", 0, 0);
      LCD.refresh();
      Vector devList = Bluetooth.inquire(5, 10,cod);
      
      if (devList.size() > 0) {
         String[] names = new String[devList.size()];
         
         LCD.clear();
         LCD.drawString("Device List:",0,0);
         for (int i = 0; i < devList.size(); i++) {
            BTRemoteDevice btrd = ((BTRemoteDevice) devList.elementAt(i));
            
            names[i] = btrd.getFriendlyName();
            LCD.drawString(names[i],0,i+1);
         }
         LCD.refresh();
      } else {
         LCD.clear();
         LCD.drawString("no devices", 0, 0);
         LCD.refresh();
         try {
            Thread.sleep(2000);
         }catch (InterruptedException e){}
      }   
   }
   
   public void discoverNXTBricks(){
      byte[] cod = {0,0,8,4}; // Toy, Robot
      LCD.clear();
      LCD.drawString("Searching ...", 0, 0);
      LCD.refresh();
      Vector devList = Bluetooth.inquire(5, 10,cod);
      
      if (devList.size() > 0) {
         String[] names = new String[devList.size()];
         
         LCD.clear();
         LCD.drawString("Device List:",0,0);
         for (int i = 0; i < devList.size(); i++) {
            BTRemoteDevice btrd = ((BTRemoteDevice) devList.elementAt(i));
            
            Bluetooth.removeDevice(btrd);
            Bluetooth.addDevice(btrd);            
            
            names[i] = btrd.getFriendlyName();
            LCD.drawString(names[i],0,i+1);
         }
         LCD.refresh();
      } else {
         LCD.clear();
         LCD.drawString("no devices", 0, 0);
         LCD.refresh();
         try {
            Thread.sleep(2000);
         }catch (InterruptedException e){}
      }      
   }
   
   public void sendCommandExample(String NXTReceiver) throws Exception{
      LCD.drawInt(0,0,5);
      //LCD.drawString("Try to connect...", 0, 6);
      LCD.refresh();
      
      //Bluetooth.
      BTRemoteDevice btrd = Bluetooth.getKnownDevice(NXTReceiver);

      BTConnection btc = Bluetooth.connect(btrd);
      
      //LCD.clear();
      LCD.drawInt(1,0,5);
      //LCD.drawString("                 ",0,6);
      //LCD.drawString("Connected", 0, 6);
      LCD.refresh();
      
      DataInputStream dis = btc.openDataInputStream();
      DataOutputStream dos = btc.openDataOutputStream();
            
      for(int i=0;i<100;i++) {
         try {
            LCD.drawInt(i*30000, 0, 6);
            LCD.refresh();
            dos.writeInt(i*30000);
            dos.flush();         
         } catch (IOException ioe) {
            LCD.drawString("Exception", 0, 7);
            LCD.refresh();
         }
         
         try {
            LCD.drawInt(dis.readInt(),0,7);
            LCD.refresh();
         } catch (IOException ioe) {
         }
      }
      
      try {
         dis.close();
         dos.close();
         btc.close();
      } catch (IOException ioe) {
      }      
   }
   
   public boolean existNXTBrick(String NXTBrickName){
      boolean flagDetected = false;
      
      Vector devList = Bluetooth.getKnownDevicesList();
      if (devList.size() > 0) {
         String[] names = new String[devList.size()];
         for (int i = 0; i < devList.size(); i++) {
            BTRemoteDevice btrd = ((BTRemoteDevice) devList.elementAt(i));
            names[i] = btrd.getFriendlyName();
            if(names[i] == NXTBrickName){
               flagDetected = false;
               break;
            }
         }
      }
      
      return flagDetected;
   }
   
      public int getValue(byte buf) {
         int val = (int) (buf);
         return val;
         }    
}

Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 296
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby esmetaman » Thu Dec 06, 2007 6:53 pm

I have noticed that NXT brick sounds differents when it tries to send data with BT. When Master program tries to send the second message, it doesnt sounds.

I need to solve this problems:

How to maintain with life listener thread in slave nxt brick and how to send 2 or more message in master nxt brick.

thanks
Juan Antonio Breña Moral
http://www.juanantonio.info/lejos-ebook/
http://www.iloveneutrinos.com/
User avatar
esmetaman
Advanced Member
 
Posts: 296
Joined: Wed Sep 13, 2006 12:16 am
Location: Madrid, Spain

Postby lawrie » Fri Dec 07, 2007 10:59 am

I have not studied your examples in detail, but a few points that may be useful:

- leJOS Bluetooth comms in connection oriented. It is inefficient and less relable to keep opening and closing connections if the same master is talking to the same slave. It is a better to keep the connection open and send the messages as part of the same data stream.
- If you start a listener thread and then drop out of your main method, the program will end when the threads terminates. If you want to receive a series of connections you need a listener thread that has a loop waiting for connections., processing one until if finishes, closing it, and then waiting for another connection, in the way that StartUpText or the BTReceive example does. This can be the main thread or a separate listener that you start.
- You are not closing your connections. leJOS currently support only one connection at a time. If you do not close a connection (BTConnection.close()) you will not be able to open another one - the BC4 chip will stay in stream mode and the second waitForConnection will fail.
- the current leJOS Bluetooth implementation has some bugs in it that makes closing connections a bit unreliable. Adding a short delay of say 100 milliseconds after a close and before waiting for the next connection may help. The next release should be more reliable.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm


Return to NXJ Software

Who is online

Users browsing this forum: No registered users and 4 guests

more stuff