The ESP32 comes with Wi-Fi, Bluetooth Low Energy and Bluetooth Classic. In this tutorial, you’ll learn how to use ESP32 Bluetooth Classic with Arduino IDE to exchange data between an ESP32 and an Android smartphone.
We’ll control an ESP32 output, and send sensor readings to an Android smartphone using Bluetooth Classic.
Note: this project is only compatible with Android smartphones.
Watch the Video Tutorial
You can watch the video tutorial or keep reading this page for the written instructions.
Bluetooth Classic with ESP32
At the moment, using Bluetooth Classic is much more simpler than Bluetooth Low Energy. If you’ve already programmed an Arduino with a Bluetooth module like the HC-06, this is very similar. It uses the standard serial protocol and functions.
In this tutorial, we’ll start by using an example that comes with the Arduino IDE. Then, we’ll build a simple project to exchange data between the ESP32 and your Android smartphone.
Parts Required
To follow this tutorial, you need the following parts:
- ESP32 DOIT DEVKIT V1 Board (read Best ESP32 development boards)
- Android Smartphone with Bluetooth
- 5mm LED
- 330 Ohm resistor
- DS18B20 temperature sensor
- 4.7k Ohm resistor
- Jumper wires
- Breadboard
You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!
Bluetooth Terminal Application
To proceed with this tutorial, you need a Bluetooth Terminal application installed in your smartphone.
We recommend using the Android app “Serial Bluetooth Terminal” available in the Play Store.
Serial to Serial Bluetooth
We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed before proceeding:
- Windows: instructions – ESP32 Board in Arduino IDE
- Mac and Linux: instructions – ESP32 Board in Arduino IDE
Open your Arduino IDE, and go to File > Examples > BluetoothSerial > SerialtoSerialBT.
The following code should load.
//This example code is in the Public Domain (or CC0 licensed, at your option.)
//By Evandro Copercini - 2018
//
//This example creates a bridge between Serial and Classical Bluetooth (SPP)
//and also demonstrate that SerialBT have the same functionalities of a normal Serial
#include "BluetoothSerial.h"
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
BluetoothSerial SerialBT;
void setup() {
Serial.begin(115200);
SerialBT.begin("ESP32test"); //Bluetooth device name
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
if (Serial.available()) {
SerialBT.write(Serial.read());
}
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
delay(20);
}
How the Code Works
This code establishes a two-way serial Bluetooth communication between two devices.
The code starts by including the BluetoothSerial library.
#include "BluetoothSerial.h"
The next three lines check if Bluetooth is properly enabled.
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
Then, create an instance of BluetoothSerial called SerialBT:
BluetoothSerial SerialBT;
setup()
In the setup() initialize a serial communication at a baud rate of 115200.
Serial.begin(115200);
Initialize the Bluetooth serial device and pass as an argument the Bluetooth Device name. By default it’s called ESP32test but you can rename it and give it a unique name.
SerialBT.begin("ESP32test"); //Bluetooth device name
loop()
In the loop(), send and receive data via Bluetooth Serial.
In the first if statement, we check if there are bytes being received in the serial port. If there are, send that information via Bluetooth to the connected device.
if (Serial.available()) {
SerialBT.write(Serial.read());
}
SerialBT.write() sends data using bluetooth serial.
Serial.read() returns the data received in the serial port.
The next if statement, checks if there are bytes available to read in the Bluetooth Serial port. If there are, we’ll write those bytes in the Serial Monitor.
if (SerialBT.available()) {
Serial.write(SerialBT.read());
}
It will be easier to understand exactly how this sketch works in the demonstration.
Testing the Code
Upload the previous code to the ESP32. Make sure you have the right board and COM port selected.
After uploading the code, open the Serial Monitor at a baud rate of 115200. Press the ESP32 Enable button.
After a few seconds, you should get a message saying: “The device started, now you can pair it with bluetooth!”.
Go to your smartphone and open the “Serial Bluetooth Terminal” app. Make sure you’ve enable your smartphone’s Bluetooth.
To connect to the ESP32 for the first time, you need to pair a new device.
Go to Devices.
Click the settings icon, and select Pair new device. You should get a list with the available Bluetooth devices, including the ESP32test. Pair with the ESP32test.
Then, go back to the Serial Bluetooth Terminal. Click the icon at the top to connect to the ESP32. You should get a “Connected” message.
After that, type something in the Serial Bluetooth Terminal app. For example, “Hello”.
You should instantly receive that message in the Arduino IDE Serial Monitor.
You can also exchange data between your Serial Monitor and your smartphone. Type something in the Serial Monitor top bar and press the “Send” button.
You should instantly receive that message in the Serial Bluetooth Terminal App.
Exchange Data using Bluetooth Serial
Now that you know how to exchange data using Bluetooth Serial, you can modify the previous sketch to make something useful. For example, control the ESP32 outputs when you receive a certain message, or send data to your smartphone like sensor readings.
The project we’ll build sends temperature readings every 10 seconds to your smartphone. We’ll be using the DS18B20 temperature sensor.
Through the Android app, we’ll send messages to control an ESP32 output. When the ESP32 receives the led_on message, we’ll turn the GPIO on, when it receives the led_off message, we’ll turn the GPIO off.
Schematic
Before proceeding with this project, assemble the circuit by following the next schematic diagram.
Connect an LED to GPIO25, and connect the DS18B20 data pin to GPIO32.
Recommended reading: ESP32 Pinout Reference: Which GPIO pins should you use?
Code
To work with the DS18B20 temperature sensor, you need to install the One Wire library by Paul Stoffregen and the Dallas Temperature library. Follow the next instructions to install these libraries, if you haven’t already.
One Wire library
- Click here to download the One Wire library. You should have a .zip folder in your Downloads
- Unzip the .zip folder and you should get OneWire-master folder
- Rename your folder from
OneWire-masterto OneWire - Move the OneWire folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Dallas Temperature library
- Click here to download the Dallas Temperature library. You should have a .zip folder in your Downloads
- Unzip the .zip folder and you should get Arduino-Temperature-Control-Library-master folder
- Rename your folder from
Arduino-Temperature-Control-Library-masterto DallasTemperature - Move the DallasTemperaturefolder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
After assembling the circuit and installing the necessary libraries, copy the following sketch to your Arduino IDE.
/*********
Rui Santos
Complete project details at https://randomnerdtutorials.com
*********/
// Load libraries
#include "BluetoothSerial.h"
#include <OneWire.h>
#include <DallasTemperature.h>
// Check if Bluetooth configs are enabled
#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif
// Bluetooth Serial object
BluetoothSerial SerialBT;
// GPIO where LED is connected to
const int ledPin = 25;
// GPIO where the DS18B20 is connected to
const int oneWireBus = 32;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
// Handle received and sent messages
String message = "";
char incomingChar;
String temperatureString = "";
// Timer: auxiliar variables
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // interval at which to publish sensor readings
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
// Bluetooth device name
SerialBT.begin("ESP32");
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
unsigned long currentMillis = millis();
// Send temperature readings
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
sensors.requestTemperatures();
temperatureString = String(sensors.getTempCByIndex(0)) + "C " + String(sensors.getTempFByIndex(0)) + "F";
SerialBT.println(temperatureString);
}
// Read received messages (LED control command)
if (SerialBT.available()){
char incomingChar = SerialBT.read();
if (incomingChar != '\n'){
message += String(incomingChar);
}
else{
message = "";
}
Serial.write(incomingChar);
}
// Check received message and control output accordingly
if (message =="led_on"){
digitalWrite(ledPin, HIGH);
}
else if (message =="led_off"){
digitalWrite(ledPin, LOW);
}
delay(20);
}
How the Code Works
Let’s take a quick look at the code and see how it works.
Start by including the necessary libraries. The BluetoothSerial library for Bluetooth, and the OneWire and DallasTemperature for the DS18B20 temperature sensor.
#include "BluetoothSerial.h"
#include <OneWire.h>
#include <DallasTemperature.h>
Create a BluetoothSerial instance called SerialBT.
BluetoothSerial SerialBT;
Create a variable called ledPin to hold the GPIO you want to control. In this case, GPIO25 has an LED connected.
const int ledPin = 25;
Define the DS18B20 sensor pin and create objects to make it work. The temperature sensor is connected to GPIO32.
// GPIO where the DS18B20 is connected to
const int oneWireBus = 32;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor
DallasTemperature sensors(&oneWire);
Create an empty string called message to store the received messages.
String message = "";
Create a char variable called incomingChar to save the characters coming via Bluetooth Serial.
char incomingChar;
The temperatureString variable holds the temperature readings to be sent via Bluetooth.
String temperatureString = "";
Create auxiliar timer variables to send readings every 10 seconds.
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // interval at which to publish sensor readings
setup()
In the setup(), set the ledPin as an output.
pinMode(ledPin, OUTPUT);
Initialize the ESP32 as a bluetooth device with the “ESP32” name.
SerialBT.begin("ESP32"); //Bluetooth device name
loop()
In the loop(), send the temperature readings, read the received messages and execute actions accordingly.
The following snippet of code, checks if 10 seconds have passed since the last reading. If it’s time to send a new reading, we get the latest temperature and save it in Celsius and Fahrenheit in the temperatureString variable.
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
sensors.requestTemperatures();
temperatureString = " " + String(sensors.getTempCByIndex(0)) + "C " + String(sensors.getTempFByIndex(0)) + "F";
Then, to send the temperatureString via bluetooth, use SerialBT.println().
SerialBT.println(temperatureString);
The next if statement reads incoming messages. When you receive messages via serial, you receive a character at a time. You know that the message ended, when you receive \n.
So, we check if there’s data available in the Bluetooth serial port.
if (SerialBT.available()) {
If there is, we’ll save the characters in the incomingChar variable.
char incomingChar = SerialBT.read();
If the incomingChar is different than \n, we’ll concatenate that char character to our message.
if (incomingChar!= '\n'){
message += String(incomingChar);
}
When we’re finished reading the characters, we clear the message variable. Otherwise all received messages would be appended to each other.
message = "";
After that, we have two if statements to check the content of the message. If the message is led_on, the LED turns on.
if (message =="led_on"){
digitalWrite(ledPin, HIGH);
}
If the message is led_off, the LED turns off.
else if (message =="led_off"){
digitalWrite(ledPin, LOW);
}
Testing the Project
Upload the previous sketch to your ESP32 board. Then, open the Serial Monitor, and press the ESP32 Enable button. When you receive the following message, you can go to your smartphone and connect with the ESP32.
Then, you can write the“led_on” and “led_off” messages to control the LED.
The application has several buttons in which you can save default messages. For example, you can associate M1 with the “led_on” message, and M2 with the “led_off” message.
Now, you are able to control the ESP32 GPIOs.
At the same time, you should be receiving the temperature readings every 10 seconds.
Wrapping Up
In summary, the ESP32 supports BLE and Bluetooth Classic. Using Bluetooth Classic is as simple as using serial communication and its functions.
If you want to learn how to use BLE with the ESP32, you can read our guide:
We hope you’ve found this tutorial useful. For more projects with the ESP32 you can check our project’s compilation: 20+ ESP32 Projects and Tutorials.
This tutorial is a preview of the “Learn ESP32 with Arduino IDE” course. If you like this project, make sure you take a look at the ESP32 course page where we cover this and a lot more topics with the ESP32.
Wonderful tutorial! Also, I recently bought your book about MicroPython programming that was great. Hopefully, we will be able to program with BLE in MicroPython soon.
Hi David.
Yes, we’ll create a tutorial with MicroPython and BLE as soon as it is fully implemented in the ESP32 micropython firmware.
Thanks 🙂
Hi! very interesting project, however I cannot find the ESP32test Bluetooth device. The sketch runs on my ESP32 without problems, but the Bluetooth scanner does not find the ESP. What could be the reason for that?
Hello Hans, which scanner are you using? What do you see in your Arduino IDE serial monitor after uploading the code?
Interesting work
This is very helpful when we want to implement IoT devices or Even WSN using ESP8266 or better ESP32 modules.
thanks for the tutorials and examples.
Thank you.
do you know how to upload program to esp32 using bluetooth for example bluino, and its very nice
Hi, Thanks for the tutorial. I want to add Bluetooth to an existing sketch that uses 56% of memory on my ESP32. When I add the Bluetooth code the size goes to 102% !
Is this normal?
Hi Dale.
I don’t know if that value is normal.
But sketches with bluetooth take a lot of space.
Regards,
Sara
Andy chance for a “stripped” version? Smaller size, less functions?
hi, I tried just like you said and it almost works. I can send commands from my phone and see them in the serial monitor but when I send a line in the serial monitor it doesn’t appear in my pone
also on my cell appears some lines with numbers occasionally (-127.00C -196.60F)
what can be the problem?
I’m sorry wrong sketch
works perfect!
I’m glad it’s solved now.
Regards,
Sara 😀
it’s a good tutorial,thanks!!
grettings from México!!
Sir? about the code, i want to do the temperature sensor only without LED.
if (message ==”led_on”){
digitalWrite(ledPin, HIGH);
}
else if (message ==”led_off”){
digitalWrite(ledPin, LOW);
}
if I erased this code for LED?, temperature sensor will still work? thank you sir
Hi Mark.
Yes, I haven’t tried it, but I think it should work.
Regards,
Sara
thank you guys for the help
Hey!
Thank you for this great tutorial. As a hobbyst it was very difficult for me to pair a simple arduino with HC bluetooth modules. After this article i quickly switched to the ESP32 and finally i could make my BLE security door lock with SPI lcd at my office.
But i have a question: How could i setup a pairing password for the ESP32? 🙂
Anyway, this tutorial is a lifesaver! 🙂
Hi – did you manage to get this working as I would like to know as well, how to set up pairing password ?
Instead of a smart phone I want to be able to use another esp32 with a touch screen so they converse with each other both ways.
Is that possible?
Whoaaw ! thanks for the tutorial, Ms. Sara Santos. I am very interested in that ESP32 program. but, i have something to ask. If you change how it works, how do I get the ESP32 to scan classic bluetooth? thank you
Hi,
Thanks a lot for the tutorial, it’s very easy to understand.
But I have a question.
If I send wroing messages, for example, ‘bread’ or ‘milk’, not ‘led_on’ nor ‘led_off’, I hope ESP32 can respond ‘Wrong code’, I don’t know how to edit the code. Can you help me?
Best regards
Hi.
You can add an else statement after this:
if (message ==”led_on”){
digitalWrite(ledPin, HIGH);
}
else if (message ==”led_off”){
digitalWrite(ledPin, LOW);
}
for example:
else{
SerialBT.print(“Invalid message”);
}
If the message is not “led_on” or “led_off”, it means it is an invalid message.
I hope this helps.
Regards,
Sara
Hi Sara, Rui, Your tutorials are great thanks. I just purchased ESP 32 book
How can I use esp32 to audio stream to another esp32 through BLE using my own audio signal?
Regards
Kazem
Hi.
Unfortunately, we don’t cover audio projects in our eBook or in our blog.
Regards,
Sara
In this line ” SerialBT.write(Serial.read()); ”
I want to put LoRa module data which is obtained using following command
” String LoRaData = LoRa.readString(); ”
In case i write it this it gives compilation error SerialBT.write(LoRaData);
Hi think you need to convert it to a char.
Try this:
SerialBT.write(LoRaData.c_str());
Regards,
Sara
hi, I want to use two or more ESP32 with Bluetooth Classic at the same time, this is possible?
I am looking for an example program that shows how to pair 2 devices. I can connect an ESP32 device to the “Serial Bluetpoth Terminal” application on my phone. But I can’t connect 2 ESP32s together!
I am trying to pair 2 devices. I can connect an ESP32 device to the “Serial Bluetooth Terminal” application on my phone. But I can’t connect ESP32 with HC-05 module. I follow the example codes but do not work. ESP32 always find a device to pair, although the remote device is turn off. is there any suggestion??
Hi,
Managed to get this project working. However, when I disconnect or when the bluetooth signal is too weak and disconnects, I cannot seem to reconnect the ESP32 again using bluetooth. Can you please advise what might be the problem?
I can do it with a HC06 no problem. Many thanks.
I would also like to know about this!
This is easy – BUT – how can we get the ESP32 to pair with the HC-06 module without using an Android phone to convince the HC-06 that it is paired?
Hi, how can I check AT Command of ESP32 ? I want to set fix address to another device
Hi.
You can check the ESP32 AT commands: https://docs.espressif.com/projects/esp-at/en/latest/AT_Command_Set/
Regards,
Sara
I notice you list an Android phone in the hardware requirements for this tutorial, and I have successfully managed to transfer text between my phone and an ESP32.
Is there an app for an iPhone that will talk serial Bluetooth classic in a similar fashion to Serial Bluetooth Terminal? I tried Blue Term, but no joy with that.
Hi.
There is this app: https://apps.apple.com/us/app/bluetooth-terminal/id1058693037
But I haven’t tried it.
Regards,
Sara
Thanks Sara for researching this – I’ll give it a try. However, I’m doubtful in view of the comment from paullbart in this ESP32 forum topic: https://esp32.com/viewtopic.php?t=9049
Then, tell me if you were able to make it work.
I’m also curious about this.
Regards,
Sara
The sketch work fine but i was surprised to see it uses 71% of recourses, i tried to use it but program went over the limit.
71% of flash memory wow i was using ESP32 WROOM.
something is rong somewhere…
Hey can i pair my hc05 and esp32 such that hc05 acts as a master and esp32 acts as a slave.If yes could u help me out with the code
Hi, i am able to connect mobile to BT module and able to send & receive data.if i want to send more than 250 bytes(i need buffer size 1K) unable to receive the data.can you please help me how to increase the buffer size in libraries for working.
Rajesh.M
Hi, thanks a lot.
It’s very wonderful and perfect tutorial.
Thank you.
Regards,
Sara
Now I want toI have 2 bluetooth devices .
Device 1: Arduino with HC05 bluetooth module along with a lm35 temp sensor.
Device 2: ESP32
Now I want to receive data in ESP 32 which is sended by the hc05 via Bluetooth
I need help that how to pair esp32 bt and hc05
Hi, in all the esp32 Bluetooth applications I’ve seen on the net, you always connect to the device from inside an app, and not the main Bluetooth functionality availible in the phone bluetooth settings. I tried to connect directly to the phone via the bluetooth settings section but even though the pairing was successfully established, connection was not. Would you happen to have any idea why this is? Is a third party app mandatory? I’ve been stuck for days now and would love some support. Thank you so much for your time.
How do I put a pin(password) on a bluetooth?
Hi, can this connect by itself to an HC-05 to remotely control a car? thanks
Hi.
Yes, I think it is possible.
Regards,
Sara
how to disable bluetooth on esp32
hello sara, i have tried your tutorial on esp32 and AMR_voice application, when i send voice message ‘ hello ‘ my serial monitor will show ‘*hello#’, can you give me reference to remove * and #
sorry if my english is bad and my question is stupid 🙁
regards,
Hi.
What project are you referring to?
To remove characters from a string your can use the remove() method: https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/remove/
Regards,
Sara
Thanks sarra,
i’m working on a project to display a message on led dot matrix max7219 with voice input via the amr_voice application which is sent via bluetooth to esp32
with the message sent in the form of a string based on voice recognition
hi, i cant get info how to save my esp32 finished sketch with the esp32 saved as a bluetooth human interface device?
Yes the tutorial works well Thanks. Nice way to control projects using a nearby phone.
I was hoping to connect a Bluetooth keyboard to an ESP32 using BT classic. I dont see any sample projects and it seems way more difficult than it should.
HI,
I got compiling error of:
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
how to fix this please?
Thanks
Summer
Hi.
What board are you using?
Do you have an ESP32 selected in Tools > Board?
Regards,
Sara
I have been looking all afternoon for library with the BluetoothSerial.h file. It won’t compile in Arduino or VSCode.
Do you know where I can find it?
Hi.
It should be automatically installed by default.
Make sure you have an ESP32 selected in Tools > Board.
Regards,
Sara
Hi, great tutorial – thanks.
Do you know of a good way to create an app on a smart-phone with which I can exchangs data with an esp32 ?
Charles
Hi, I enjoyed this tutorial and wondered if it is possible to see continuous Arduino analog data from, for example, a potentiometer on Android using bluetooth with ESP32. In other words, can the Android be used as an Arduino serial plotter?
Can i use the classic Bluetooth and ESP-NOW at the same time?
excelent !.
Sorry I d’nt speak English
do you have a program to connect two esp32 bluetooth . Master and slave and send a single character like ” A “
I enjoyed your tutorial on ESP32 with BT. However, I would like to see a tutorial extending these concepts to continuous analog recording with the ESP32 and BT. My experience is that with continuous analog recording, the BT is overwhelmed, resulting in hanging of the recording every few seconds. I don’t know if that reflects a problem with my programming or a limitation of the hardware or software.
There is indeed a hardware limitation of how frequently you can send data using bluetooth classic. I’ve found that the maximum frequency is about once every 1.25-1.5 seconds without overwhelming the bluetooth. I don’t think anything can be done about that-in the arduino/esp32 realm at least. What you can do is read 5 or 10 values, and send them all together in one packet. Then you’ll have to send data 5 or 10 times less frequently, giving the bluetooth plenty of time to do its job.
Thanks so much for your reply. It makes me feel a bit better about my failure to obtain a continuous recording–without hanging–via bluetooth using the ESP32 and the AD8232 breakout board. It seems unlikely that any other Arduino board is free of this problem.
How can you enable a pairing pin?
I enjoyed your tutorial on ESP32 with BT. BUT Is there a way to use bluetooth and wifi at the same time on the ESP32
Hello, Im able to use the bluetooth serial app to turn the on board led on and off. Unfortunantly I cant read any data on my PCs serial monitor. I have tried several bluetooth serial examples. They all load and connect to my android app but the serial monitor does not work. When I first blug it in the serial monitor diplays some information EXCEPT for the Bluetooth ready to pair message that seems to be in most of the examples. I have a esp 32 dev kitv1. Any help would be appreciated. Lastly, can you recommend a good esp32 board?
Thanks for all the great lessons
Hello Sara :
I want to ask how load a gif file via Bluetooth and displayed on GC9A01 display ?
Thank you
Hi.
Unfortunately, we don’t have any tutorials about that subject.
Regards,
Sara
I uploaded the code to the ESP32 and it all was successful. I then tried to connect using the recommended Serial Bluetooth Terminal but I don’t see the ESP32test. It doesn’t show in the list. I am using Pixel 8 pro with Android 14. Any idea why it doesn’t show up?