ESP32 - DIYables Bluetooth App Rotator

Overview

The Bluetooth Rotator example provides a rotatable disc/knob control accessible through the DIYables Bluetooth STEM app. Designed for ESP32 boards with support for both BLE (Bluetooth Low Energy) and Classic Bluetooth connections. The rotator sends angle values and supports continuous (0-360°) or limited angle range modes — perfect for servo control, compass display, volume knobs, and any application requiring rotational input.

This example supports two Bluetooth modes:

  • ESP32 BLE (Bluetooth Low Energy): Works on both Android and iOS
  • ESP32 Classic Bluetooth: Works on Android only. iOS does not support Classic Bluetooth. Use BLE if you need iOS support.
ESP32 Bluetooth Rotator Example - Rotatable Disc/Knob Control Interface Tutorial

Features

  • Rotatable Knob: Touch and drag to rotate the on-screen disc
  • Continuous Mode: Full 360° rotation without limits
  • Limited Mode: Constrained angle range (e.g., 0-180° for servos)
  • Angle Output: Float angle value sent in real time
  • Servo Compatible: Direct mapping to servo angles (0-180°)
  • BLE & Classic Bluetooth: Choose the Bluetooth mode that suits your project
  • Cross-Platform: BLE mode works on both Android and iOS; Classic Bluetooth works on Android
  • Low Power Option: BLE mode consumes less power than Classic Bluetooth

Hardware Used In This Tutorial

1×ESP-WROOM-32 Dev Module
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×Jumper Wires
1×Recommended: Screw Terminal Expansion Board for ESP32
1×Recommended: Breakout Expansion Board for ESP32
1×Recommended: Power Splitter for ESP32

Or you can buy the following kits:

1×DIYables ESP32 Starter Kit (ESP32 included)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links in this section are Amazon affiliate links, meaning we may earn a commission at no additional cost to you if you make a purchase through them. Additionally, some links direct you to products from our own brand, DIYables .

ESP32 Code

Quick Instructions

Follow these instructions step by step:

  • If this is your first time using the ESP32, refer to the tutorial on setting up the environment for ESP32 in the Arduino IDE.
  • Connect the ESP32 board to your computer using a USB cable.
  • Launch the Arduino IDE on your computer.
  • Select the appropriate ESP32 board and COM port.
  • Navigate to the Libraries icon on the left bar of the Arduino IDE.
  • Search "DIYables Bluetooth", then find the DIYables Bluetooth library by DIYables
  • Click Install button to install the library.
ESP32 DIYables Bluetooth library
  • You will be asked for installing some other library dependencies
  • Click Install All button to install all library dependencies.
ESP32 DIYables Bluetooth dependency

Choose one of the two Bluetooth modes below depending on your needs:

ESP32 Classic Bluetooth Code (works with app on Android only)

Note: Classic Bluetooth is NOT supported on iOS. If you need iOS support, use the BLE code below.

  • On Arduino IDE, Go to File Examples DIYables Bluetooth Esp32Bluetooth_Rotator example, or copy the above code and paste it to the editor of Arduino IDE
