ESP32 Challenge #7: Bluetooth Communication

Gisela Ivenita
11 min readMar 21, 2021

--

Halo! Selamat datang di challenge ke-7. Pada challenge kali ini kita akan bermain dengan bluetooth yang sudah embedded di dalam ESP32.

ESP32 memiliki Wireless Communication Protocol, antara lain:

  1. Short Range Communication Protocol
  • Bluetooth technology (Classic dan Low Energy)

2. Mid Range Communication Protocol

  • Wi-Fi technology
  • ZigBee technology

3. Long Range Communication Protocol

  • LoRaWAN protocol
  • LTE-M
  • Narrowband Internet of Things (NB-IoT) Protocol
  • Fifth cellular generation network (5G).

Nah, pada challenge kali ini kita akan bermain dengan bluetooth!

Apa sih bedanya Bluetooth Classic dan Bluetooth Low Energy (BLE)?

Bluetooth Classic dapat menangani banyak data, tapi masa pakai baterainya cukup cepat dan lebih mahal. Sebaliknya, BLE digunakan untuk aplikasi
yang tidak perlu menukar data dalam jumlah besar sehingga tidak mengonsumsi daya baterai sebesar Bluetooth Classic dan biayanya lebih murah. Oleh karena itu, pemilihan bluetooth yang dipakai tergantung dengan kebutuhan kalian, yaa!

DAFTAR KOMPONEN DAN PERANGKAT

Komponen dan perangkat yang harus disiapkan sebagai berikut:

  1. ESP32 Development Board (disini aku menggunakan ESP32 DOIT DEVKIT V1)
  2. Breadboard
  3. Sensor BMP 280
  4. LED
  5. Kabel male to male (bisa disesuaikan)
  6. Micro USB Cable
  7. Laptop/komputer yang terdapat aplikasi Arduino IDE (sudah terinstall package board ESP32)
  8. Android smartphone

Nah, langsung aja kita eksperimen, yuk!

Bluetooth Classic

Catatan: Unfortunately, eksperimen ini hanya bisa digunakan pada smartphone Android.

Sebelumnya, silahkan download aplikasi Serial Bluetooth Terminal pada Play Store.

Gambar 1. Serial Bluetooth Terminal

EKSPERIMEN 1: LED ON AND OFF

Pertama-tama, kita akan menyalakan dan mematikan LED melalui aplikasi Serial Bluetooth Terminal.

DIAGRAM SKEMA

Silahkan rangkai komponen dan perangkat sebelumnya seperti pada skema berikut:

Gambar 2. Rangkaian dengan LED

Pada skema tersebut, kutub positif (anoda) LED dihubungkan dengan GPIO 2 (D2) ESP32. Sebenarnya kalian tidak harus menggunakan GPIO 2 tetapi bisa menggunakan pin yang lain asalkan memiliki fungsi yang sama sebagai output, silahkan lihat penjelasan lengkapnya disini. Lalu, kutub negatif (katoda) LED terhubung dengan ground breadboard. GND ESP32 dihubungkan dengan kutub negatif yang berada pada pinggir breaboard, dan 3V3 ESP32 dihubungkan dengan kutub positif yang berada pada pinggir breadboard.

KODE PROGRAM

Kode program yang digunakan sebagai berikut.

/*********
Rui Santos
Complete project details at http://randomnerdtutorials.com
*********/
// Load libraries
#include "BluetoothSerial.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.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 = 2;
Adafruit_BMP280 bmp; // I2C// Handle received and sent messages
String message = "";
char incomingChar;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
// Bluetooth device name
SerialBT.begin("ESP32test");
Serial.println("The device started, now you can pair it with bluetooth!");
}
void loop() {
// 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);
}

Keterangan program:

#include "BluetoothSerial.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

Seperti biasa, pada awal program kita harus meng-include seluruh library yang digunakan.

Library baru yang kita gunakan disini adalah BluetoothSerial karena pada program kali ini kita menggunakan bluetooth.

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

Kode program di atas mengecek apakah Bluetooth telah aktif.

// Bluetooth Serial object
BluetoothSerial SerialBT;

Dilakukan instansiasi BluetoothSerial dengan nama SerialBT.

// GPIO where LED is connected to
const int ledPin = 2;

Set variabel ledPin dengan 2 yang menandakan penggunaan GPIO 2.

Adafruit_BMP280 bmp; // I2C

Dilakukan instansiasi Adafruit_BMP280 dengan nama bmp.

// Handle received and sent messages
String message = "";
char incomingChar;

Inisialisasi message dengan tipe string dan incomingChar dengan tipe char.

