Jan 15, 2012

Arduino Bluetooth Link


In a previous Arduino project, I used the BlueSmirf Bluetooth Breakout Board to communicate with my Android phone. There was absolutely no special code on the Arduino to handle Bluetooth since, by default, the BlueSmirf is set as Slave and will accept any connection call. The phone app was doing all the work.

The next logical step was to use the BlueSmirf interface by programming the Arduino. Using a second Bluetooth board, I decided to create a link between two autonomous Arduinos. To make things interesting, I've set a couple of rules for the project. I wanted to heave the same code on both Arduinos and have the whole connection process be automatic. I also wanted the Master device to scan for other devices, retrieve the MAC address, connect and send data.  Here's the video of the final result:



My biggest issue started with the Sparkfun proto shield for Arduino. It has a built-in socket for their Bluesmirf device. Nice marketing move! This socket is hardwired to use the Arduino pins 0 and 1 for communications. It all looks good until you need to use it in the real world. Here are the pros and cons:

Pros:

  • No wiring needed to connect the Bluesmirf board.
  • No extra library needed to do serial communications.

Cons:

  • You must remove the Bluesmirf breakout board every time you need to plug the Arduino board in the computer. Why? Because of the hardwired Bluesmirf socket the Arduino board communications are mixed with the Bluesmirf interface.
  • Another consequence of the previous problem: You can't used the USB serial output to the computer to send debug info. That is really annoying when debugging your project.
  • The power is always ON for the Bluesmirf.

I'll fix this by using different pins for the Bluetooth communication using the NewSoftSerial library. I will also modify the Sparkfun Bluesmirf socket to use any communication pins and to have control on the power usage.

For more details continue reading after the break. (Warning! Geeky stuff about code and electronics)




Tips about BlueSmirf interface
  1. Read the User Manual
  2. Serial speed: By default, BlueSmirf is set to 115200 so you need to call Serial.begin(115200); before sending the first command.
  3. The “$$$” command is the only one that is not followed by a carriage return. Why? To complicate things of course. Use print() for the “$$$” command and println() for all other commands.
  4. Read and validate all the responses that are sent back.
  5. Wait 100ms delay after each command you send and before trying to read the response. This will give Bluesmirf the time to process the command.
  6. Don't forget to exit the command mode (using “---”). Some commands are not effective until you have exited the command mode (e.g. MS command).

A simple test
A quick way to get two Arduino+Bluesmirf connected is by hard-coding the Slave's MAC address into the Master connection command. With this there's no need for code in the loop() function. In the following example, the MAC address of the Slave Bluesmirf is 000666123ABC. The example also assumes that the RX and TX are connected to pins 0 and 1. Here's the code for both Master ans Slave:

//Master code
void setup() {
  Serial.begin(115200);
  Serial.print("$$$");
  delay(100);
  Serial.println("SM,1");
  delay(100);
  Serial.println("C,000666123ABC");
  delay(100);
  Serial.println("---");
}


//Slave code
void setup() {
  Serial.begin(115200);
  Serial.print("$$$");
  delay(100);
  Serial.println("SM,0");
  delay(100);
  Serial.println("---");
}

To test, start the Slave 5 seconds before the Master. The 'Connect' lights on both Bluesmirfs will turn green when the connection is open.

Instructable
After many questions about this project, I finally decided to make an Instructables about it.


