Ví dụ Bluetooth Slider cung cấp hai điều khiển slider độc lập có thể truy cập thông qua ứng dụng DIYables Bluetooth STEM. Được thiết kế cho bo mạch ESP32 với hỗ trợ cả BLE (Bluetooth Low Energy) và Classic Bluetooth. Mỗi slider cung cấp giá trị từ 0-100, hoàn hảo cho điều khiển PWM, điều chỉnh độ sáng, điều khiển tốc độ motor và bất kỳ ứng dụng nào yêu cầu giá trị điều khiển kiểu analog.
Ví dụ này hỗ trợ hai chế độ Bluetooth:
| 1 | × | mô-đun phát triển ESP-WROOM-32 | | |
| 1 | × | Alternatively, ESP32 Uno-form board | | |
| 1 | × | Alternatively, ESP32 S3 Uno-form board | | |
| 1 | × | USB Cable Type-A to Type-C (for USB-A PC) | | |
| 1 | × | USB Cable Type-C to Type-C (for USB-C PC) | | |
| 1 | × | breadboard | | |
| 1 | × | dây jumper | | |
| 1 | × | (Khuyến nghị) Screw Terminal Expansion Board for ESP32 | | |
| 1 | × | (Khuyến nghị) Breakout Expansion Board for ESP32 | | |
| 1 | × | (Khuyến nghị) Power Splitter for ESP32 | | |
Or you can buy the following kits:
| 1 | × | DIYables ESP32 Starter Kit (ESP32 included) | | |
| 1 | × | DIYables Sensor Kit (30 sensors/displays) | | |
| 1 | × | DIYables Sensor Kit (18 sensors/displays) | | |
Làm theo các hướng dẫn từng bước:
Kết nối bo mạch ESP32 với máy tính của bạn bằng cáp USB.
Khởi chạy Arduino IDE trên máy tính của bạn.
Chọn bo mạch ESP32 và cổng COM thích hợp.
Điều hướng tới biểu tượng Libraries trên thanh bên trái của Arduino IDE.
Tìm kiếm "DIYables Bluetooth", sau đó tìm thư viện DIYables Bluetooth của DIYables
Nhấp nút Install để cài đặt thư viện.
Chọn một trong hai chế độ Bluetooth dưới đây tùy theo nhu cầu của bạn:
Lưu ý: Classic Bluetooth KHÔNG được hỗ trợ trên iOS. Nếu bạn cần hỗ trợ iOS, hãy sử dụng code BLE dưới đây.
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothSlider.h>
#include <platforms/DIYables_Esp32Bluetooth.h>
DIYables_Esp32Bluetooth bluetooth("ESP32_Slider");
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothSlider bluetoothSlider(0, 100, 1);
int currentSlider1 = 0;
int currentSlider2 = 0;
const int PWM_PIN_1 = 16;
const int PWM_PIN_2 = 17;
const int PWM_CHANNEL_1 = 0;
const int PWM_CHANNEL_2 = 1;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 Slider Example");
ledcSetup(PWM_CHANNEL_1, 5000, 8);
ledcSetup(PWM_CHANNEL_2, 5000, 8);
ledcAttachPin(PWM_PIN_1, PWM_CHANNEL_1);
ledcAttachPin(PWM_PIN_2, PWM_CHANNEL_2);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothSlider);
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothSlider.send(currentSlider1, currentSlider2);
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.print("Slider 1: ");
Serial.print(slider1);
Serial.print(", Slider 2: ");
Serial.println(slider2);
int pwm1 = map(slider1, 0, 100, 0, 255);
int pwm2 = map(slider2, 0, 100, 0, 255);
ledcWrite(PWM_CHANNEL_1, pwm1);
ledcWrite(PWM_CHANNEL_2, pwm2);
});
bluetoothSlider.onGetConfig([]() {
bluetoothSlider.send(currentSlider1, currentSlider2);
Serial.print("App requested values - Sent: Slider1=");
Serial.print(currentSlider1);
Serial.print(", Slider2=");
Serial.println(currentSlider2);
});
Serial.println("Waiting for Bluetooth connection...");
}
void loop() {
bluetoothServer.loop();
delay(10);
}
DIYables Bluetooth - ESP32 Slider Example
Waiting for Bluetooth connection...
#include <DIYables_BluetoothServer.h>
#include <DIYables_BluetoothSlider.h>
#include <platforms/DIYables_Esp32BLE.h>
const char* DEVICE_NAME = "ESP32BLE_Slider";
const char* SERVICE_UUID = "19B10000-E8F2-537E-4F6C-D104768A1214";
const char* TX_UUID = "19B10001-E8F2-537E-4F6C-D104768A1214";
const char* RX_UUID = "19B10002-E8F2-537E-4F6C-D104768A1214";
DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID);
DIYables_BluetoothServer bluetoothServer(bluetooth);
DIYables_BluetoothSlider bluetoothSlider(0, 100, 1);
int currentSlider1 = 0;
int currentSlider2 = 0;
const int PWM_PIN_1 = 16;
const int PWM_PIN_2 = 17;
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("DIYables Bluetooth - ESP32 BLE Slider Example");
pinMode(PWM_PIN_1, OUTPUT);
pinMode(PWM_PIN_2, OUTPUT);
bluetoothServer.begin();
bluetoothServer.addApp(&bluetoothSlider);
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothSlider.send(currentSlider1, currentSlider2);
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.print("Slider 1: ");
Serial.print(slider1);
Serial.print(", Slider 2: ");
Serial.println(slider2);
int pwm1 = map(slider1, 0, 100, 0, 255);
int pwm2 = map(slider2, 0, 100, 0, 255);
analogWrite(PWM_PIN_1, pwm1);
analogWrite(PWM_PIN_2, pwm2);
});
bluetoothSlider.onGetConfig([]() {
bluetoothSlider.send(currentSlider1, currentSlider2);
Serial.print("App requested values - Sent: Slider1=");
Serial.print(currentSlider1);
Serial.print(", Slider2=");
Serial.println(currentSlider2);
});
Serial.println("Waiting for Bluetooth connection...");
}
void loop() {
bluetoothServer.loop();
delay(10);
}
DIYables Bluetooth - ESP32 BLE Slider Example
Waiting for Bluetooth connection...
Cài đặt ứng dụng DIYables Bluetooth trên smartphone của bạn:
Android |
iOS
Nếu bạn đang sử dụng ESP32 Classic Bluetooth code, bạn cần ghép nối ESP32 với điện thoại Android của bạn trước khi mở ứng dụng:
Đi tới Settings > Bluetooth trên điện thoại của bạn
Đảm bảo Bluetooth đã được bật
Điện thoại của bạn sẽ quét các thiết bị có sẵn
Tìm và nhấn "ESP32_Slider" trong danh sách các thiết bị có sẵn
Xác nhận yêu cầu ghép nối (không cần mã PIN)
Đợi cho đến khi nó hiển thị "Paired" dưới tên thiết bị
Nếu bạn đang sử dụng ESP32 BLE code, không cần ghép nối. Chỉ cần tiến tới bước tiếp theo.
Mở ứng dụng DIYables Bluetooth
Khi mở ứng dụng lần đầu tiên, nó sẽ yêu cầu quyền. Vui lòng cấp các quyền sau:
Quyền Nearby Devices (Android 12+) / quyền Bluetooth (iOS) - cần thiết để quét và kết nối với các thiết bị Bluetooth
Quyền Location (chỉ Android 11 trở xuống) - yêu cầu bởi các phiên bản Android cũ để quét thiết bị BLE
Đảm bảo Bluetooth đã được bật trên điện thoại của bạn
Trên màn hình chính, nhấn nút Connect. Ứng dụng sẽ quét cả thiết bị BLE và Classic Bluetooth.

