Making the Bluetooth connection

Discussion specific to NXT-G, NXC, NBC, RobotC, Lejos, and more.
Post Reply
mcsummation
Posts: 220
Joined: 23 Jan 2012, 17:07
Location: Round Rock, TX

Making the Bluetooth connection

Post by mcsummation »

A little background: From the PC I can connect to an NXT via Bluetooth using the c++ library found at http://www.norgesgade14.dk/bluetoothlibrary.php. I can wake up the BT connection and start a program in the NXT.

Now that I've moved to NXC and have a second NXT, I'm trying to do some of the same things. Once the BT connection is set up from the master, the master can start a program on the slave. However, what I haven't found is the "wake up the BT connection to the slave". The 2 NXTs have already been "introduced" to each other, so it should be easy enough to do it, given the name of the slave NXT and the desired connection number. So, what's the magic routine name?
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Making the Bluetooth connection

Post by HaWe »

I can confirm it: it's really not very comfortable.
I use this for the master:

Code: Select all

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void BTConnect(int conn) { // pass 1, 2, or 3 for each slave one after the other
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  printf("searching slv %d", conn);
  do {
    CommExecuteFunctionType args2;
    args2.Cmd = INTF_CONNECT;
    args2.Param1 = conn-1; // device index
    args2.Param2 = conn;   // connection index
    SysCommExecuteFunction(args2);  // make the connection
    Wait(20);
  } while (BluetoothStatus(conn)==STAT_COMM_PENDING) ;
  printf("connected: slv %d", conn);
}
edit: Wait(20) inserted

and this for the slaves:

Code: Select all

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void BTCheck()  {  // checking BluetoothStatus on the slave's channel (0)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  do  {
    printf("%s", "searching BT master");
    Wait(50);
  } while (BluetoothStatus(0)!=NO_ERR)
  printf("%s", "BT master connected");
}
when starting the first time, better first start the slave(s), then finally the master.
If it might hang (BT is quite shaky) switch off all NXTs and then start anew.
Last edited by HaWe on 11 Feb 2012, 15:54, edited 1 time in total.
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Making the Bluetooth connection

Post by afanofosc »

I would definitely not use Doc's master routine unmodified. You should only call the connect function one time and then wait in a loop after the call for the status to be something other than STAT_COMM_PENDING. But you don't need to use the enhanced firmware only CommExecuteFunction system call anymore. LEGO added to the standard firmware a system call function specifically for making a bluetooth connection. You should use that one instead of CommExecuteFunction.

See SysCommBTConnection in the online NXC help.

http://bricxcc.sourceforge.net/nbc/nxcd ... 0d3ae.html
http://bricxcc.sourceforge.net/nbc/nxcd ... _type.html
http://bricxcc.sourceforge.net/nbc/nxcd ... ample.html

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Making the Bluetooth connection

Post by HaWe »

like this?

Code: Select all

 
// modified version but not working reliably though!

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void BTConnect(int conn) { // pass 1, 2, or 3 for each slave one after the other
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  printf("searching slv %d", conn);
  CommExecuteFunctionType args2;
  args2.Cmd = INTF_CONNECT;
  args2.Param1 = conn-1; // device index
  args2.Param2 = conn;   // connection index
  SysCommExecuteFunction(args2);  // make the connection
  while (BluetoothStatus(conn)==STAT_COMM_PENDING) {Wait(20);}
  printf("connected: slv %d", conn);
}
I'll be very glad if you could write the whole code for connections numbers (not BT names!) explicitely both for the master and for the slaves (1-3).
I have been searching a long long time for a code that really works even for several slaves (which my code actually does!) because it's not very lucidly documented anywhere!

It least for me personally your links don't help very much either.

I now tested this last version but the BT connection is not set up reliably. The program pretends to having set up BT conn but actually it's dead.
My old version works more reliably. Maybe I should also insert some waits(). (Already done.)
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Making the Bluetooth connection

Post by afanofosc »

The problem with your modified code is that it will skip past the while loop without ever waiting because the status will not immediately be STAT_COMM_PENDING. So use a do while loop like you have in your original code but call the function before you enter the loop like in your modified code. i.e., scef do wait 20 while stat_comm_pending

That should work reliably, but I have not tested it. Certainly calling the CommExecuteFunction system call over and over and over again is a bad idea.

Another thing that is odd is that you use conn-1 for the device index and conn as the connection index. How is it that you can be sure that the NXT that you want to connect to connection 1 is actually in the device table at index 0 and so forth for the NXTs you want to connect for 2 and 3? You really should pass the device table index as a separate parameter since to the best of my knowledge it is possible that you could have laptops, cell phones, gps devices, etc... in the device table before any NXT devices. And if you prefer to connect to a device by its device table index then you can look up the name from the device table using the device table index and then use the name in the SysCommBTConnection system call.