42 comments:

  1. I hope I understand this corectly, and it would help me greatly if I am, so tell me if I'm right.

    by running the master and slave code on two separate BlueSmirf Gold modules I can then just replace a wired serial connection with those modules without editing the rest of my code?

    Sincerely,
    Anton Stamhuis.
    (Anton[at]fullformfreedom[dot]cc

    ReplyDelete
    Replies
    1. I just went ahead and tested it, and it seems I was right. :)

      one thing though, the "MS" that you have in your code there should be "SM"

      greetings,
      Anton Stamhuis

      Delete
    2. Thanks for catching this mistake! I'm glad this could help.

      Delete
    3. no problem, and yeah, I mostly just didn't know where to start. but I got it figured out now, so thank you for that. ^^

      one more thing I ran into, I was getting a few errors after I copied the code from your blog, figured out it was a problem with the quotation marks. just had to take them out and replace them.

      Tomorrow I shall do some wiring and get my project back up and running. :3

      thanks again.

      ~anton

      Delete
  2. Cool. I'll follow that on Twitter. If you have any other problems, I can probably help since I have 2-3 projects using Bluetooth.

    I'm not sure about the quotation marks. They might have been modified during the copy-paste.

    This is an ultra simplified version of the code I'm running. If you need more help I can send you my whole project code to make things easier.

    ReplyDelete
  3. Very cool! But what exactly do those commands mean? Serial.print(“$$$”) // Command Mode?
    Serial.println(“SM,1”); // Maybe setting it to receive?
    Serial.println(“C,000666123ABC”); //Connect to that Address?
    Serial.println(“---”); //Just for kicks?

    Thanks For the help!

    ReplyDelete
  4. For those specific commands:
    $$$ : is to set the device in command mode
    SM, : is to set the the device mode
    C,[address] : is to connect to a specific address
    --- : is to exit the command mode

    I explain some in the post but, for the best reference, I have a link to the User Manual where all the commands are defined.

    ReplyDelete
  5. could u show us how to make that?

    ReplyDelete
    Replies
    1. I have made an Instrucable about it. http://www.instructables.com/id/BlueTooth-Link-with-auto-detect-connect/

      Delete
  6. After a short battle with the Blogger "WYSIWYG" editor I finally have fixed my bad quotes characters in the print statements.

    ReplyDelete
  7. Is it possible to connect more than one bluetooth device to the arduino and log data? Lets say I had 4 arduinos and 3 of them want to connect to the 4th arduino, will there be a problem?

    ReplyDelete
    Replies
    1. Yes you can connect more than one Bluetooth device on a single Arduino by using ‘SoftwareSerial Library’ and opening a different serial connection for each device. The down side of this approach is that your 4th Arduino would need 3 bluetooth devices ($$$).
      On the other hand, it looks like a single Bluetooth device could manage multiple connections but I haven’t tried that yet.

      Delete
    2. Thank you, I appreciate your quick response. I will let you know how it goes.

      Delete
    3. Dear Phillipe, thanks for your useful response which solved my question as well. Is there any other solution rather than what you said?

      Delete
    4. I'm happy to be helping. Some bluetooth device can support a multiple connection called piconet where 1 master can connect to up to 7 slave devices. I have not try this yet.

      Delete
  8. About multiple connections: So far I could only find one Bluetooth SMD Module that can support multiple connection (Piconet <7>). It's the Rayson BTM-182. I'll try to get one and start working on a Bluetooth swarm network.

    ReplyDelete
  9. This comment has been removed by a blog administrator.

    ReplyDelete
    Replies
    1. @Dwin I had to remove the comment since it contained a link to a .rar file. This is unsafe so please use standard URL links pointing to safe HTML content.

      Delete
    2. I'm sorry about it sir my bad.
      I just like to ask if this product can be use as an alternative to Blue Smirf that you use for interfacing your Arduino RObots. We will interface it to mindwave mobile controller of neurosky

      btw sir here is the link of the product :
      http://www.e-gizmo.com/KIT/BLUETOOTH%20SHIELD.html

      Delete
    3. With a quick read through the manuals (link at the end) it is clear that all the necessary functions are present to make a similar-type of link.
      I say 'similar' because if you use some 'Slave Only' modules (EGBT-04S), you won't be able to run the same code on those. So, I would suggest using only the Master-Slave modules (EGBT-045MS) which will resemble the BlueSmirf behavior.

      Link to the manual (link is in on the left): http://www.e-gizmo.com/KIT/egbt-04.htm

      Delete
    4. Thank you for your quick reply sir!
      your blog is really a great help :)
      Godbless!

      Delete
  10. Hi Phillipe,

    I owuld like to create multiple game devices with 1 joystick + 4 buttons + 1 rumble.

    In first, can I establish a communication in both sides : gamepad <-> PC with 2 BT devices ?

    Moreover, have you test the "Rayson BTM-182" to use only one BT device and listen all gamepad devices ?

    Thx, Gilles

    ReplyDelete
    Replies
    1. Sadly I haven't tested it yet but I'm planning to get one soon. It supports up to 7 connections (with piconet) and I'd like to build an easy to use networking API for it.

      Are you having trouble using this device?

      Delete
    2. I'm still waiting for it. I should receive it in one or two weeks :/
      (it seams that it's no more produced) ... do you know another kind of this device ; that could connect with multiple slaves ?

      Delete
    3. There's the "BT44-191S Bluetooth Class 2" that you can find at zbaus.com. You can find more by google'ing "bluetooth module supporting piconet". Be careful because there's a lot of Chinese knockoffs on the market.

      Delete
  11. Hi Phillipe,

    I'm starting a new project and I want to connect two arduinos via bluetooth to control some relays(the relays are located at the slave).
    The bt modules I buy are: http://i.ebayimg.com/t/Wireless-Serial-4-Pin-Bluetooth-RF-Transceiver-Module-with-Backplane-RS232-New-/00/s/ODAwWDgwMA==/$%28KGrHqF,!oMFC3OZgs2LBQzq4jts7Q~~60_12.JPG
    The connections I made are ok, Vcc->arduino3.3V GND->arduinoGND TXD->RXD RXD->TXD
    Do I need switches to define master and slave or the software does it?

    Thank you in advance
    Steve

    ReplyDelete
    Replies
    1. This module can be interfaced using AT commands. If by default they are in Slave mode (like bluesmirf) then you will have to set one to be the Master, using AT commands (AT+ROLE=1).
      Google this "jy mcu bt board commands" and/or this "bluetooth at commands" and you'll find many documentation and examples of how to use basic AT commands for this device.
      Let me know how it turns out.

      Delete
  12. Thank you for your quick answer.
    I check it on google but I can't understand if I need a serial connection between bt module and my pc to define master and slave or I can do this with arduino and his software?
    Sorry for my ignorance this is the first time I get involved with bt and arduino.
    Steve

    ReplyDelete
    Replies
    1. Connect the Arduino pin0 (Rx) to BTmodule Tx and Arduino pin1 (Tx) to BTmodule Rx. Connect power and ground wires to the BTmodule. Then try something like this in your Arduino sketch:

      //Set the serial with the right baud rate for JY-MCU
      Serial.begin(38400);

      //Test the communications
      Serial.println("AT");
      //Here you can add a loop/function to read the output that should be "OK"

      //Set as master
      Serial.println("AT+ROLE=1");

      Delete
    2. Follow up: This my last answer help? Keep me updated, I'd like to know how it turned out.

      Delete
    3. Hello again Phillipe,

      I took 'SoftwareSerialExample' from arduino 1.0.1 examples and changed a little.I don't know if the code is right..

      #include
      SoftwareSerial mySerial(2, 3);
      void setup(){Serial.begin(38400);Serial.println("Goodnight moon!");mySerial.println("Hello, world?");}
      void loop(){Serial.println("AT+ROLE=1");}

      The compiler says,done uploading but I have an error:
      avrdude: stk500_getsync(): not in sync: resp=0x00

      Steve

      Delete
    4. It looks like you can't upload to your Arduino. Do you have wire(s) connected to pin0 and/or pin1? If so you must disconnect them while your are uploading a sketch. Then, in the code, make sure that you are sending the AT commands to the right serial interface. In your example you are using(mixing) 2 interfaces.

      Delete
    5. I disconnected the TX and RX wires and everything seems to be OK! I made some corrections to the code.

      #include
      SoftwareSerial mySerial(2, 3);
      void setup(){Serial.begin(38400);Serial.println("Goodnight moon!");Serial.println("Hello, world?");}
      void loop(){Serial.println("AT+ROLE=1");}

      I run 'putty' and at the serial section I choose my com port and 38400 speed.Then 'open' and on console screen AT+ROLE=1 was running again and again.
      Am I ok?

      Thanks you again!

      Delete
    6. Are you trying to communicate with the BT device and sending debug info on 2 separate serial interfaces? If so, you have to tweak your code. Currently mySerial(pins 2&3) is not used while arduino serial default (pins 0&1) is use to do both. Maybe we could continue this conversation on Google+ (email, chat or hangout) it would go faster.

      Delete
  13. Hello Phillipe,

    I have two RN42XV Bluetooth modules each on my two Arduino Uno boards. I'm trying to connect the two together, so on the serial monitor I enter into command mode, "$$$", and then "c,<>" to connection with each other. It says that it is "TRYING" but then just freezes, but the LEDs on the Bluetooth modules indicate they are connected. However it doesn't say that the connection is successful. Any ideas?

    Earl

    ReplyDelete
    Replies
    1. Try "SM,1" before calling "c,<>". Don't forget to close the command mode with "---" after the "c,<>".

      Delete
  14. HI Phillipe
    I copy your code and compiled it successfully to my Arduino devises ,sadly I never got connection between the two BT
    I am using standard Bluetooth BC417 module and two separate Arduino devises (Arduino Nano & Arduino Uno).
    Do you have any idea why ?
    Thanks,
    Yaniv

    ReplyDelete
    Replies
    1. The code in this post in intended to work with the BlueSmirf device. The device you mention seems to us the AT commands. Other comments in this page are talking about the AT commands.

      Delete
    2. O.K Thanks
      I will try looking at the AT commends how to do this

      Delete
    3. HI
      Well I have investigated this thing for the last few hours.
      I have tried to enter the AT command and I got "O.K" at the siral port that means that I can send AT command
      But when I have tried to send " BluetoothSerial.write("AT+ROLE=1");"
      I got nothing.
      I think that my devise can't be Master, could it be ?
      I am working with Linovor HC-06
      DO you now if St Sak succeed to connect the tow Arduino's over BT

      This is my code :
      #include

      /* DIO used to communicate with the Bluetooth module's TXD pin */
      #define BT_SERIAL_TX_DIO 10
      /* DIO used to communicate with the Bluetooth module's RXD pin */
      #define BT_SERIAL_RX_DIO 11

      /* Initialise the software serial port */
      SoftwareSerial BluetoothSerial(BT_SERIAL_TX_DIO, BT_SERIAL_RX_DIO);

      void setup()
      {
      /* Set the baud rate for the hardware serial port */
      Serial.begin(9600);
      /* Set the baud rate for the software serial port */
      BluetoothSerial.begin(9600);
      BluetoothSerial.write("AT+VERSION");

      BluetoothSerial.write("AT+ROLE=1");
      }

      /* Main loop that will pass any data to and from the Bluetooth mode to the
      host PC */
      void loop()
      {
      /* If data is available from the Bluetooth module then pass it on to the
      hardware serial port. */
      if (BluetoothSerial.available())
      Serial.write(BluetoothSerial.read());

      /* If data is available from the hardware serial port then pass it on
      to the Bluetooth module. */
      if (Serial.available()){
      BluetoothSerial.write(Serial.read());
      }
      }

      Thanks,
      I am truly grateful yaniv,

      Delete
    4. I wish I had a pair of AT devices to test this. I don't know if @St Sak got his project to work. I haven't heard anything since my last comment in January. You should check the specs of your device to know if it can be set to Master Mode. Some device are Salve only while other device can be either Master or Slave.

      Delete
    5. O.K thanks the BT can be slave only :)
      I need to order HC-05

      Delete