void setup() {
pinMode(ledPin, OUTPUT);

Pada bagian setup, terdapat instruksi pinMode yang menentukan ledPin sebagai output.

Serial.begin(115200);

Lalu, Serial.begin berfungsi untuk menentukan kecepatan penyampaian data melalui port serial dalam satuan baud, di sini kita buat 115200 baud.

SerialBT.begin("ESP32test");

Dilakukan inisialisasi perangkat Bluetooth serial dan diberikan nama perangkat Bluetooth sebagai argumen.

Serial.println("The device started, now you can pair it with bluetooth!");

Menampilkan ke layar serial monitor jika device sudah siap.

void loop() {
// Read received messages (LED control command)
if (SerialBT.available()){
char incomingChar = SerialBT.read();
if (incomingChar != '\n'){
message += String(incomingChar);
}
else{
message = "";
}
Serial.write(incomingChar);
}

Jika bluetooth telah tersedia (SerialBT.avaliable()) , akan dibaca message yang dikirim dan menuliskannya pada serial monitor.

// Check received message and control output accordingly
if (message =="led_on"){
digitalWrite(ledPin, HIGH);
}
else if (message =="led_off"){
digitalWrite(ledPin, LOW);
}
delay(20);

Apabila message yang dituliskan adalah led_on, maka ledPin akan menyala. Sebaliknya apabila message yang dituliskan adalah led_off, maka ledPin akan mati. Lalu diberikan delay 20 ms.

ESKPERIMEN DAN DEMO

Hubungkan dengan bluetooth ESP32

Selanjutnya, buka aplikasi Serial Bluetooth Terminal.

Hubungkan dengan bluetooth ESP32 dengan cara klik Devices > tombol Settings > hubungkan dengan ESP32test > klik ESP32test yang sudah tersedia pada aplikasi Serial Bluetooth Terminal.

Gambar 3. Settings pada Serial Bluetooth Terminal

Kalian juga bisa mengganti bagian macroM1, M2, M3, dst nya yang berada pada terminal sebagai berikut sehingga tidak perlu repot mengetik perintahnya nanti hehe.

Gambar 4. Settings Macro

Setelah semua sudah siap, silahkan verify dan compile pada aplikasi Arduino IDE.

Kemudian, silahkan tekan tombol EN pada ESP32 jika masih belum connected.

Gambar 5. Menyalakan dan mematikan LED

Setelah connected, kalian bisa mencoba menyalakan dan mematikan LED dengan macro yang sudah dibuat seperti pada Gambar 5.

DOKUMENTASI

Gambar 6. Hasil Eksperimen

EKSPERIMEN 2: LED ON AND OFF + BMP280 SENSOR

Selanjutnya, kita juga akan menggunakan sensor BMP 280 di mana hasil sensor akan ditampilkan ke Serial Bluetooth Terminal.

DIAGRAM SKEMA

Gambar 7. Rangkaian LED dan sensor BMP 280

Sama seperti pada rangkaian sebelumnya, disini kita menambahkan sensor BMP 280. Cara menghubungkannya pun sama saat kita bereksperimen menggunakan sensor BMP 280. GPIO 22 dihubungkan dengan SCL sensor BMP 280, GPIO 21 dihubungkan dengan SDA sensor BMP 280, GND ESP32 dihubungkan GND sensor, dan 3V3 ESP32 dihubungkan dengan VCC sensor.

KODE PROGRAM

Kode program yang digunakan sebagai berikut.

/*********
Rui Santos
Complete project details at http://randomnerdtutorials.com
*********/
// Load libraries
#include "BluetoothSerial.h"
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>
#define SEALEVELPRESSURE_HPA (1013.25)// 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 = 2;
Adafruit_BMP280 bmp; // I2C// Handle received and sent messages
String message = "";
char incomingChar;
// 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);
if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}
// Bluetooth device name
SerialBT.begin("ESP32test");
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;
SerialBT.print("Temperature = ");
SerialBT.print(bmp.readTemperature());
SerialBT.println(" *C");

// Convert temperature to Fahrenheit
SerialBT.print("Temperature (Fahrenheit) = ");
SerialBT.print(1.8 * bmp.readTemperature() + 32);
SerialBT.println(" *F");

SerialBT.print("Pressure = ");
SerialBT.print(bmp.readPressure() / 100.0F);
SerialBT.println(" hPa");
SerialBT.print("Approx. Altitude = ");
SerialBT.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
SerialBT.println(" m");
}
// 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);
}

Keterangan program:

Kode program sebenarnya tidak jauh berbeda dengan kode program sebelumnya, hanya saja disini kita menambahkan untuk sensor BMP 280.

#define SEALEVELPRESSURE_HPA (1013.25)

Melakukan define SEALEVELPRESSURE_HPA dengan nilai 1013.25 sebagai average sea level pressure.

const long interval = 10000;

Kita juga mendefinisikan interval sebesar 10000 untuk mempublish pembacaan sensor.

if (!bmp.begin(0x76)) {
Serial.println("Could not find a valid BMP280 sensor, check wiring!");
while (1);
}

