Modifikasi Config Dengan Komunuikasi Bluetooth
Modifikasi Config Dengan Komunuikasi Bluetooth
Bluetooth module pada ESP32, khususnya fitur Bluetooth Classic (Serial Port Profile / SPP), memungkinkan perangkat ini berkomunikasi dengan smartphone secara sederhana dan cepat melalui protokol mirip komunikasi serial. Dengan memanfaatkan antarmuka ini, pengguna dapat mengirim dan menerima data layaknya menggunakan UART, namun tanpa kabel. Hal ini menjadikan Bluetooth sebagai opsi yang ideal untuk melakukan konfigurasi dasar pada perangkat IoT tanpa perlu membuka antarmuka web, menggunakan kabel USB, maupun terhubung ke jaringan WiFi terlebih dahulu.
Dalam konteks konfigurasi perangkat, ESP32 dapat diprogram untuk menerima perintah tertentu dari aplikasi atau terminal Bluetooth di smartphone. Misalnya, pengguna dapat mengirimkan data berupa nama SSID baru dan password WiFi melalui komunikasi serial Bluetooth, kemudian ESP32 memproses data tersebut dan menyimpannya secara permanen ke file system seperti SPIFFS atau LittleFS. Dengan cara ini, konfigurasi perangkat menjadi jauh lebih fleksibel karena dapat diubah tanpa reflash firmware.
Selain mempermudah proses setup, pendekatan ini juga meningkatkan pengalaman pengguna karena tidak memerlukan jaringan WiFi sementara untuk provisioning, seperti pada metode Access Point konfigurasi. Bluetooth memungkinkan perangkat untuk tetap tertutup secara fisik dan aman, sementara perubahan konfigurasi dapat dilakukan hanya oleh perangkat yang memiliki akses langsung melalui koneksi Bluetooth. Kombinasi ESP32 dengan Bluetooth serial ini memberikan solusi ringan, praktis, dan efisien untuk memodifikasi parameter konfigurasi seperti SSID dan password secara real-time.
Script Program
BluetoothModule.h
#ifndef BLUETOOTH_MODULE_H
#define BLUETOOTH_MODULE_H
#include <Arduino.h>
#include <BluetoothSerial.h>
#include <StorageModule.h>
class BluetoothModule {
public:
BluetoothModule(const String& deviceName, StorageModule* storage);
void begin(); // mulai bluetooth
bool available(); // cek data masuk
String readString(); // baca string masuk
void send(const String& msg); // kirim data ke client
void saveConfig(const char* path, const char* key, const String& value);
void loop();
private:
BluetoothSerial BT;
StorageModule* storage;
String _name;
};
#endif
BluetoothModule.cpp
#include "BluetoothModule.h"
#include <ArduinoJson.h>
#include "WiFi.h"
BluetoothModule::BluetoothModule(const String& deviceName, StorageModule* fsModule) {
_name = deviceName;
storage = fsModule;
}
void BluetoothModule::begin() {
BT.begin(_name);
Serial.println("[BT] Bluetooth started: " + _name);
}
bool BluetoothModule::available() {
return BT.available();
}
String BluetoothModule::readString() {
return BT.readString();
}
void BluetoothModule::send(const String& msg) {
BT.print(msg);
}
void BluetoothModule::saveConfig(const char* path, const char* key, const String& value) {
ArduinoJson::JsonDocument doc;
storage->readJSON(path, doc);
doc[key] = value;
storage->writeJSON(path, doc);
}
void BluetoothModule::loop() {
if (BT.available()) {
String msg = BT.readStringUntil('\n');
msg.trim();
Serial.println("[BT RX] " + msg);
if (msg == "read-config") {
// baca JSON dari storage
ArduinoJson::JsonDocument doc;
if (storage->readJSON("/config.json", doc)) {
String out;
serializeJson(doc, out);
send(out + "\n");
Serial.println("[BT TX] config sent");
} else {
send("{\"error\":\"failed to read config\"}\n");
}
}
else if (msg.startsWith("add-config")) {
int jsonStart = msg.indexOf('{');
if (jsonStart == -1) {
send("{\"error\":\"invalid format\"}\n");
} else {
String jsonPart = msg.substring(jsonStart);
ArduinoJson::JsonDocument incoming;
DeserializationError err = deserializeJson(incoming, jsonPart);
if (err) {
send("{\"error\":\"invalid json\"}\n");
} else {
String key = incoming["key"] | "";
String value = incoming["value"] | "";
if (key.length() == 0) {
send("{\"error\":\"missing key\"}\n");
return;
}
ArduinoJson::JsonDocument doc;
storage->readJSON("/config.json", doc); // jika file belum ada, doc kosong
// update atau tambah key
doc[key] = value;
if (storage->writeJSON("/config.json", doc)) {
send("{\"success\":\"config updated\"}\n");
Serial.println("[BT TX] config updated: " + key);
} else {
send("{\"error\":\"failed to write config\"}\n");
}
}
}
}
else if (msg == "get-ip") {
IPAddress ip = WiFi.localIP();
String json = "{\"info\":\"" + ip.toString() + "\"}\n";
send("{\"info\":\""+ ip.toString() + "\"}\n");
Serial.println("[BT] IP sent: " + ip.toString());
}
else if (msg == "restart") {
send("{\"info\":\"restarting ESP32\"}\n");
Serial.println("[BT] Restarting ESP32");
delay(100); // beri waktu untuk kirim data sebelum restart
ESP.restart();
}
else {
send("Unknown command: " + msg + "\n");
}
}
}
main.cpp
#include <Arduino.h>
#include <BlinkModule.h>
#include <WiFiModule.h>
#include <ArduinoOTA.h>
#include <StorageModule.h>
#include <BluetoothModule.h>
BlinkModule blink(2, 500);
StorageModule storage(true);
WiFiModule wifi(&storage);
BluetoothModule bt("ESP32_Device", &storage);
void setup() {
Serial.begin(115200);
delay(200);
Serial.println("Project 01 - Blink Module");
blink.start();
storage.begin();
wifi.begin();
bt.begin();
ArduinoOTA.setPort(3232);
ArduinoOTA.setPassword("otapassword");
ArduinoOTA.begin();
}
void loop() {
ArduinoOTA.handle();
bt.loop();
}
Check it out!
Tags:
Ikuti terus tutorial saya di e-Project dan channel
saya di