ESP32 S3 UNO - DIYables Bluetooth App Slider

Overview

This ESP32 S3 Uno Bluetooth slider tutorial shows you how to drag two sliders on your phone and send their values to the ESP32 S3 Uno form board over BLE. The DIYables Bluetooth STEM app gives you two independent sliders with a 0 to 100 range. You can use them to dim LEDs, set a motor speed or move a servo, with no wires between the phone and the board.

In this tutorial, you will:

  1. Install the DIYables Bluetooth library in the Arduino IDE
  2. Upload the BLE slider example to the ESP32 S3 Uno
  3. Connect the DIYables Bluetooth app and read the slider values in the Serial Monitor
  4. Change the slider range and step size in code
  5. Map the values to PWM for LED brightness, servo angle and motor speed
ESP32 S3 Uno Bluetooth slider

※ NOTE THAT:

The ESP32 S3 Uno supports only BLE (Bluetooth Low Energy). It has no Bluetooth Classic radio, so the BluetoothSerial library and the Classic Bluetooth example (Esp32Bluetooth_Slider) do not work on it. This page uses only the BLE example (Esp32BLE_Slider). The good news: BLE works with the app on both Android and iOS, and you do not need to pair the board first.

Features

The slider app turns your phone into a small control panel with two faders. Here is what it gives you.

Two independent sliders

Each slider sends its own value. You can control two outputs at the same time, for example two LEDs or two servos.

Range and step you can change

The default range is 0 to 100 with a step of 1. You can set a new minimum, maximum and step in code, even while the sketch runs.

Real-time values

The app sends a new value as soon as you move a slider. The board gets it right away and can update its output.

Ready for PWM

A value from 0 to 100 maps easily to the 0 to 255 range of analogWrite(), so LED dimming and motor speed are only one line of code.

BLE on Android and iOS

BLE works on both phone types and needs no manual pairing. It also uses less power than Classic Bluetooth.

Hardware Preparation

1×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)
2×(optional) LED
1×Alternatively, Button and LED Kit
2×(optional) 220 ohm Resistor
2×(optional) Servo Motor
1×Breadboard
1×Jumper Wires

Or you can buy the following kits:

1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you.
Additionally, some of these links are for products from our own brand, DIYables .

Buy Note: For controlling multiple servo motors, use the PCA9685 16 Channel PWM Servo Driver Module to save MCU pins and simplify wiring.

ESP32 S3 Uno Pinout

The image below shows the pinout diagram of the ESP32 S3 Uno form board. Use it to find the Uno header pins (D3, D5, D9, D10…) and their GPIO numbers when you add LEDs or servos to this project.

ESP32 S3 Uno pinout diagram

ESP32 S3 Uno Code

You can test the basic example with only the board, a USB cable and your phone. The steps below install the library and upload the BLE slider sketch. LEDs are optional and only show the PWM output.

Detailed Instructions

  1. New to the ESP32 S3 Uno? Follow ESP32 S3 Uno - Getting Started first.
  2. Connect the board to your computer with a USB Type-C cable.
  3. Open Arduino IDE, choose the ESP32S3 Dev Module board and the correct COM port.
  4. Set the partition scheme: go to Tools > Partition Scheme and pick "Huge APP (3MB No OTA/1MB SPIFFS)". The Bluetooth library is big and does not fit in the default app space.
  5. Open the Library Manager: click the Libraries icon on the left bar of the Arduino IDE.
  6. Find the library: search "DIYables Bluetooth" and find the DIYables Bluetooth library by DIYables.
  7. Install it: click the Install button.
  • Search for DIYables Bluetooth created by DIYables and click the Install button.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Library Manager
Type:
All
Topic:
All
DIYables Bluetooth by DIYables
A comprehensive Bluetooth library that connects Arduino to the DIYables Bluetooth STEM mobile app (Android & iOS) via BLE and Classic Bluetooth. Features 11 built-in apps: Monitor, Chat, Digital Pin Control, Joystick, Sliders, Plotter, Analog Gauge, Rotator, Temperature, RTC, and Data Table. Clean architecture with platform abstraction. Works with Arduino Uno R4 WiFi, Arduino Nano 33 BLE, ESP32, and other BLE-capable boards. No mobile coding required. More info
1.0.1
INSTALL
Newbiely.ino
···
1 void setup() {
Output
Serial Monitor
Ln 1, Col 1
ESP32S3 Dev Module on COM15
1
  1. Install the dependencies: when the IDE asks about other libraries, click Install All.
  2. Tip: if the upload fails with a "Sketch too big" message, check the partition scheme again. It often resets when you change the board.

ESP32 S3 Uno BLE Code (works with the app on Android and iOS)

This sketch starts a BLE server named "ESP32BLE_Slider" and adds the slider app to it. Each new slider value is printed to the Serial Monitor and turned into a PWM signal on D9 (GPIO46) and D10 (GPIO10). When the phone connects, the board sends the last values back, so the sliders in the app show the right position.

If you want to see the PWM output, wire one LED to each pin like this:

LED Pin ESP32 S3 Uno Pin
LED 1 anode (+) through a 220 ohm resistor D9 (GPIO46)
LED 2 anode (+) through a 220 ohm resistor D10 (GPIO10)
LED 1 and LED 2 cathode (-) GND

WARNING

D9 (GPIO46) is a boot strapping pin on the ESP32 S3 Uno. The board reads it at startup to choose the boot mode. An LED with a resistor is normally fine, but if the board will not boot or upload while the LED is connected, unplug the wire from D9, upload, and then plug it back in.

  1. Load the example: in Arduino IDE, go to File Examples DIYables Bluetooth Esp32BLE_Slider, or copy the code below into the editor.
/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-diyables-bluetooth-app-slider */ /* * DIYables Bluetooth Library - ESP32 S3 Uno BLE Slider Example * Works with DIYables Bluetooth STEM app on Android and iOS * * This example demonstrates the Bluetooth Slider feature: * - Control values using sliders (0-100) * - Support for dual sliders * - Configurable range and step * * Board: ESP32 S3 Uno form board (BLE only, no Classic Bluetooth) * Optional: LEDs (with 220 ohm resistors) on header pins D9 (GPIO46) and D10 (GPIO10) * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 S3 Uno * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and control sliders * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothSlider.h> #include <platforms/DIYables_Esp32BLE.h> // BLE Configuration 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"; // Create Bluetooth instances DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Slider app instance (min=0, max=100, step=1) DIYables_BluetoothSlider bluetoothSlider(0, 100, 1); // Variables to store current slider values int currentSlider1 = 0; int currentSlider2 = 0; // PWM output pins (for LED brightness control example) const int PWM_PIN_1 = 46; // ESP32 S3 Uno pin D9 (GPIO46) const int PWM_PIN_2 = 10; // ESP32 S3 Uno pin D10 (GPIO10) void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 S3 Uno BLE Slider Example"); // Initialize PWM pins pinMode(PWM_PIN_1, OUTPUT); pinMode(PWM_PIN_2, OUTPUT); // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add slider app to server bluetoothServer.addApp(&bluetoothSlider); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); // Send initial slider positions bluetoothSlider.send(currentSlider1, currentSlider2); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); // Set up slider callback for value changes bluetoothSlider.onSliderValue([](int slider1, int slider2) { // Store the received values currentSlider1 = slider1; currentSlider2 = slider2; // Print slider values (0-100) Serial.print("Slider 1: "); Serial.print(slider1); Serial.print(", Slider 2: "); Serial.println(slider2); // Map slider values (0-100) to PWM range (0-255) int pwm1 = map(slider1, 0, 100, 0, 255); int pwm2 = map(slider2, 0, 100, 0, 255); // Control LED brightness analogWrite(PWM_PIN_1, pwm1); analogWrite(PWM_PIN_2, pwm2); // TODO: Add your control logic here }); // Optional: Handle requests for current slider values (when app loads) bluetoothSlider.onGetConfig([]() { // Send the stored slider values back to the app bluetoothSlider.send(currentSlider1, currentSlider2); Serial.print("App requested values - Sent: Slider1="); Serial.print(currentSlider1); Serial.print(", Slider2="); Serial.println(currentSlider2); }); // You can change slider configuration at runtime: // bluetoothSlider.setRange(0, 255); // Change range to 0-255 // bluetoothSlider.setStep(5); // Change step to 5 (coarser control) Serial.println("Waiting for Bluetooth connection..."); } void loop() { // Handle Bluetooth server communications bluetoothServer.loop(); delay(10); }
  1. Upload: click the Upload button.
  2. Open the Serial Monitor and set it to 115200 baud.
  3. Check the output. It should look like this:
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
DIYables Bluetooth - ESP32 S3 Uno BLE Slider Example Waiting for Bluetooth connection...
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2
  1. Tip: the library example uses other pin numbers. Keep the D9 (GPIO46) and D10 (GPIO10) numbers from the code above so they match the Uno header positions.

Mobile App

The app is where you move the sliders. Because the ESP32 S3 Uno uses BLE, you connect from inside the app and skip the phone's Bluetooth pairing menu.

  1. Install the app: get the DIYables Bluetooth App for Android or iOS.
  2. Open the app and grant the permissions it asks for:
  • Nearby Devices (Android 12+) or Bluetooth (iOS), needed to scan and connect
  • Location (Android 11 and below only), needed by older Android versions to scan for BLE devices
  1. Turn on Bluetooth on your phone.
  2. Scan: on the home screen, tap the Connect button.
DIYables Bluetooth App - Home Screen with Scan Button
  1. Connect: tap "ESP32BLE_Slider" in the scan results.
  2. Open the Slider: the app returns to the home screen after it connects. Tap the Slider app.
DIYables Bluetooth App - Home Screen with Slider App

※ NOTE THAT:

You can tap the settings icon on the home screen to show or hide apps. For more details, read the DIYables Bluetooth App User Manual.

  1. Move the sliders: drag each one to change its value from 0 to 100.
DIYables Bluetooth App - Slider Screen

Go back to the Serial Monitor in the Arduino IDE. You will see each new pair of values as you move the sliders:

∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
ESP32S3 Dev Module
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'ESP32S3 Dev Module' on 'COM15')
New Line
9600 baud
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
Ln 11, Col 1
ESP32S3 Dev Module on COM15
2

If you wired the LEDs, they get brighter as you move the sliders up.

Creative Customization - Adapt the Code to Your Project

The example prints the values and dims two outputs. The snippets below show the library functions you can use to shape the sliders and react to them in your own ESP32 S3 Uno project.

Set Default Slider Values

The two variables hold the slider positions. Give them a start value, and the app shows that position when it connects.

// Current slider values (0-100) int currentSlider1 = 25; // Default 25% int currentSlider2 = 50; // Default 50%

Customize Slider Range and Step

You set the range and step when you create the slider object. You can also change them later and read them back.

// Create Slider app instance with custom range (min=0, max=255, step=5) DIYables_BluetoothSlider bluetoothSlider(0, 255, 5); // Or change at runtime: bluetoothSlider.setRange(0, 255); // Change range to 0-255 bluetoothSlider.setStep(5); // Change step to 5 (coarser control) // Read current configuration: int currentMin = bluetoothSlider.getMin(); // Get current minimum value int currentMax = bluetoothSlider.getMax(); // Get current maximum value int currentStep = bluetoothSlider.getStep(); // Get current step value

Handle Configuration Request from App

When the app opens the slider screen, it asks the board for the current values. Answer in the onGetConfig() callback, so the sliders do not jump back to 0.

bluetoothSlider.onGetConfig([]() { // This is called when the app requests slider configuration // Send current slider values so the app displays them correctly bluetoothSlider.send(currentSlider1, currentSlider2); Serial.println("App requested config - sent current values"); });

Send Values to App

The ESP32 S3 Uno can also move the sliders on the phone by itself, for example after a button press or a sensor change.

// Send both slider values to the app bluetoothSlider.send(currentSlider1, currentSlider2); // Send a single value (applied to both sliders) bluetoothSlider.send(50);

Handle Connection Events

These two callbacks tell you when the phone connects or leaves. A good habit is to stop motors when the connection drops.

// Called when the app connects to the ESP32 S3 Uno bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); // Send current slider values to the app bluetoothSlider.send(currentSlider1, currentSlider2); }); // Called when the app disconnects from the ESP32 S3 Uno bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); // Optional: stop motors, reset outputs, etc. }); // Check connection status anywhere in your code if (bluetoothServer.isConnected()) { // Do something only when connected }

How to Use the Sliders

It helps to know what each part of the screen does before you build on it.

App Interface Controls

Slider 1 and Slider 2

Two separate sliders. Drag each one up or down to set its value.

Value display

A number next to each slider shows its current value, so you always know what the board receives.

Value Ranges

Each slider runs from 0 to 100 by default. You can change the range and step in code. To drive a PWM pin, map the value to 0 to 255 with map(value, 0, 100, 0, 255).

Programming Examples

These examples show real uses for the slider values. Each one is a part of a sketch, so add it to the full BLE example above.

Basic Slider Handler

This is the smallest useful callback. It stores the two values and prints them, and you add your own logic at the end.

void setup() { // Set up slider callback for value changes bluetoothSlider.onSliderValue([](int slider1, int slider2) { // Store the received values currentSlider1 = slider1; currentSlider2 = slider2; // Print slider values Serial.println("Slider 1: " + String(slider1) + ", Slider 2: " + String(slider2)); // Add your control logic here }); }

LED Brightness Control

Each slider sets the brightness of one LED. The analogWrite() function works on the ESP32 S3 Uno, so no special PWM setup is needed. Use the same LED wiring as the main example: D9 (GPIO46) and D10 (GPIO10).

// PWM output pins const int PWM_PIN_1 = 46; // ESP32 S3 Uno pin D9 (GPIO46) const int PWM_PIN_2 = 10; // ESP32 S3 Uno pin D10 (GPIO10) void setup() { // Configure PWM pins as outputs pinMode(PWM_PIN_1, OUTPUT); pinMode(PWM_PIN_2, OUTPUT); bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Map slider values (0-100) to PWM range (0-255) int pwm1 = map(slider1, 0, 100, 0, 255); int pwm2 = map(slider2, 0, 100, 0, 255); // Control LED brightness analogWrite(PWM_PIN_1, pwm1); analogWrite(PWM_PIN_2, pwm2); Serial.println("LED1 Brightness: " + String(pwm1) + ", LED2 Brightness: " + String(pwm2)); }); }

Servo Position Control

Each slider moves one servo from 0° to 180°. Install the "ESP32Servo" library by Kevin Harrington first. The standard Servo library does not run on the ESP32 S3 Uno.

Servo Pin ESP32 S3 Uno Pin
VCC (red) of both servos 5V
GND (brown) of both servos GND
Signal (orange) of servo 1 D9 (GPIO46)
Signal (orange) of servo 2 D10 (GPIO10)
#include <ESP32Servo.h> Servo servo1, servo2; void setup() { // Attach servos to pins servo1.attach(46); // ESP32 S3 Uno pin D9 (GPIO46) servo2.attach(10); // ESP32 S3 Uno pin D10 (GPIO10) bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Map slider values (0-100) to servo angles (0-180°) int angle1 = map(slider1, 0, 100, 0, 180); int angle2 = map(slider2, 0, 100, 0, 180); // Move servos to calculated positions servo1.write(angle1); servo2.write(angle2); Serial.println("Servo1: " + String(angle1) + "°, Servo2: " + String(angle2) + "°"); }); }

Motor Speed with Direction

Here slider 1 sets the motor speed and slider 2 picks the direction. A value of 50 or more means forward, below 50 means reverse. Connect the speed input of your motor driver to D9 (GPIO46) and the direction input to D8 (GPIO21).

const int MOTOR_SPEED_PIN = 46; // ESP32 S3 Uno pin D9 (GPIO46) const int MOTOR_DIR_PIN = 21; // ESP32 S3 Uno pin D8 (GPIO21) void setup() { pinMode(MOTOR_SPEED_PIN, OUTPUT); pinMode(MOTOR_DIR_PIN, OUTPUT); bluetoothSlider.onSliderValue([](int slider1, int slider2) { // Slider 1: speed (0-100%) // Slider 2: direction threshold (below 50 = reverse, above 50 = forward) int speed = map(slider1, 0, 100, 0, 255); bool forward = (slider2 >= 50); analogWrite(MOTOR_SPEED_PIN, speed); digitalWrite(MOTOR_DIR_PIN, forward ? HIGH : LOW); Serial.print("Speed: "); Serial.print(slider1); Serial.print("%, Direction: "); Serial.println(forward ? "Forward" : "Reverse"); }); }

RGB LED Color Control

Two sliders can mix three colors. Slider 1 sets red, slider 2 sets blue, and green is the average of both. Wire the red, green and blue legs to D9 (GPIO46), D10 (GPIO10) and D11 (GPIO11), each through a 220 ohm resistor.

// RGB LED pins const int RED_PIN = 46; // ESP32 S3 Uno pin D9 (GPIO46) const int GREEN_PIN = 10; // ESP32 S3 Uno pin D10 (GPIO10) const int BLUE_PIN = 11; // ESP32 S3 Uno pin D11 (GPIO11) void setup() { pinMode(RED_PIN, OUTPUT); pinMode(GREEN_PIN, OUTPUT); pinMode(BLUE_PIN, OUTPUT); bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Slider 1 controls red intensity // Slider 2 controls blue intensity // Green is calculated based on both sliders 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)); }); }

Advanced Programming Techniques

Once the basics work, you can change how the values are handled before you use them.

Value Smoothing

A sudden jump from 0 to 100 can make a motor jerk. This class moves the output toward the new target in small steps every 10 ms, so changes feel soft.

class SliderSmoother { private: int currentValue = 0; int targetValue = 0; unsigned long lastUpdate = 0; const int SMOOTH_RATE = 2; // Change per update cycle public: void setTarget(int target) { targetValue = target; } int getCurrentValue() { return currentValue; } bool update() { if (millis() - lastUpdate > 10) { // Update every 10ms 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) { // Set target values for smooth transition smoother1.setTarget(slider1); smoother2.setTarget(slider2); }); } void loop() { bluetoothServer.loop(); // Update smoothed values bool changed1 = smoother1.update(); bool changed2 = smoother2.update(); if (changed1 || changed2) { // Map smoothed values (0-100) to PWM (0-255) and apply analogWrite(46, map(smoother1.getCurrentValue(), 0, 100, 0, 255)); // D9 (GPIO46) analogWrite(10, map(smoother2.getCurrentValue(), 0, 100, 0, 255)); // D10 (GPIO10) } }

Slider with Dead Zone

A dead zone around the middle gives you a clear "stop" position. Values from 45 to 55 turn the output off, and the rest sets the speed.

const int MOTOR_PIN = 46; // ESP32 S3 Uno pin D9 (GPIO46) bluetoothSlider.onSliderValue([](int slider1, int slider2) { // Add dead zone around center (45-55 = stop) if (slider1 >= 45 && slider1 <= 55) { Serial.println("Center - stopped"); analogWrite(MOTOR_PIN, 0); } else { int speed = map(slider1, 0, 100, 0, 255); analogWrite(MOTOR_PIN, speed); } });

Threshold-Based Control

You can also split a slider into levels and switch digital outputs. Slider 1 turns on zero, one or three outputs on D2 (GPIO18), D4 (GPIO19) and D7 (GPIO14). Slider 2 still sets PWM on D10 (GPIO10).

void setupThresholdControl() { bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Threshold-based control for discrete outputs const int LOW_THRESHOLD = 33; const int MEDIUM_THRESHOLD = 66; // Control digital outputs based on slider 1 thresholds // D2 = GPIO18, D4 = GPIO19, D7 = GPIO14 if (slider1 < LOW_THRESHOLD) { // Low level: Turn off all outputs digitalWrite(18, LOW); digitalWrite(19, LOW); digitalWrite(14, LOW); } else if (slider1 < MEDIUM_THRESHOLD) { // Medium level: Turn on first output digitalWrite(18, HIGH); digitalWrite(19, LOW); digitalWrite(14, LOW); } else { // High level: Turn on all outputs digitalWrite(18, HIGH); digitalWrite(19, HIGH); digitalWrite(14, HIGH); } // Use slider 2 for analog PWM control on D10 (GPIO10) analogWrite(10, map(slider2, 0, 100, 0, 255)); }); }

Preset Value System

Presets let you jump to saved positions with one call. The function updates the outputs and sends the new values to the app, so the sliders move too.

// Predefined preset values (0-100 range) const int PRESETS[][2] = { {0, 0}, // Preset 0: Both off {25, 50}, // Preset 1: Low/Medium {50, 50}, // Preset 2: Both medium {100, 50}, // Preset 3: High/Medium {100, 100} // Preset 4: Both maximum }; void applyPreset(int presetNumber) { if (presetNumber >= 0 && presetNumber < 5) { currentSlider1 = PRESETS[presetNumber][0]; currentSlider2 = PRESETS[presetNumber][1]; // Update hardware: D9 (GPIO46) and D10 (GPIO10) analogWrite(46, map(currentSlider1, 0, 100, 0, 255)); analogWrite(10, map(currentSlider2, 0, 100, 0, 255)); // Send updated values to the app bluetoothSlider.send(currentSlider1, currentSlider2); Serial.println("Applied preset " + String(presetNumber) + ": " + String(currentSlider1) + ", " + String(currentSlider2)); } }

Rate Limiting

If you drag a slider fast, the app sends many values. This check makes sure the output changes at most once every 50 ms.

const int PWM_PIN = 46; // ESP32 S3 Uno pin D9 (GPIO46) unsigned long lastSliderAction = 0; const unsigned long SLIDER_COOLDOWN = 50; // 50ms minimum bluetoothSlider.onSliderValue([](int slider1, int slider2) { if (millis() - lastSliderAction >= SLIDER_COOLDOWN) { lastSliderAction = millis(); // Process slider value analogWrite(PWM_PIN, map(slider1, 0, 100, 0, 255)); } });

Hardware Integration Examples

The same callback can drive bigger hardware. These two examples show an addressable LED strip and two fans.

LED Strip Control

Slider 1 sets the brightness and slider 2 sets the hue of a WS2812B strip. You need a library like FastLED or Adafruit NeoPixel. Connect the strip data line to D7 (GPIO14). Most WS2812B strips read the 3.3V data signal fine, but some need a level shifter.

// For WS2812B or similar addressable LED strips // (requires additional libraries like FastLED or Adafruit NeoPixel) const int LED_STRIP_PIN = 14; // ESP32 S3 Uno pin D7 (GPIO14) const int NUM_LEDS = 30; void setupLEDStrip() { // Initialize LED strip (depends on library used) bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Slider 1 controls brightness (0-100 mapped to 0-255) // Slider 2 controls color temperature or hue (0-100 mapped to 0-255) uint8_t brightness = map(slider1, 0, 100, 0, 255); uint8_t hue = map(slider2, 0, 100, 0, 255); // Update LED strip (example with conceptual functions) // strip.setBrightness(brightness); // strip.fill(CHSV(hue, 255, 255)); // strip.show(); Serial.println("LED Strip - Brightness: " + String(brightness) + ", Hue: " + String(hue)); }); }

Fan Speed Control

Small fans often do not start at a low PWM value. This code keeps the fan off below a threshold and starts it at a safe minimum speed. Drive each fan through a transistor or MOSFET module from D9 (GPIO46) and D10 (GPIO10), never straight from the pin.

const int FAN1_PIN = 46; // ESP32 S3 Uno pin D9 (GPIO46) const int FAN2_PIN = 10; // ESP32 S3 Uno pin D10 (GPIO10) void setupFanControl() { pinMode(FAN1_PIN, OUTPUT); pinMode(FAN2_PIN, OUTPUT); bluetoothSlider.onSliderValue([](int slider1, int slider2) { currentSlider1 = slider1; currentSlider2 = slider2; // Map slider values (0-100) to PWM (0-255) int pwm1 = map(slider1, 0, 100, 0, 255); int pwm2 = map(slider2, 0, 100, 0, 255); // Control fan speeds with minimum threshold for startup int fan1Speed = (pwm1 > 50) ? map(pwm1, 50, 255, 100, 255) : 0; int fan2Speed = (pwm2 > 50) ? map(pwm2, 50, 255, 100, 255) : 0; analogWrite(FAN1_PIN, fan1Speed); analogWrite(FAN2_PIN, fan2Speed); Serial.println("Fan1: " + String(slider1) + "%, " + "Fan2: " + String(slider2) + "%"); }); }

Why BLE Only on the ESP32 S3 Uno?

Some ESP32 boards offer both BLE and Classic Bluetooth. The ESP32 S3 Uno has a BLE radio only, so the choice is made for you. That is fine for this project, as the table shows.

Feature BLE on the ESP32 S3 Uno
iOS Support Yes
Android Support Yes
Power Use Low
Range About 30 to 100 m in open space
Pairing Not needed, connect from the app
Example Name Esp32BLE_Slider
Classic Bluetooth (BluetoothSerial) Not supported on this board

Video Tutorial

Watch the video below to see this ESP32 S3 Uno project step by step. In the demo, each slider moves one servo motor. The servo signals go to D3 (GPIO17) and D5 (GPIO20), and both servos take power from the 5V pin.

Servo Pin ESP32 S3 Uno Pin
VCC (red) of both servos 5V
GND (brown) of both servos GND
Signal (orange) of servo 1 D3 (GPIO17)
Signal (orange) of servo 2 D5 (GPIO20)

The code used in the demo is below. It needs the "ESP32Servo" library by Kevin Harrington.

/* * This ESP32 S3 Uno code was developed by newbiely.com * * This ESP32 S3 Uno code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp32-s3-uno/esp32-s3-uno-diyables-bluetooth-app-slider */ /* * DIYables Bluetooth Library - ESP32 S3 Uno BLE Slider Example (Servo Demo) * Works with DIYables Bluetooth STEM app on Android and iOS * * This example demonstrates the Bluetooth Slider feature: * - Control values using sliders (0-100) * - Support for dual sliders * - Each slider moves one servo motor (0-180 degrees) * * Board: ESP32 S3 Uno form board (BLE only, no Classic Bluetooth) * Servo 1 signal: header pin D3 (GPIO17) * Servo 2 signal: header pin D5 (GPIO20) * Library: ESP32Servo by Kevin Harrington * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Setup: * 1. Upload the sketch to your ESP32 S3 Uno * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and control sliders * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothSlider.h> #include <platforms/DIYables_Esp32BLE.h> #include <ESP32Servo.h> Servo servo1, servo2; // BLE Configuration 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"; // Create Bluetooth instances DIYables_Esp32BLE bluetooth(DEVICE_NAME, SERVICE_UUID, TX_UUID, RX_UUID); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Slider app instance (min=0, max=100, step=1) DIYables_BluetoothSlider bluetoothSlider(0, 100, 1); // Variables to store current slider values int currentSlider1 = 0; int currentSlider2 = 0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 S3 Uno BLE Slider Example"); // Attach the servos servo1.attach(17); // ESP32 S3 Uno pin D3 (GPIO17) servo2.attach(20); // ESP32 S3 Uno pin D5 (GPIO20) // Initialize Bluetooth server with platform-specific implementation bluetoothServer.begin(); // Add slider app to server bluetoothServer.addApp(&bluetoothSlider); // Set up connection event callbacks bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); // Send initial slider positions bluetoothSlider.send(currentSlider1, currentSlider2); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); // Set up slider callback for value changes 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.print("Servo 1: "); Serial.print(angle1); Serial.print("°, Servo 2: "); Serial.print(angle2); Serial.println("°"); }); // Optional: Handle requests for current slider values (when app loads) bluetoothSlider.onGetConfig([]() { // Send the stored slider values back to the app bluetoothSlider.send(currentSlider1, currentSlider2); Serial.print("App requested values - Sent: Slider1="); Serial.print(currentSlider1); Serial.print(", Slider2="); Serial.println(currentSlider2); }); // You can change slider configuration at runtime: // bluetoothSlider.setRange(0, 255); // Change range to 0-255 // bluetoothSlider.setStep(5); // Change step to 5 (coarser control) Serial.println("Waiting for Bluetooth connection..."); } void loop() { // Handle Bluetooth server communications bluetoothServer.loop(); delay(10); }

Common Issues and Debugging

Most slider problems come from the connection, the range settings or the output pins. Check these first.

The device does not show up in the app

Make sure the sketch is uploaded and the board is powered. Turn on Bluetooth on your phone, and on Android 11 and below also turn on Location. Look for "ESP32BLE_Slider", not a Classic Bluetooth name.

The sliders move but nothing happens

Look at the connection status in the app and in the Serial Monitor. If you see no "Bluetooth connected!" line, disconnect and connect again.

The values do not reach the full range

Check the range in DIYables_BluetoothSlider(min, max, step) and the numbers in your map() call. Print the received values in the Serial Monitor to see what really arrives.

The sliders jump back to 0 after a reconnect

Store the values in global variables and send them back in the onGetConfig() and setOnConnected() callbacks.

The connection drops often

Move the phone closer to the ESP32 S3 Uno and away from other BLE devices. A weak USB port can also cause drops.

Sketch too big

Go to Tools > Partition Scheme and pick "Huge APP (3MB No OTA/1MB SPIFFS)" or "No OTA (Large APP)". The default scheme leaves only about 1.2 MB for your code, which is too small for the Bluetooth library.

Debug Tips

This helper prints both slider values and their PWM values in one block. Call it inside onSliderValue() while you test.

void debugSliderValues(int slider1, int slider2) { Serial.println("=== Slider Debug ==="); Serial.println("Slider 1: " + String(slider1) + "%"); Serial.println("Slider 2: " + String(slider2) + "%"); Serial.println("PWM 1: " + String(map(slider1, 0, 100, 0, 255))); Serial.println("PWM 2: " + String(map(slider2, 0, 100, 0, 255))); Serial.println("==================="); }

Project Ideas

Two sliders are a simple input, but they fit many projects. Here are some ideas for your ESP32 S3 Uno.

Lighting Control Projects

A room light dimmer, an RGB color mixer, an LED strip brightness and hue control, or a small stage light dimmer.

Motor Control Projects

A robot speed control, a fan speed regulator, a pump flow control, a pan-tilt camera mount with two servos, or a conveyor belt speed control.

Audio Projects

A volume control, a tone frequency selector or an equalizer band.

Home Automation

A heating or cooling level control, a window blind position control, or an irrigation flow control.

Integration with Other Bluetooth Apps

The slider works well together with other DIYables Bluetooth apps on the same board.

Combine with Bluetooth Joystick

Use slider 1 as a speed limit and the joystick for direction. The joystick values are scaled by the slider before they reach the motors.

// Global speed limit from sliders int maxSpeed = 100; // In Bluetooth Slider callback bluetoothSlider.onSliderValue([](int slider1, int slider2) { maxSpeed = slider1; // Use slider 1 as global speed limit }); // In Bluetooth Joystick callback bluetoothJoystick.onJoystickValue([](int x, int y) { // Scale joystick values by slider-controlled speed limit int scaledX = map(x, -100, 100, -maxSpeed, maxSpeed); int scaledY = map(y, -100, 100, -maxSpeed, maxSpeed); controlRobot(scaledX, scaledY); });

Combine with Bluetooth Digital Pins

Use digital pins as on/off switches and sliders for the level. A PWM output only runs when its switch pin is HIGH. Here the switch pins are D2 (GPIO18) and D4 (GPIO19), and the PWM outputs are D9 (GPIO46) and D10 (GPIO10).

bluetoothSlider.onSliderValue([](int slider1, int slider2) { // Only apply PWM if corresponding digital pins are ON if (digitalRead(18) == HIGH) { // D2 (GPIO18) analogWrite(46, map(slider1, 0, 100, 0, 255)); // D9 (GPIO46) } else { analogWrite(46, 0); } if (digitalRead(19) == HIGH) { // D4 (GPIO19) analogWrite(10, map(slider2, 0, 100, 0, 255)); // D10 (GPIO10) } else { analogWrite(10, 0); } });

Next Steps

When the slider works, try these other examples on your ESP32 S3 Uno:

  1. Bluetooth Joystick for 2D direction control
  2. Bluetooth Rotator for angle control
  3. Bluetooth Digital Pins for on/off control
  4. Bluetooth Monitor to watch your slider values on the phone
  5. Multiple Bluetooth Apps to combine the slider with other controls

Support

If you get stuck, these places can help:

  1. The API Reference documentation of the DIYables Bluetooth library
  2. The Arduino community forums

FAQ

Does the ESP32 S3 Uno support Classic Bluetooth for the slider?

No. The ESP32 S3 Uno has BLE only. Use the Esp32BLE_Slider example. The Esp32Bluetooth_Slider example uses BluetoothSerial and will not compile or work on this board.

Which library do I need for the Bluetooth slider on the ESP32 S3 Uno?

Install the "DIYables Bluetooth" library by DIYables and its dependencies. The ESP32 S3 Uno uses platforms/DIYables_Esp32BLE.h, while the UNO R4 WiFi uses platforms/DIYables_ArduinoBLE.h. The slider functions are the same on both boards.

Does analogWrite() work on the ESP32 S3 Uno?

Yes. The esp32 core supports analogWrite() with values from 0 to 255, so you can map the slider value and write it directly. You do not need ledcSetup() or ledcAttachPin() for this project.

Why are my LEDs dimmer than on a 5V board?

The ESP32 S3 Uno pins output 3.3V, not 5V. An LED with a 220 ohm resistor still works but looks a bit dimmer. For more brightness, use a smaller resistor (not below about 100 ohm) or drive the LED through a transistor.

Can I power two servos from the ESP32 S3 Uno 5V pin?

Two small SG90 servos with no load usually work from the 5V pin. Bigger servos, or servos under load, can pull current spikes that reset the board. In that case use an external 5V supply and connect its GND to the ESP32 S3 Uno GND.

What if my project needs more pins than the Uno headers give?

The ESP32 S3 Uno has two extra rows of holes with more GPIOs: GPIO15 and GPIO16 (I/O, PWM, analog), GPIO45 and GPIO35 to GPIO42 (I/O, PWM), and GPIO47/GPIO48 (output only, PWM). Solder pin headers to use them and write the GPIO number in code. For extra LEDs, servos or motor drivers, GPIO35 to GPIO42 are a good choice, because every one of them supports PWM. Be careful with two things. First, GPIO47 and GPIO48 may run at 1.8V instead of 3.3V on some modules (especially ones with "V" in the name, like R8V or R16V), so 3.3V devices can be damaged or act strangely. Second, GPIO0, GPIO3 (D6), GPIO45 and GPIO46 (D9) are boot strapping pins, and a wrong connection can stop the board from booting or uploading code. Use the other extra pins first.

Troubleshooting

Problem Possible Cause Solution
No COM port in Arduino IDE USB driver missing or board not in download mode Install the CP210x or CH340 driver, try another USB cable, or hold BOOT while you press RESET
Upload fails with Sketch too big Default partition scheme is too small for BLE Select Huge APP (3MB No OTA/1MB SPIFFS) in Tools > Partition Scheme
ESP32BLE_Slider not in the scan list Sketch not running, or phone Bluetooth or Location is off Check the Serial Monitor for Waiting for Bluetooth connection, then turn on Bluetooth (and Location on Android 11 and below)
Compile error about BluetoothSerial Classic Bluetooth example used Use the Esp32BLE_Slider example, as the ESP32 S3 Uno has no Classic Bluetooth
LED does not change brightness Wrong pin, missing resistor or LED reversed Wire the LEDs to D9 (GPIO46) and D10 (GPIO10) with 220 ohm resistors and check the LED direction
Board does not boot with the LED or servo connected D9 (GPIO46) is a boot strapping pin Unplug the wire from D9 during boot or upload, then plug it back in
Board resets when the servos move Servos pull too much current from the 5V pin Use an external 5V supply for the servos and share GND with the board
Serial Monitor shows strange characters Wrong baud rate Set the Serial Monitor to 115200 baud

※ OUR MESSAGES

  • As freelancers, We are AVAILABLE for HIRE. See how to outsource your project to us
  • Please feel free to share the link of this tutorial. However, Please do not use our content on any other websites. We invested a lot of effort and time to create the content, please respect our work!