Pada bagian setup juga ditambahkan perintah untuk mengecek jika tidak dapat ditemukan sensor BMP 280.

void loop() {
unsigned long currentMillis = millis();
// Send temperature readings
if (currentMillis - previousMillis >= interval){
previousMillis = currentMillis;
SerialBT.print("Temperature = ");
SerialBT.print(bmp.readTemperature());
SerialBT.println(" *C");

// Convert temperature to Fahrenheit
SerialBT.print("Temperature (Fahrenheit) = ");
SerialBT.print(1.8 * bmp.readTemperature() + 32);
SerialBT.println(" *F");

SerialBT.print("Pressure = ");
SerialBT.print(bmp.readPressure() / 100.0F);
SerialBT.println(" hPa");
SerialBT.print("Approx. Altitude = ");
SerialBT.print(bmp.readAltitude(SEALEVELPRESSURE_HPA));
SerialBT.println(" m");
}

Pada bagian loop ditambahkan perintah untuk menampilkan temperatur (dalam Celcius dan Farenheit), tekanan, dan altitude.

Perbedaan jika kita menggunakan bluetooth adalah hasil akan ditampilkan pada aplikasi sehingga menggunakan perintal SerialBT.print.

EKSPERIMEN DAN DEMO

Proses menghubungkannya sama seperti pada eksperimen sebelumnya.

Gambar 8. Hasil pada terminal

Pada terminal akan menampilkan pembacaan dari sensor dan juga kita bisa menyalakan dan mematikan LED.

DOKUMENTASI

Gambar 9. Hasil eksperimen kedua

HASIL EKSPERIMEN DAN ANALISIS

Eksperimen dapat berjalan dengan baik sesuai dengan kode program, meskipun cukup lama untuk beradaptasi dengan penggunaan aplikasi Serial Bluetooth Terminal. Awalnya, aku tidak tahu fungsi dari macro yang tersedia sehingga aku mengetik message secara manual jadi cukup agak ribet ya hehe. Tetapi setelah aku mencoba mengotak-atik, aku baru sadar bahwa macro tersebut bisa digunakan untuk mempermudah dalam mengirimkan perintah.

Dengan menggunakan Bluetooth Classic yang sudah embedded pada ESP32, kita dapat mengatur nyala/matinya LED dan menerima pembacaan sensor pada smartphone kita. Terdapat fungsi baru disini, yaitu:

  • Serial.write(): berfungsi untuk menuliskan binary data ke serial port.
  • Serial.available(): berfungsi untuk mendapatkan jumlah byte (karakter) yang tersedia untuk dibaca dari serial port.
  • if(Serial): berfungsi untuk melihat apakah serial port sudah siap.
  • Serial.print(): berfungsi untuk mencetak data ke port serial dalam bentuk teks ASCII yang dapat dibaca oleh manusia.
  • Serial.read(): berfungsi untuk membaca data serial yang masuk.

Bluetooth Low Energy (BLE)

Selanjutnya, dengan Bluetooth Low Energy kita akan mencoba BLE Server dan BLE Scanner.

DAFTAR KOMPONEN DAN PERANGKAT

  1. ESP32 Development Board
  2. Breadboard
  3. Micro USB Cable
  4. Laptop/komputer yang terdapat Aplikasi Arduino IDE (sudah terinstall package board ESP32)
  5. Smartphone

Nah, pada smartphone kalian silahkan install aplikasi nRF Connect for Mobile.

Gambar 10. Aplikasi nRF Connect for Mobile

DIAGRAM SKEMA

Gambar 11. Skema

Kita hanya memerlukan sebuah ESP32, kabel Micro USB, dan sebuah aplikasi Arduino IDE saja pada eksperimen ini.

ESP32 BLE Server

Pada eksperimen ini, ESP32 akan bertindak sebagai BLE server. Penasaran, kan, gimana caranya?

KODE PROGRAM

/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleServer.cpp
Ported to Arduino ESP32 by Evandro Copercini
updates by chegewara
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
// See the following for generating UUIDs:
// https://www.uuidgenerator.net/
#define SERVICE_UUID “4fafc201–1fb5–459e-8fcc-c5c9c331914b”
#define CHARACTERISTIC_UUID “beb5483e-36e1–4688-b7f5-ea07361b26a8”
void setup() {
Serial.begin(115200);
Serial.println(“Starting BLE work!”);
BLEDevice::init(“ESP32”);
BLEServer *pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setValue(“Hello everyone!”);
pService->start();
// BLEAdvertising *pAdvertising = pServer->getAdvertising(); // this still is working for backward compatibility
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06); // functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println(“Characteristic defined! Now you can read it in your phone!”);
}
void loop() {
// put your main code here, to run repeatedly:
delay(2000);
}