John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Making the Bluetooth connection

Post by HaWe »

well, for my purposes I can be sure that device numbers equal the connection numbers or 1 less.
So how about the definite code? (my first code works , the 2nd acc to your proposals doesn't, so I don't see why that shoud be a "bad idea")
and how about the "new" fw function?
afanofosc
Site Admin
Posts: 1256
Joined: 26 Sep 2010, 19:36
Location: Nashville, TN
Contact:

Re: Making the Bluetooth connection

Post by afanofosc »

Did you change the 2nd to match my recommendation or not?

Code: Select all

void BTConnect(byte devIdx, byte conn) {
  printf("searching slv %d", conn);
  CommExecuteFunctionType args2;
  args2.Cmd = INTF_CONNECT;
  args2.Param1 = devIdx; // device index
  args2.Param2 = conn;   // connection index
  SysCommExecuteFunction(args2);  // make the connection
  do { Wait(MS_20); } while (BluetoothStatus(conn)==STAT_COMM_PENDING);
  printf("connected: slv %d", conn);
}
Or this:

Code: Select all

void BTConnect(byte devIdx, byte conn) { 
  printf("searching slv %d", conn);
  CommBTConnectionType args;
  args.Name = BTDeviceName(devIdx);
  args.ConnectionSlot = conn; // connection index
  args.Action = TRUE;   // connect (FALSE == disconnect)
  SysCommBTConnection(args);  // make the connection
  do { Wait(MS_20); } while (BluetoothStatus(conn)==STAT_COMM_PENDING);
  printf("connected: slv %d", conn);
}
John Hansen
Multi-platform LEGO MINDSTORMS programming
http://bricxcc.sourceforge.net/
mcsummation
Posts: 220
Joined: 23 Jan 2012, 17:07
Location: Round Rock, TX

Re: Making the Bluetooth connection

Post by mcsummation »

I have tested the following code and it works. It's based on what John posted earlier (which didn't work). I called it "ConnectBT.h"

Code: Select all

// This handles the connect/disconnect from a slave NXT.

bool ConnectBT(byte Conn, string SlaveName)
{
  CommBTConnectionType args;
  args.Name = SlaveName;      // Name of the slave NXT
  args.ConnectionSlot = Conn; // This is the desired connection slot
  args.Action = true;         // Connect to the slave
  if(!BluetoothStatus(Conn)==NO_ERR)
  {
    SysCommBTConnection(args); // try to connect.
    for (int i = 0; i < 10000; i++)  // Will try for about 10 seconds before failing.
    {
      if(BluetoothStatus(Conn)==NO_ERR)
        return true;  // Connect has completed.
      Wait(1);
    }
  }
  return false;
}

sub DisconnectBT(byte Conn)
{
  CommBTConnectionType args;
  args.ConnectionSlot = Conn; // This is the desired connection slot
  args.Action = 0;            // Disconnect
  if(BluetoothStatus(Conn)==NO_ERR)
  {
    // It is connected, so disconnect it.
    SysCommBTConnection(args);
    for (int i = 0; i < 10000; i++)  // Will try for about 10 seconds.
    {
      if(BluetoothStatus(Conn)!=NO_ERR)
        break;  // Disconnect has completed.
      Wait(1);
    }
  }
}
The following is the main task:

Code: Select all

#define CONNECTION 1

#include "ConnectBT.h"

task main()
{
    DisconnectBT(CONNECTION);   // In case it is already connected to something.
    if (ConnectBT(CONNECTION, "JHS_NXT"))
        TextOut(0, LCD_LINE6, "Connected");
    else
        TextOut(0, LCD_LINE6, "Failed");
    Wait(SEC_5);
    DisconnectBT(CONNECTION);
}
HaWe
Posts: 2500
Joined: 04 Nov 2014, 19:00

Re: Making the Bluetooth connection

Post by HaWe »

I tried this

Code: Select all

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void BTConnect(int conn) { // pass 1, 2, or 3 for each slave one after the other
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  printf("searching slv %d", conn);
  CommExecuteFunctionType args2;
  args2.Cmd = INTF_CONNECT;
  args2.Param1 = conn-1; // device index
  args2.Param2 = conn;   // connection index
  SysCommExecuteFunction(args2);  // make the connection
  do {Wait(20);} while (BluetoothStatus(conn)==STAT_COMM_PENDING); // should wait but actually doesn't
  printf("connected: slv %d", conn);

  PlayTone(TONE_G4, 50);   Wait(50);
  PlayTone(TONE_C5,100);   Wait(100);
}
but the master program runs through these lines although no connection is already established (e.g., although no slave is already running any program at all or is even completely switched off):
it doesn't wait until the slave has connected, it plays the tones and starts all over.
Post Reply

Who is online

Users browsing this forum: Semrush [Bot] and 7 guests