/* * DIYables Bluetooth Library - ESP32 Classic Bluetooth Rotator Example * Works with DIYables Bluetooth STEM app on Android * Note: Classic Bluetooth is NOT supported on iOS. Use BLE examples for iOS support. * * This example demonstrates the Bluetooth Rotator feature: * - Rotatable disc/knob control (0-360 degrees) * - Continuous or limited angle range * - Perfect for servo control, compass display, volume knobs * * Compatible Boards: * - ESP32 (all variants with Classic Bluetooth) * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Optional: Servo motor for visual feedback * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and rotate the knob * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothRotator.h> #include <platforms/DIYables_Esp32Bluetooth.h> // Create Bluetooth instances DIYables_Esp32Bluetooth bluetooth("ESP32_Rotator"); DIYables_BluetoothServer bluetoothServer(bluetooth); // Create Rotator app instance // Option 1: Continuous mode (0-360, wraps around) // DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_CONTINUOUS); // Option 2: Limited mode (constrained angle range) DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180); // Variables to store current angle float currentAngle = 0.0; // Optional: Servo control (uncomment if using ESP32Servo library) // #include <ESP32Servo.h> // Servo myServo; // const int SERVO_PIN = 13; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 Rotator Example"); // Optional: Initialize servo // myServo.attach(SERVO_PIN); // myServo.write(0); bluetoothServer.begin(); bluetoothServer.addApp(&bluetoothRotator); bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); bluetoothRotator.send(currentAngle); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; Serial.print("Rotator angle: "); Serial.print(angle); Serial.println("°"); // TODO: Add your control logic here based on angle // Examples: // - Servo control: myServo.write((int)angle); // - Stepper motor: stepper.moveTo(angleToSteps(angle)); // - LED ring: setLEDPosition(angle); // - Volume control: setVolume(map(angle, 0, 360, 0, 100)); }); Serial.println("Waiting for Bluetooth connection..."); } void loop() { bluetoothServer.loop(); delay(10); }
  • Click Upload button on Arduino IDE to upload code to ESP32
  • Open the Serial Monitor
  • Check out the result on Serial Monitor. It looks like the below:
COM6
Send
DIYables Bluetooth - ESP32 Rotator Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

ESP32 BLE Code (works with app on both Android and iOS)

  • On Arduino IDE, Go to File Examples DIYables Bluetooth Esp32BLE_Rotator example, or copy the above code and paste it to the editor of Arduino IDE
/* * DIYables Bluetooth Library - ESP32 BLE Rotator Example * Works with DIYables Bluetooth STEM app on Android and iOS * * This example demonstrates the Bluetooth Rotator feature: * - Rotatable disc/knob control (0-360 degrees) * - Continuous or limited angle range * - Perfect for servo control, compass display, volume knobs * * Compatible Boards: * - ESP32-WROOM-32 * - ESP32-DevKitC * - ESP32-WROVER * - ESP32-S3 * - ESP32-C3 * - Any ESP32 board supporting BLE * * Note: Select "Huge APP (3MB No OTA/1MB SPIFFS)" partition scheme * in Arduino IDE: Tools > Partition Scheme * * Optional: Servo motor for visual feedback * * Setup: * 1. Upload the sketch to your ESP32 * 2. Open Serial Monitor (115200 baud) to see connection status * 3. Use DIYables Bluetooth App to connect and rotate the knob * * Tutorial: https://diyables.io/bluetooth-app * Author: DIYables */ #include <DIYables_BluetoothServer.h> #include <DIYables_BluetoothRotator.h> #include <platforms/DIYables_Esp32BLE.h> // BLE Configuration const char* DEVICE_NAME = "ESP32BLE_Rotator"; 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 Rotator app instance DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180); // Variables to store current angle float currentAngle = 0.0; void setup() { Serial.begin(115200); delay(1000); Serial.println("DIYables Bluetooth - ESP32 BLE Rotator Example"); bluetoothServer.begin(); bluetoothServer.addApp(&bluetoothRotator); bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); bluetoothRotator.send(currentAngle); }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); }); bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; Serial.print("Rotator angle: "); Serial.print(angle); Serial.println("°"); // TODO: Add your control logic here based on angle }); Serial.println("Waiting for Bluetooth connection..."); } void loop() { bluetoothServer.loop(); delay(10); }
  • Click Upload button on Arduino IDE to upload code to ESP32
  • Open the Serial Monitor
  • Check out the result on Serial Monitor. It looks like the below:
COM6
Send
DIYables Bluetooth - ESP32 BLE Rotator Example Waiting for Bluetooth connection...
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Mobile App

  • Install the DIYables Bluetooth App on your smartphone: Android | iOS
  • If you are using the ESP32 Classic Bluetooth code, you need to pair the ESP32 with your Android phone before opening the app:
    • Go to your phone's Settings > Bluetooth
    • Make sure Bluetooth is turned on
    • Your phone will scan for available devices
    • Find and tap "ESP32_Rotator" in the list of available devices
    • Confirm the pairing request (no PIN required)
    • Wait until it shows "Paired" under the device name
  • If you are using the ESP32 BLE code, no pairing is needed. Just proceed to the next step.
  • Open the DIYables Bluetooth App
  • When opening the app for the first time, it will ask for permissions. Please grant the following:
    • Nearby Devices permission (Android 12+) / Bluetooth permission (iOS) - required to scan and connect to Bluetooth devices
    • Location permission (Android 11 and below only) - required by older Android versions to scan for BLE devices
  • Make sure Bluetooth is turned on on your phone
  • On the home screen, tap the Connect button. The app will scan for both BLE and Classic Bluetooth devices.
DIYables Bluetooth App - Home Screen with Scan Button
  • Find and tap your device in the scan results to connect:
    • For Classic Bluetooth: tap "ESP32_Rotator"
    • For BLE: tap "ESP32BLE_Rotator"
  • Once connected, the app automatically goes back to the home screen. Select the Rotator app from the app menu.
DIYables Bluetooth App - Home Screen with Rotator App

Note: You can tap the settings icon on the home screen to hide/show apps on the home screen. For more details, see the DIYables Bluetooth App User Manual.

  • Drag the rotator knob to change the angle
DIYables Bluetooth App - Rotator Screen

Now look back at the Serial Monitor on Arduino IDE. You will see:

COM6
Send
Bluetooth connected! Rotator angle: 45.0° Rotator angle: 90.0° Rotator angle: 135.0° Rotator angle: 180.0°
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Rotate the knob in the app and watch the real-time angle values in the Serial Monitor

Creative Customization - Adapt the Code to Your Project

Configure Rotator Mode

Set continuous or limited mode:

// Option 1: Continuous mode (0-360°, wraps around) DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_CONTINUOUS); // Option 2: Limited mode (constrained angle range) DIYables_BluetoothRotator bluetoothRotator(ROTATOR_MODE_LIMITED, 0, 180); // Change mode at runtime: bluetoothRotator.setRotatorMode(ROTATOR_MODE_LIMITED, 0, 270); // Read current configuration: int mode = bluetoothRotator.getRotatorMode(); float minAngle = bluetoothRotator.getMinAngle(); float maxAngle = bluetoothRotator.getMaxAngle();

Handle Angle Changes

Use the onRotatorAngle() callback to receive angle values:

bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; Serial.print("Rotator angle: "); Serial.print(angle); Serial.println("°"); // TODO: Add your control logic here });

Handle Configuration Request from App

bluetoothRotator.onGetConfig([]() { // Send current angle to the app bluetoothRotator.send(currentAngle); Serial.println("App requested config - sent current angle"); });

Send Angle to App

You can update the rotator position from ESP32:

// Send angle value to update the app display bluetoothRotator.send(90.0); // Set rotator to 90° // Send text message bluetoothRotator.send("Calibrated");

Handle Connection Events

bluetoothServer.setOnConnected([]() { Serial.println("Bluetooth connected!"); bluetoothRotator.send(currentAngle); // Send current position }); bluetoothServer.setOnDisconnected([]() { Serial.println("Bluetooth disconnected!"); });

How to Use the Rotator

App Interface Controls

The rotator interface in the DIYables Bluetooth App provides:

  • Rotatable Disc: Touch and drag to rotate
  • Angle Display: Shows current angle value
  • Visual Indicator: Marks the current rotation position

Rotator Modes

  • ROTATOR_MODE_CONTINUOUS (0): Full 360° rotation, wraps around
  • ROTATOR_MODE_LIMITED (1): Constrained to min/max angle range

Programming Examples

Servo Control

#include <ESP32Servo.h> Servo myServo; const int SERVO_PIN = 13; void setup() { myServo.attach(SERVO_PIN); myServo.write(0); // Limited mode: 0-180° matches servo range // bluetoothRotator already configured as (ROTATOR_MODE_LIMITED, 0, 180) bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; myServo.write((int)angle); Serial.print("Servo: "); Serial.print((int)angle); Serial.println("°"); }); }

Volume/Brightness Knob

const int PWM_PIN = 16; void setup() { pinMode(PWM_PIN, OUTPUT); // Continuous mode: 0-360° mapped to 0-255 bluetoothRotator.setRotatorMode(ROTATOR_MODE_CONTINUOUS); bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; int pwmValue = map((int)angle, 0, 360, 0, 255); analogWrite(PWM_PIN, pwmValue); int percentage = map((int)angle, 0, 360, 0, 100); Serial.print("Volume: "); Serial.print(percentage); Serial.println("%"); }); }

Compass Display

// Read compass heading from sensor and display on rotator float getCompassHeading() { // TODO: Read from HMC5883L, QMC5883L, or BMM150 // Return heading in degrees 0-360 return 0.0; } void loop() { bluetoothServer.loop(); static unsigned long lastUpdate = 0; if (millis() - lastUpdate >= 500) { lastUpdate = millis(); float heading = getCompassHeading(); bluetoothRotator.send(heading); // Update rotator display } delay(10); }

Stepper Motor Control

#include <AccelStepper.h> AccelStepper stepper(AccelStepper::DRIVER, 16, 17); const int STEPS_PER_REV = 200; void setup() { stepper.setMaxSpeed(1000); stepper.setAcceleration(500); bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; // Convert angle to stepper position long targetSteps = (long)(angle / 360.0 * STEPS_PER_REV); stepper.moveTo(targetSteps); Serial.print("Stepper target: "); Serial.print(targetSteps); Serial.println(" steps"); }); } void loop() { bluetoothServer.loop(); stepper.run(); delay(1); }

Advanced Programming Techniques

Angle Snap to Increments

bluetoothRotator.onRotatorAngle([](float angle) { // Snap to nearest 15° increment float snapped = round(angle / 15.0) * 15.0; currentAngle = snapped; Serial.print("Snapped angle: "); Serial.print(snapped, 0); Serial.println("°"); // Update app to show snapped value bluetoothRotator.send(snapped); });

Zone-Based Control

bluetoothRotator.onRotatorAngle([](float angle) { currentAngle = angle; // Divide 360° into zones if (angle < 90) { Serial.println("Zone: NORTH"); setColor(0, 0, 255); // Blue } else if (angle < 180) { Serial.println("Zone: EAST"); setColor(0, 255, 0); // Green } else if (angle < 270) { Serial.println("Zone: SOUTH"); setColor(255, 0, 0); // Red } else { Serial.println("Zone: WEST"); setColor(255, 255, 0); // Yellow } });

BLE vs Classic Bluetooth - Which to Choose?

FeatureBLE (Esp32BLE_Rotator)Classic Bluetooth (Esp32Bluetooth_Rotator)
iOS Support? Yes? No
Android Support? Yes? Yes
Power ConsumptionLowHigher
Range~30-100m~10-100m
Data RateLowerHigher
Pairing RequiredNo (auto-connect)Yes (manual pairing)
Best ForBattery-powered, cross-platformHigh throughput, Android-only

Troubleshooting

Common Issues

1. Cannot find the device in the app

  • Make sure the ESP32 is powered on and the sketch is uploaded
  • For BLE: Ensure your phone's Bluetooth and Location are enabled
  • For Classic Bluetooth: Pair the device first in phone's Bluetooth settings
  • Check that the correct partition scheme is selected (Huge APP)

2. Rotator not responding

  • Check Bluetooth connection status in the app
  • Verify connection in Serial Monitor
  • Try disconnecting and reconnecting

3. Angle values seem incorrect

  • Check rotator mode configuration (continuous vs limited)
  • Verify min/max angle settings with getMinAngle() and getMaxAngle()
  • Check Serial Monitor for actual angle values received

4. Servo jitters at certain angles

  • Add a small dead zone filter for angle changes
  • Use a separate power supply for the servo
  • Add a capacitor across servo power pins

5. Connection drops frequently

  • Move closer to the ESP32 (reduce distance)
  • For BLE: Check for interference from other BLE devices
  • For Classic Bluetooth: Ensure stable power supply to ESP32

6. Sketch too large / not enough space

  • In Arduino IDE, go to Tools > Partition Scheme and select "Huge APP (3MB No OTA/1MB SPIFFS)" or "No OTA (Large APP)"
  • The default partition scheme only provides ~1.2MB for app code, which is not enough for Bluetooth libraries
  • This setting gives ~3MB by sacrificing the OTA (over-the-air update) partition

Debug Tips

Add comprehensive debugging:

void debugRotatorValue(float angle) { Serial.println("=== Rotator Debug ==="); Serial.println("Angle: " + String(angle, 1) + "°"); Serial.println("Mode: " + String(bluetoothRotator.getRotatorMode() == ROTATOR_MODE_CONTINUOUS ? "Continuous" : "Limited")); Serial.println("Range: " + String(bluetoothRotator.getMinAngle(), 0) + "° - " + String(bluetoothRotator.getMaxAngle(), 0) + "°"); Serial.println("====================="); }

Project Ideas

Motor Control

  • Servo position knob
  • Stepper motor angle selector
  • Motor speed dial
  • Robotic arm joint control

Display Projects

  • Compass heading display
  • Analog clock hands
  • Wind direction indicator
  • Dial gauge simulator

Audio Projects

  • Volume control knob
  • Tone frequency selector
  • Equalizer band control
  • Radio tuner dial

Lighting Projects

  • LED ring position control
  • Color wheel (hue selector)
  • Spotlight direction control
  • Stage lighting angle

Integration with Other Bluetooth Apps

Combine with Bluetooth Slider

Use rotator for angle and slider for speed/intensity:

float speed = 50; bluetoothSlider.onSliderValue([](int slider1, int slider2) { speed = slider1; }); bluetoothRotator.onRotatorAngle([](float angle) { // Combine angle (direction) with speed (intensity) float radians = angle * PI / 180.0; float x = speed * cos(radians); float y = speed * sin(radians); controlMotors(x, y); });

Combine with Bluetooth Table

Display rotator data in a structured table:

bluetoothRotator.onRotatorAngle([](float angle) { bluetoothTable.sendValueUpdate("Angle", String(angle, 1) + "°"); bluetoothTable.sendValueUpdate("Quadrant", String((int)(angle / 90) + 1)); bluetoothTable.sendValueUpdate("Radians", String(angle * PI / 180.0, 3)); });

Next Steps

After mastering the Bluetooth Rotator example, try:

  1. Bluetooth Joystick - For 2D directional control
  2. Bluetooth Slider - For linear value control
  3. Bluetooth Analog Gauge - For gauge-style feedback display
  4. Multiple Bluetooth Apps - Combining rotator with other controls

Support

For additional help:

※ OUR MESSAGES