ESP32 Arduino Serial over Bluetooth: Receiving data

In this tutorial we will check how to receive data on a serial connection operating over Bluetooth classic. The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.

 

Introduction

In this tutorial we will check how to receive data on a serial connection operating over Bluetooth classic.

This tutorial will be very simple since we are going to use the BluetoothSerial library for the Arduino core, which exposes a very high level API much similar to the regular wired serial interface.

Note that, at the time of writing, the code of the mentioned library had just been merged to the Arduino Master branch, so you may need to get the latest changes from there. You can check here how to update your Arduino core version.

The tutorial shown here was based on the Arduino core BluetoothSerial library example, which can be see seen here. It’s a really good example to get started, which I encourage you to try.

If you want to know a little bit more of the lower level Bluetooth functionalities, you can check the Related Posts section at the end of this tutorial, which includes some tutorials on how to use the IDF Bluetooth API on the Arduino core.

The tests of this ESP32 tutorial were performed using a DFRobot’s ESP-WROOM-32 device integrated in a ESP32 FireBeetle board.


The code

We start our code by including the BluetoothSerial.h library, which makes available the Bluetooth related functionalities we will need.

#include "BluetoothSerial.h"

Next we will need an object of class BluetoothSerial. We will use this object to initialize the Bluetooth stacks (controller and host) and to established the serial communication over Bluetooth.

This object works very similarly to the Serial extern variable we use to establish a regular wired serial communication.

BluetoothSerial SerialBT;

Moving on to the Arduino setup function, we start by opening a wired serial connection, so we can print the content we receive via Bluetooth.

Serial.begin(115200);

Next we call the begin method of the BluetoothSerial object, to initialize the Bluetooth interface. This method will handle all the lower level initialization, so we can use the Bluetooth functionality without having to worry about what happens under the hood.

As input, the begin method receives the name we want to assign to the ESP32, which will be shown to other Bluetooth enabled devices when performing a scan.

As output, the method returns a Boolean value indicating if the initialization was correctly performed. Thus, to confirm everything executed fine, we will do an error check wrapping the begin method call.

Note that we are not going to take in consideration the result of this call in the main loop function, which will assume that everything went fine. Nonetheless, for a final robust code, you should handle error situations and act accordingly.

if(!SerialBT.begin("ESP32")){
    Serial.println("An error occurred initializing Bluetooth");
}

Now, on the Arduino main loop, we will handle the received data. Our flow will be very simple and will consist on reading available bytes one by one from the Bluetooth connection and printing them to the wired serial connection.

To check if there are bytes available, we can use the available function of the BluetoothSerial object. This function behaves like the Arduino serial available function, which returns the number of bytes available for reading.

For curiosity, the current implementation of the BluetoothSerial.h uses a FreeRTOS queue under the hood to store the received bytes, which can be seen by analyzing the source code.

Thus, the available method calls the uxQueueMessagesWaiting function, which returns the number of messages available on the queue, which correspond to the number of bytes. If you want to learn more about this FreeRTOS function and how to use it, please check here.

Also, take in consideration that the size of FreeRTOS queues is specified at their creation and in the case of this library it is initialized with 256.

So, in order to get the bytes available, we will start by polling the BluetoothSerial object with the mentioned available method. Since we are going to read the bytes one by one and the ESP32 may have received more, we will poll it in a while loop.

while(SerialBT.available()){
// Handling code here
}

In order to get a byte, if it is available, we simply need to call the read method of the BluetoothSerial object. This will return the value of the byte as an integer.

Note: At the time of writing and by analyzing the source code, this method call is returning 0 when no data is available. Nonetheless, for the wired serial connection implementation, this function returns -1. I’ve opened this GitHub issue to track the correction.

In its implementation, the read method calls the FreeRTOS xQueueReceive function You can also check a tutorial for this functionality here.

SerialBT.read()

In order to write a byte to the wired serial connection, we simply need to call the write method, passing as input the byte to write. To avoid having to declare an intermediate variable, we can directly pass to the write method the return of the BluetoothSerial read method.

while(SerialBT.available()){
    Serial.write(SerialBT.read());
}

To finalize, we make a small delay between each iteration of the Arduino loop, so we are not constantly polling for incoming bytes. You can check the full source code below.

#include "BluetoothSerial.h"

BluetoothSerial SerialBT;

void setup() {
  Serial.begin(115200);

  if(!SerialBT.begin("ESP32")){
    Serial.println("An error occurred initializing Bluetooth");
  }
}

void loop() {

  while(SerialBT.available()){
    Serial.write(SerialBT.read());
  }

  delay(50);
}

 

Testing the code

To test the code, simply compile it and upload it to your ESP32 using the Arduino IDE. Then, when the procedure finishes, open the serial monitor using the COM port for the wired connection.

If you see no error message, then the Bluetooth was correctly initialized. If you start a Bluetooth scan with your computer, you should see the ESP32. Pair with it if you haven’t already done so.

Once the pairing finishes, you should have a new COM port available. On Windows 8, it is possible to check it on the Device Manager. If you need more help with the pairing procedure, please check this previous post.

Now, in order to establish the serial communication with the ESP32 over Bluetooth, we will need an additional serial monitor, so we can send the data to the device.

Although we can open a new instance of the Arduino IDE and open a new terminal for the Bluetooth emulated COM port, I’ve been experiencing some crashes with it, so I will be using Putty. Amongst many other features, Putty allows to establish serial connections.

You can give it a try with using two instances of the Arduino IDE since it may be related to my local environment, but if you run into crashes my recommendation is to change to Putty to send the data.

After downloading and opening putty, configure it like is shown in figure 1, on the left. As can be seen, we need to select “Serial” in the connection type radio. After that, put the COM port detected by your computer for the Serial over Bluetooth and select a speed of 115200. Note that other speeds will also work.

ESP32 Arduino Bluetooth Serial PuTTY.png

Figure 1 – Connection using Putty and the Arduino IDE serial monitor.

By default, Putty will not echo the characters inserted in the serial interface and will send them as soon as they are clicked. If you want a behavior more similar to the Arduino IDE where we can type some characters and only send them after clicking enter, then use the configurations of figure 2, before establishing the connection.

As shown, you need to go to the Terminal tab and select “Force On” in both “Local echo” and “Local line editing” options.

Putty activate serial terminal echo.png

Figure 2 – Changing Putty serial configurations to echo inputted chars and wait for enter to send them.

After that you can start sending data to the Bluetooth serial connection, which should be printed in the wired serial connection, as shown in figure 3.

ESP32 Arduino Bluetooth Serial receiving data

Figure 3 – Echoing the Serial over Bluetooth received data.

 

Related posts

 

21 thoughts on “ESP32 Arduino Serial over Bluetooth: Receiving data”

  1. Pingback: ESP32 Arduino Serial over Bluetooth: Get client address – techtutorialsx

  2. Pingback: ESP32 Arduino Serial over Bluetooth: Get client address – techtutorialsx

Leave a Reply

%d bloggers like this: