Bluetooth communication between 2 Arduinos

Hello all,

I have a simple project, but I am still working out the kinks on the Bluetooth communication.
Project: 2 Arduino Nanos each with Bluetooth HC-05. One of the Nanos also has an Ultrasonic HR-SR04. The goal is to have the ultrasonic Nano send the data via Bluetooth to the other Nano where that data can be used for the rest of the project.

I have paired and bind the Bluetooth modules and the ultrasonic Nano has the master Bluetooth while the receiver Nano has the Slave Bluetooth. They seem to be paired with synchronized blinking.

The Master code looks something like this:

//Bluetooth Nano Master
//Sends the ultrasonic distance to the Slave

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX

// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;

// defines variables
long duration;
int distance;

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
BTserial.begin(38400);

}

void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

// Calculating the distance
distance= duration*0.034/2;

// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);

// Send the distance via Bluetooth
BTserial.write(distance);
}

Question 1: Is this the right way to send the results of the ultrasonic data via Bluetooth?
BTserial.write(distance);

Here is the Receiver Nano

//Bluetooth Nano Slave
//Receives the ultrasonic distance from the Master

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX

void setup() {
Serial.begin(9600);
BTserial.begin(38400);
}

void loop() {
  if (BTserial.available()) {
    Serial.write(BTserial.read());
    Serial.println(BTserial.read());
  }
  if (Serial.available()) {
    BTserial.write(Serial.read());
    Serial.println(BTserial.read());
  }
}

Question 2: What is the correct way to output what a Bluetooth module receives for working in a script and outputting to the Serial Monitor for debugging?

As a confirmation of this working, I am opening the Serial Monitor with the Slave and expecting to see the distance reading from the Master, but it isn't working.

I am just getting started with Arduinos with this project and I can find many instructions on binding HC-05s and using HC-05s and Android, but I am having difficulties with Arduino-Arduino. Any help would be great!

The (usual) default baud rate for HC05s is 9600, unless you changed it using AT commands.

Use BT.print(), write() writes one byte. Distance is an int data type (2 bytes).

The serial input basics tutorial shows how to reliably read serial data.

Hi groundFungus,

You are right! I didn't change the baud rate during setup and 9600 is the correct value. I changed that and the Master's print line

FROM
BTserial.write(distance);

TO
BTserial.print(distance);

Also, I simplified the Slave loop to just one line.
Serial.println(BTserial.read());

The Slave monitor is now outputting something, but not the expected data... it is -1

I am not sure if the problem is the Master sending or the Slave receiving. Any other suggestions?

Post the latest code so we don't have to guess what you did. I think that -1 means that nothing was received.

You will need to put the HC05s in AT mode to configure them. Has that been done? Here is a page that may help you.

I set up 2 HC05 modules on 2 Unos and set the BT modules up according to the instructions on the page that I linked above. Then I wrote very simple master and slave test codes to see if the slave would receive from the master. Each BT module connected Uno pin 4 (ssRX) to BT TX and Uno pin 7 (ssTX) to BT RX through a 1K, 2K voltage divider (as shown on the linked page).

Note that I set the communication baud rate (not AT) to 38400 per the linked page while in AT mode.

Master test code:

#include <SoftwareSerial.h>

SoftwareSerial bt(4, 7);


void setup()
{
   Serial.begin(115200);
   bt.begin(38400);
   bt.println("\n printing millis every second \n");
}

void loop()
{
   static unsigned long timer = 0;
   unsigned long interval = 1000;
   if (millis() - timer >= interval)
   {
      timer = millis();
      bt.println(millis());
   }
}

Slave test code:

#include <SoftwareSerial.h>

SoftwareSerial bt(4, 7);


void setup()
{
   Serial.begin(115200);
   bt.begin(38400);
}

void loop()
{
   if (bt.available())
   {
      Serial.print(char(bt.read()));
   }
}

Output from slave:

 printing millis every second 

1000
2000
3000
4000
5000
6000
7000

They seem to be paired with synchronized blinking.

Not paired is a steady quick flash, Paired is 2 quick flashes and a pause of a couple seconds and AT mode is very slow on-off flash. It is not necessary that they be synchronized, it is the pattern that is important.

TEST CODE WAS GREAT HELP! I had my RX and TX mixed! Communication is there, but the output still isn't as expected. It looks like the output is only 2 characters and it is including the 13 Return and 10 New Line even though I am using the println. Here is the most current code for Master and Slave and example of Master Serial Monitor and Slave Bluetooth Serial Monitor.

Master

//Bluetooth Nano Master
//Sends the ultrasonic distance to the Slave

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX

// defines pins numbers
const int trigPin = 9;
const int echoPin = 10;

// defines variables
long duration;
int distance;

void setup() {
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);
BTserial.begin(9600);

}

void loop() {
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);

// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);

// Calculating the distance
distance= duration*0.034/2;

// Prints the distance on the Serial Monitor
Serial.print("Distance: ");
Serial.println(distance);

// Send the distance via Bluetooth
BTserial.println(distance);
}

Slave

//Bluetooth Nano Slave
//Receives the ultrasonic distance from the Master

#include <SoftwareSerial.h>
SoftwareSerial BTserial(2,3); // RX | TX

void setup() {
Serial.begin(9600);
BTserial.begin(9600);
}

void loop() {
  if (BTserial.available()) {
//    Serial.write(BTserial.read());
    Serial.println(BTserial.read());
  }
//  if (Serial.available()) {
//    BTserial.write(Serial.read());
//    Serial.println(BTserial.read());
//  }

//Serial.println(char(BTserial.read()));
}

Sample Master output

Distance: 356
Distance: 355
Distance: 355
Distance: 355
Distance: 355
Distance: 355
Distance: 356
Distance: 355
Distance: 357
Distance: 357
Distance: 355
Distance: 356
Distance: 356

Sample Slave output

13
10
51
53
53
13
10
51
53
54
13
10
51
53

Looks like 13,10,515,353,13,10,515,354,...
Not sure what 515 is, but the 13 and 10 look familiar.

Thanks for all your help!

No, what you are seeing is 51,53,53,13,10. Those are the ASCII codes for 3,5,5,CR,LF. If you will notice, in my test code I converted the ASCII code to characters in the Serial.print(char( bt.read())); line.

Also in the test code I allow some time between readings (interval) so as not to flood the serial ports and to minimize false reading from echos that are still ringing from the last ping. It takes a bit of time for the echos to die down. I usually do not range more often than every 50ms.

YOU ARE THE MAN! You did it! Fantastic! I didn't realize that the timer was a generic timer that I could use elsewhere. Also, I did overlook the char... that makes sense that it was ASCII. It was coming down the monitor one character at a time in ASCII. I changed println to print and everything lined up! Thank so much for your help!