Kode program ini bisa kalian buka melalui File > Examples > ESP32 BLE Arduino > BLE_server. Nah, silahkan ubah nama server dan karakteristik sesuai keinginan kalian. Disini aku mengubah nama server menjadi “ESP32” dan karakteristiknya “Hello everyone!”.

Keterangan program:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>

Seperti biasa pada awal program kita perlu meng-inclue library yang digunakan.

#define SERVICE_UUID “4fafc201–1fb5–459e-8fcc-c5c9c331914b”
#define CHARACTERISTIC_UUID “beb5483e-36e1–4688-b7f5-ea07361b26a8”

Lalu, didefinisikan UUID untuk Service dan Characteristic.

void setup() {
Serial.begin(115200);
Serial.println(“Starting BLE work!”);

Pada bagian setup, set kecepatan serial monitor sebesar 115200 baud, dan dicetak ke layar serial monitor bahwa BLE mulai bekerja.

BLEDevice::init(“ESP32”);

Lalu membuat BLE device dengan nama ESP32.

BLEServer *pServer = BLEDevice::createServer();

Membuat BLE device sebagai server.

BLEService *pService = pServer->createService(SERVICE_UUID);

Selanjutnya, dibuat service untuk BLE server dengan UUID yang telah didefinisikan pada awal program.

BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);

Kemudian, kita menetapkan karakteristik untuk service tersebut dengan menggunakan UUID yang didefinisikan sebelumnya, properti karakteristik sebagai argumen, yaitu READ dan WRITE.

pCharacteristic->setValue(“Hello everyone!”);

Setelah membuat karakteristik, kita bisa set nilainya dengan menggunakan setValue() dan disini kita set dengan text “Hello everyone!”.

pService->start();BLEDevice::startAdvertising();

Selanjutnya, service dan advertising dapat dimulai sehingga perangkat BLE lain dapat melakukan scan dan menemukan device BLE ini.

EKSPERIMEN DAN DEMO

Silahkan klik verify dan compile pada aplikasi Arduino IDE. Setelah itu, buka aplikasi nRF Connect for Mobile.

Kalian akan menemukan devices dengan nama ESP32, dan apabila dibuka akan terdapat pesna yang ditulis pada karakteristik.

Gambar 12. ESP32 BLE Server

ESP32 BLE Scanner

Pada aplikasi Arduino IDE, silahkan pilih File > Examples > ESP32 BLE Arduino > BLE_scan.

KODE PROGRAM

Kode program yang muncul seperti di bawah ini.

/*
Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp
Ported to Arduino ESP32 by Evandro Copercini
*/
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
int scanTime = 5; //In seconds
BLEScan* pBLEScan;
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
Serial.printf(“Advertised Device: %s \n”, advertisedDevice.toString().c_str());
}
};
void setup() {
Serial.begin(115200);
Serial.println(“Scanning…”);
BLEDevice::init(“”);
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print(“Devices found: “);
Serial.println(foundDevices.getCount());
Serial.println(“Scan done!”);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}

Kode diatas berfungsi untuk membuat ESP32 sebagai suatu BLE yang melakukan scan terhadap device terdekat.

Keterangan program:

#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>

Seperti biasanya, pada awal program kita meng-include library yang dibutuhkan.

int scanTime = 5; //In seconds

Diinisialisasi waktu untuk melakukan scan dengan nama scanTime dan tipe int.

void setup() {
Serial.begin(115200);
Serial.println(“Scanning…”);

Pada bagian setup, kita set kecepatan sebesar 115200 baud.

BLEDevice::init(“”);
pBLEScan = BLEDevice::getScan(); //create new scan

Selanjutnya, membuat BLE Device dan BLE Device dijadikan sebuah scanner.

void loop() {
// put your main code here, to run repeatedly:
BLEScanResults foundDevices = pBLEScan->start(scanTime, false);
Serial.print(“Devices found: “);
Serial.println(foundDevices.getCount());
Serial.println(“Scan done!”);
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
delay(2000);
}

Pada bagian loop, akan ditampilkan jumlah device yang ditemukan.

EKSPERIMEN DAN DEMO

Nah, setelah itu klik verify dan compile pada Arduino IDE.

Selanjutnya, pilih Tools > Serial Monitor pada Arduino IDE.

Gambar 13. BLE Scanner

Hasil eksperimen ditemukan 1 buah device seperti pada gambar.

HASIL EKSPERIMEN DAN ANALISIS

Eksperimen dapat berjalan dengan baik. Pada eksperimen dengan Bluetooth Low Energy (BLE) ESP32, BLE ESP32 dapat menjadi server dan juga dapat menjadi scanner untuk mengetahui jumlah device yang ditemukan.

Challenge kali ini cukup menantang dan menyenangkan, bukan? Sampai jumpa di challenge selanjutnya yang pastinya gak kalah keren dari challenge ini!

--

--

No responses yet