Tìm và nhấn thiết bị của bạn trong kết quả quét để kết nối:
Sau khi kết nối, ứng dụng tự động quay về màn hình chính. Chọn ứng dụng Slider từ menu ứng dụng.
Lưu ý: Bạn có thể nhấn biểu tượng cài đặt trên màn hình chính để ẩn/hiện các ứng dụng trên màn hình chính. Để biết thêm chi tiết, xem Hướng dẫn sử dụng DIYables Bluetooth App.
Bây giờ hãy quay lại xem Serial Monitor trên Arduino IDE. Bạn sẽ thấy:
Bluetooth connected!
Slider 1: 50, Slider 2: 30
Slider 1: 75, Slider 2: 30
Slider 1: 75, Slider 2: 60
Slider 1: 100, Slider 2: 85
Cấu hình vị trí ban đầu của slider:
int currentSlider1 = 25;
int currentSlider2 = 50;
DIYables_BluetoothSlider bluetoothSlider(0, 255, 5);
bluetoothSlider.setRange(0, 255);
bluetoothSlider.setStep(5);
int currentMin = bluetoothSlider.getMin();
int currentMax = bluetoothSlider.getMax();
int currentStep = bluetoothSlider.getStep();
Khi ứng dụng kết nối và mở màn hình Slider, nó yêu cầu cấu hình slider từ ESP32. Bạn có thể sử dụng callback onGetConfig() để gửi giá trị slider hiện tại tới ứng dụng vào thời điểm đó:
bluetoothSlider.onGetConfig([]() {
bluetoothSlider.send(currentSlider1, currentSlider2);
Serial.println("App requested config - sent current values");
});
Bạn có thể gửi giá trị slider từ ESP32 tới ứng dụng (ví dụ, để cập nhật vị trí slider của ứng dụng):
bluetoothSlider.send(currentSlider1, currentSlider2);
bluetoothSlider.send(50);
Bạn có thể phát hiện khi ứng dụng kết nối hoặc ngắt kết nối khỏi ESP32:
bluetoothServer.setOnConnected([]() {
Serial.println("Bluetooth connected!");
bluetoothSlider.send(currentSlider1, currentSlider2);
});
bluetoothServer.setOnDisconnected([]() {
Serial.println("Bluetooth disconnected!");
});
if (bluetoothServer.isConnected()) {
}
Giao diện slider trong ứng dụng DIYables Bluetooth cung cấp:
Slider 1: Slider điều khiển đầu tiên với hiển thị giá trị
Slider 2: Slider điều khiển thứ hai với hiển thị giá trị
Hiển thị giá trị: Giá trị số thời gian thực cho cả hai slider
Mỗi slider cung cấp:
Phạm vi mặc định: 0 đến 100
Có thể cấu hình: Phạm vi và bước có thể được tùy chỉnh trong code
Ánh xạ PWM: Dễ dàng ánh xạ tới 0-255 cho analogWrite()
void setup() {
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
Serial.println("Slider 1: " + String(slider1) + ", Slider 2: " + String(slider2));
});
}
const int PWM_PIN_1 = 16;
const int PWM_PIN_2 = 17;
void setup() {
pinMode(PWM_PIN_1, OUTPUT);
pinMode(PWM_PIN_2, OUTPUT);
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
int pwm1 = map(slider1, 0, 100, 0, 255);
int pwm2 = map(slider2, 0, 100, 0, 255);
analogWrite(PWM_PIN_1, pwm1);
analogWrite(PWM_PIN_2, pwm2);
Serial.println("LED1 Brightness: " + String(pwm1) +
", LED2 Brightness: " + String(pwm2));
});
}
const int PWM_PIN_1 = 16;
const int PWM_PIN_2 = 17;
const int PWM_CHANNEL_1 = 0;
const int PWM_CHANNEL_2 = 1;
void setup() {
ledcSetup(PWM_CHANNEL_1, 5000, 8);
ledcSetup(PWM_CHANNEL_2, 5000, 8);
ledcAttachPin(PWM_PIN_1, PWM_CHANNEL_1);
ledcAttachPin(PWM_PIN_2, PWM_CHANNEL_2);
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
int pwm1 = map(slider1, 0, 100, 0, 255);
int pwm2 = map(slider2, 0, 100, 0, 255);
ledcWrite(PWM_CHANNEL_1, pwm1);
ledcWrite(PWM_CHANNEL_2, pwm2);
Serial.println("LED1 Brightness: " + String(pwm1) +
", LED2 Brightness: " + String(pwm2));
});
}
#include <ESP32Servo.h>
Servo servo1, servo2;
void setup() {
servo1.attach(16);
servo2.attach(17);
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
int angle1 = map(slider1, 0, 100, 0, 180);
int angle2 = map(slider2, 0, 100, 0, 180);
servo1.write(angle1);
servo2.write(angle2);
Serial.println("Servo1: " + String(angle1) + "°, Servo2: " + String(angle2) + "°");
});
}
const int MOTOR1_PWM = 16;
const int MOTOR1_DIR1 = 18;
const int MOTOR1_DIR2 = 19;
const int MOTOR2_PWM = 17;
const int MOTOR2_DIR1 = 21;
const int MOTOR2_DIR2 = 22;
void setup() {
pinMode(MOTOR1_PWM, OUTPUT);
pinMode(MOTOR1_DIR1, OUTPUT);
pinMode(MOTOR1_DIR2, OUTPUT);
pinMode(MOTOR2_PWM, OUTPUT);
pinMode(MOTOR2_DIR1, OUTPUT);
pinMode(MOTOR2_DIR2, OUTPUT);
digitalWrite(MOTOR1_DIR1, HIGH);
digitalWrite(MOTOR1_DIR2, LOW);
digitalWrite(MOTOR2_DIR1, HIGH);
digitalWrite(MOTOR2_DIR2, LOW);
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
int pwm1 = map(slider1, 0, 100, 0, 255);
int pwm2 = map(slider2, 0, 100, 0, 255);
analogWrite(MOTOR1_PWM, pwm1);
analogWrite(MOTOR2_PWM, pwm2);
Serial.println("Motor1: " + String(slider1) + "%, " +
"Motor2: " + String(slider2) + "%");
});
}
const int RED_PIN = 16;
const int GREEN_PIN = 17;
const int BLUE_PIN = 18;
void setup() {
pinMode(RED_PIN, OUTPUT);
pinMode(GREEN_PIN, OUTPUT);
pinMode(BLUE_PIN, OUTPUT);
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
int redValue = map(slider1, 0, 100, 0, 255);
int blueValue = map(slider2, 0, 100, 0, 255);
int greenValue = (redValue + blueValue) / 2;
analogWrite(RED_PIN, redValue);
analogWrite(GREEN_PIN, greenValue);
analogWrite(BLUE_PIN, blueValue);
Serial.println("RGB - R:" + String(redValue) +
" G:" + String(greenValue) +
" B:" + String(blueValue));
});
}
class SliderSmoother {
private:
int currentValue = 0;
int targetValue = 0;
unsigned long lastUpdate = 0;
const int SMOOTH_RATE = 2;
public:
void setTarget(int target) {
targetValue = target;
}
int getCurrentValue() {
return currentValue;
}
bool update() {
if (millis() - lastUpdate > 10) {
bool changed = false;
if (currentValue < targetValue) {
currentValue = min(currentValue + SMOOTH_RATE, targetValue);
changed = true;
} else if (currentValue > targetValue) {
currentValue = max(currentValue - SMOOTH_RATE, targetValue);
changed = true;
}
lastUpdate = millis();
return changed;
}
return false;
}
};
SliderSmoother smoother1, smoother2;
void setup() {
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
smoother1.setTarget(slider1);
smoother2.setTarget(slider2);
});
}
void loop() {
bluetoothServer.loop();
bool changed1 = smoother1.update();
bool changed2 = smoother2.update();
if (changed1 || changed2) {
analogWrite(16, map(smoother1.getCurrentValue(), 0, 100, 0, 255));
analogWrite(17, map(smoother2.getCurrentValue(), 0, 100, 0, 255));
}
}
void setupThresholdControl() {
bluetoothSlider.onSliderValue([](int slider1, int slider2) {
currentSlider1 = slider1;
currentSlider2 = slider2;
const int LOW_THRESHOLD = 33;
const int MEDIUM_THRESHOLD = 66;
if (slider1 < LOW_THRESHOLD) {
digitalWrite(18, LOW);
digitalWrite(19, LOW);
digitalWrite(21, LOW);
} else if (slider1 < MEDIUM_THRESHOLD) {
digitalWrite(18, HIGH);
digitalWrite(19, LOW);
digitalWrite(21, LOW);
} else {
digitalWrite(18, HIGH);
digitalWrite(19, HIGH);
digitalWrite(21, HIGH);
}
analogWrite(16, map(slider2, 0, 100, 0, 255));
});
}